[
  {
    "path": ".github/workflows/docker-image.yml",
    "content": "name: Docker Image CI\n\non:\n  workflow_dispatch:\n\n\nenv:\n  UPLOAD_IMAGES: true\n  PUSH_IMAGES: true\n  RELEASE_IMAGE_TAG: ellermister/shourturl:latest\n\njobs:\n\n  build:\n\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v3\n      - name: Build the Docker image\n        id: compile\n        run: |\n          docker build . --file Dockerfile --tag ${{ env.RELEASE_IMAGE_TAG }}\n          echo \"status=success\" >> $GITHUB_OUTPUT\n          echo \"FILE_DATE=_$(date +\"%Y%m%d%H%M\")\" >> $GITHUB_ENV\n          docker save ${{ env.RELEASE_IMAGE_TAG }} > docker.tar\n\n      - name: Login to Docker Hub\n        uses: docker/login-action@v3\n        with:\n          username: ${{ secrets.DOCKERHUB_USERNAME }}\n          password: ${{ secrets.DOCKERHUB_TOKEN }}\n\n\n      - name: Push images to regitry\n        if: steps.compile.outputs.status == 'success' && env.PUSH_IMAGES == 'true'\n        run: docker push ${{ env.RELEASE_IMAGE_TAG }}\n\n      - name: Upload images\n        uses: actions/upload-artifact@main\n        if: steps.compile.outputs.status == 'success' && env.UPLOAD_IMAGES == 'true'\n        with:\n          name: ShortURL_Images${{ env.FILE_DATE }}\n          path: docker.tar"
  },
  {
    "path": ".gitignore",
    "content": ".idea\n.project"
  },
  {
    "path": "Dockerfile",
    "content": "FROM kooldev/php:8.2-nginx\n\nWORKDIR /app/public\n\nCOPY . /app/public\n\nRUN wget https://raw.githubusercontent.com/ym/chnroutes2/master/chnroutes.txt -O /app/public/chnroutes.txt \\\n    && chmod -R  775 /app/public && chown -R kool:kool /app/public\n"
  },
  {
    "path": "README.md",
    "content": "# 🔗PHP轻量短链接\n\nPHP轻量短链接是一个简单而强大的工具，用于生成短链接，并提供多种定制化的功能，使链接管理变得更加灵活和便捷。通过使用这个工具，您可以快速生成短链接，支持API方式和在线网页方式生成。该项目提供了丰富的功能，包括密码访问、附加图文信息、仅限特定地区访问等，以满足不同需求场景的链接管理。\n\n\n\n## 体验预览\n\n<https://x007.in/>\n\n[![preview](preview.png)](preview.png)\n\n## 支持功能\n\n- 🌵API快速生成短链接\n- 🌱在线网页生成短链接\n- 🍄支持Redis、File缓存控制\n- 🏄🏼‍♀️ 原始: 直接跳转到目标网站\n- 🐸无Referer: 无 Referer 参数，目标网站无法获取来源站地址\n- 🕷 加密跳转 : 加密跳转参数信息，反大部分爬虫抓取探测\n- 👺 伪装页面 : 使用随机信息、论坛、商品来骗过机器人爬虫\n- 🔥 阅后即焚: 一次性跳转(阅后即焚)\n- 🔑 密码访问: 将为你生成密码，访问时需要密码验证\n- 📝 附加图文: 附加富文本信息，您可以在此留言并分享给您的其他社交媒体用户\n- 💻 仅限PC访问\n- 📱 仅限手机访问\n- 🇨🇳 仅限中国大陆用户访问\n- 🗺️ 仅限非中国大陆用户访问\n\n\n\n## 安装\n\n采用传统 php 项目方式部署安装，以下介绍两种方式进行部署安装，线上推荐使用 Docker。\n\n### Docker 部署\n\n运行命令之后访问 80 端口即可, 容器内部采用 php-fpm 与 nginx 并行提供服务。\n\n```bash\ndocker run -d -p 80:80 ellermister/shourturl:latest\n```\n\n\n\n\n### 手动安装\n\n**下载本程序到网站根目录**\n\n```bash\nphp -S 127.0.0.1:12138\n```\n\n**访问浏览**\n\nhttp://127.0.0.1:12138\n\n**nginx 配置**\n\n```nginx\nlocation / {\n    try_files $uri $uri/ /index.php?$query_string;\n}\n```\n\n**二级目录配置**\n\n比如，`/shorturl/`以 `/` 结尾，实际访问 `http://ip/shorturl/`\n\n```php\ndefine('SUB_PATH', '/shorturl/');\n```\n\n同样，这里 nginx 要做配置\n\n```nginx\n location /shorturl {\n    try_files $uri $uri/ /shorturl/index.php?$query_string;\n }\n```\n\n\n\n### API\n\n**生成短链接**\n\n```bash\ncurl -s http://127.0.0.1:12138/api/link?url=https://map.baidu.com/poi/%E4%B9%9D%E9%BE%99%E5%85%AC%E5%9B%AD/@12713897.395906774,2531599.1717763273,15.45z\n```\n\nResponse\n\n```json\n{\"msg\":\"ok\",\"code\":200,\"data\":\"http://127.0.0.1:12138/s/aFdlm\"}\n```\n"
  },
  {
    "path": "cache/.gitignore",
    "content": "*\n!.gitignore\n"
  },
  {
    "path": "chnroutes.txt",
    "content": "# 14166332 routes were dumped from us-iad01-rs01cn-b at Wed Nov 15 04:00:03 UTC 2023.\n# Found 46493 routes matching, aggregated to 3447.\n1.1.8.0/24\n1.2.4.0/24\n1.8.1.0/24\n1.8.8.0/24\n1.12.0.0/14\n1.18.128.0/24\n1.24.0.0/13\n1.45.0.0/16\n1.48.0.0/14\n1.56.0.0/13\n1.68.0.0/14\n1.80.0.0/13\n1.88.0.0/14\n1.92.0.0/17\n1.92.128.0/19\n1.92.192.0/18\n1.93.0.0/16\n1.94.0.0/17\n1.116.0.0/15\n1.119.0.0/17\n1.119.128.0/18\n1.119.192.0/20\n1.119.208.0/22\n1.180.0.0/14\n1.184.0.0/15\n1.188.0.0/14\n1.192.0.0/13\n1.202.0.0/15\n1.204.0.0/14\n8.129.0.0/16\n8.130.0.0/15\n8.132.0.0/14\n8.136.0.0/13\n8.144.0.0/14\n8.148.0.0/19\n14.16.0.0/12\n14.103.0.0/18\n14.103.64.0/19\n14.103.96.0/20\n14.104.0.0/13\n14.112.0.0/12\n14.134.0.0/15\n14.144.0.0/12\n14.204.0.0/15\n14.208.0.0/12\n27.0.128.0/24\n27.0.130.0/23\n27.0.132.0/22\n27.0.160.0/21\n27.0.204.0/22\n27.0.208.0/21\n27.8.0.0/13\n27.16.0.0/12\n27.36.0.0/14\n27.40.0.0/13\n27.50.128.0/17\n27.54.224.0/19\n27.98.224.0/19\n27.106.128.0/18\n27.106.204.0/22\n27.109.124.0/22\n27.112.0.0/21\n27.112.80.0/23\n27.112.82.0/24\n27.112.84.0/22\n27.115.0.0/17\n27.128.0.0/15\n27.148.0.0/14\n27.152.0.0/13\n27.184.0.0/13\n27.192.0.0/11\n27.224.0.0/14\n36.1.0.0/16\n36.4.0.0/14\n36.16.0.0/12\n36.32.0.0/14\n36.36.0.0/16\n36.40.0.0/13\n36.48.0.0/15\n36.51.253.0/24\n36.56.0.0/13\n36.96.0.0/12\n36.112.0.0/15\n36.114.0.0/16\n36.128.0.0/10\n36.192.0.0/11\n36.248.0.0/14\n36.255.116.0/22\n36.255.128.0/22\n36.255.164.0/24\n39.64.0.0/11\n39.96.0.0/13\n39.104.0.0/14\n39.108.0.0/16\n39.128.0.0/10\n40.0.176.0/20\n40.0.248.0/21\n40.72.0.0/15\n40.125.128.0/17\n40.126.64.0/18\n40.198.10.0/24\n40.198.16.0/21\n40.198.24.0/23\n40.251.225.0/24\n40.251.227.0/24\n42.4.0.0/14\n42.48.0.0/15\n42.51.0.0/16\n42.52.0.0/14\n42.56.0.0/14\n42.62.0.0/17\n42.63.0.0/16\n42.80.0.0/15\n42.83.128.0/23\n42.83.133.0/24\n42.83.134.0/24\n42.83.144.0/22\n42.83.189.0/24\n42.83.190.0/24\n42.83.200.0/23\n42.83.255.0/24\n42.84.0.0/14\n42.88.0.0/13\n42.96.128.0/17\n42.97.0.0/16\n42.99.0.0/18\n42.100.0.0/14\n42.120.0.0/15\n42.122.0.0/16\n42.123.64.0/18\n42.156.128.0/17\n42.157.128.0/21\n42.157.160.0/19\n42.157.192.0/21\n42.158.0.0/15\n42.176.0.0/13\n42.184.0.0/15\n42.186.0.0/16\n42.187.120.0/22\n42.187.128.0/17\n42.192.0.0/15\n42.194.12.0/24\n42.194.128.0/17\n42.201.32.0/19\n42.201.64.0/22\n42.201.68.0/23\n42.201.70.0/24\n42.202.0.0/15\n42.224.0.0/12\n42.240.0.0/21\n42.240.8.0/22\n42.240.12.0/24\n42.240.16.0/24\n42.240.128.0/17\n42.242.0.0/15\n42.244.0.0/14\n42.248.0.0/15\n43.136.0.0/13\n43.144.0.0/15\n43.192.0.0/16\n43.193.0.0/18\n43.196.0.0/16\n43.224.12.0/22\n43.224.24.0/22\n43.224.52.0/23\n43.224.56.0/22\n43.224.80.0/22\n43.224.208.0/22\n43.225.84.0/23\n43.225.180.0/22\n43.225.208.0/22\n43.225.216.0/22\n43.226.32.0/20\n43.226.49.0/24\n43.226.50.0/23\n43.226.53.0/24\n43.226.54.0/24\n43.226.64.0/21\n43.226.72.0/22\n43.226.76.0/23\n43.226.116.0/22\n43.226.120.0/22\n43.226.144.0/20\n43.226.160.0/21\n43.226.236.0/22\n43.227.64.0/22\n43.227.68.0/24\n43.227.104.0/22\n43.227.140.0/22\n43.227.152.0/21\n43.227.160.0/20\n43.227.176.0/21\n43.227.192.0/19\n43.227.252.0/22\n43.228.0.0/19\n43.228.36.0/22\n43.228.40.0/21\n43.228.48.0/20\n43.228.64.0/21\n43.228.76.0/22\n43.228.116.0/22\n43.228.204.0/22\n43.228.240.0/22\n43.229.48.0/23\n43.229.51.0/24\n43.229.185.0/24\n43.229.186.0/23\n43.229.216.0/22\n43.230.220.0/22\n43.230.224.0/23\n43.231.32.0/20\n43.231.80.0/20\n43.231.96.0/20\n43.231.144.0/20\n43.231.160.0/21\n43.231.168.0/22\n43.231.172.0/23\n43.231.174.0/24\n43.239.120.0/22\n43.240.0.0/22\n43.240.56.0/22\n43.240.72.0/22\n43.240.124.0/22\n43.240.128.0/22\n43.240.136.0/22\n43.240.156.0/22\n43.240.192.0/21\n43.240.200.0/23\n43.240.204.0/22\n43.240.220.0/22\n43.241.16.0/22\n43.241.48.0/22\n43.241.76.0/22\n43.241.180.0/22\n43.241.208.0/20\n43.241.224.0/20\n43.242.64.0/22\n43.242.72.0/22\n43.242.84.0/22\n43.242.96.0/22\n43.242.152.0/21\n43.242.164.0/22\n43.242.180.0/22\n43.242.192.0/21\n43.242.204.0/22\n43.242.252.0/22\n43.243.4.0/22\n43.243.12.0/22\n43.243.16.0/22\n43.243.88.0/22\n43.243.128.0/22\n43.243.136.0/22\n43.243.148.0/22\n43.243.156.0/22\n43.243.228.0/22\n43.243.232.0/22\n43.243.244.0/22\n43.246.228.0/23\n43.247.4.0/24\n43.247.68.0/22\n43.247.88.0/22\n43.247.100.0/22\n43.247.176.0/20\n43.247.196.0/22\n43.247.240.0/21\n43.247.248.0/22\n43.248.48.0/22\n43.248.76.0/22\n43.248.96.0/21\n43.248.108.0/22\n43.248.112.0/21\n43.248.128.0/20\n43.248.184.0/21\n43.248.192.0/20\n43.248.244.0/22\n43.249.136.0/22\n43.249.144.0/22\n43.249.192.0/22\n43.249.236.0/22\n43.250.4.0/22\n43.250.32.0/22\n43.250.112.0/22\n43.250.144.0/22\n43.250.168.0/22\n43.250.200.0/22\n43.250.236.0/22\n43.250.244.0/22\n43.251.4.0/22\n43.251.36.0/22\n43.251.244.0/22\n43.252.48.0/24\n43.254.0.0/22\n43.254.8.0/22\n43.254.24.0/22\n43.254.44.0/22\n43.254.52.0/22\n43.254.88.0/22\n43.254.100.0/22\n43.254.104.0/23\n43.254.106.0/24\n43.254.116.0/22\n43.254.128.0/22\n43.254.136.0/22\n43.254.140.0/23\n43.254.144.0/20\n43.254.192.0/22\n43.254.200.0/22\n43.254.220.0/22\n43.254.224.0/22\n43.254.232.0/21\n43.255.4.0/22\n43.255.68.0/22\n43.255.84.0/22\n43.255.96.0/22\n43.255.212.0/22\n43.255.224.0/21\n45.40.192.0/18\n45.65.20.0/22\n45.65.24.0/22\n45.113.20.0/22\n45.113.24.0/22\n45.113.40.0/22\n45.113.200.0/22\n45.113.240.0/23\n45.113.252.0/22\n45.115.44.0/22\n45.115.144.0/22\n45.115.164.0/22\n45.115.200.0/22\n45.116.32.0/22\n45.116.52.0/22\n45.116.100.0/22\n45.116.140.0/22\n45.116.152.0/22\n45.116.208.0/22\n45.117.8.0/22\n45.119.60.0/22\n45.119.64.0/24\n45.119.68.0/22\n45.119.104.0/22\n45.119.116.0/22\n45.120.100.0/22\n45.120.164.0/22\n45.120.243.0/24\n45.121.52.0/24\n45.121.55.0/24\n45.123.128.0/22\n45.123.168.0/21\n45.123.176.0/21\n45.124.20.0/22\n45.124.68.0/22\n45.124.76.0/22\n45.124.80.0/22\n45.124.124.0/22\n45.125.44.0/22\n45.125.56.0/22\n45.126.112.0/22\n45.126.120.0/22\n45.127.128.0/22\n45.127.144.0/21\n45.248.8.0/22\n45.248.108.0/22\n45.249.212.0/22\n45.250.32.0/21\n45.250.40.0/22\n45.250.180.0/23\n45.250.188.0/24\n45.251.20.0/22\n45.251.88.0/21\n45.251.96.0/21\n45.252.0.0/22\n45.252.104.0/22\n45.253.24.0/22\n45.253.32.0/24\n45.253.64.0/22\n45.253.96.0/20\n45.253.112.0/21\n45.253.132.0/22\n45.253.136.0/21\n45.253.144.0/20\n45.253.160.0/19\n45.253.192.0/19\n45.253.224.0/20\n45.253.240.0/22\n45.254.20.0/22\n45.254.48.0/23\n45.254.50.0/24\n45.254.64.0/20\n47.92.0.0/14\n47.96.0.0/12\n47.112.0.0/13\n47.120.0.0/15\n47.122.0.0/17\n47.122.128.0/18\n47.122.192.0/19\n47.123.0.0/16\n49.4.0.0/18\n49.4.64.0/19\n49.4.96.0/21\n49.4.104.0/22\n49.4.108.0/23\n49.4.110.0/24\n49.4.112.0/20\n49.5.0.0/17\n49.7.0.0/16\n49.52.0.0/14\n49.64.0.0/11\n49.112.0.0/13\n49.120.0.0/14\n49.140.0.0/15\n49.208.0.0/15\n49.221.26.0/23\n49.221.64.0/19\n49.221.128.0/19\n49.232.0.0/14\n49.239.192.0/18\n52.80.0.0/15\n52.82.0.0/17\n52.82.128.0/23\n52.82.131.0/24\n52.82.132.0/24\n52.82.134.0/23\n52.82.136.0/24\n52.82.144.0/23\n52.82.148.0/22\n52.82.160.0/21\n52.82.168.0/24\n52.82.170.0/23\n52.82.172.0/22\n52.82.176.0/21\n52.82.187.0/24\n52.82.188.0/23\n52.82.190.0/24\n52.82.192.0/18\n52.83.0.0/16\n52.130.0.0/15\n54.222.0.0/19\n54.222.32.0/21\n54.222.45.0/24\n54.222.48.0/21\n54.222.57.0/24\n54.222.59.0/24\n54.222.60.0/22\n54.222.70.0/23\n54.222.72.0/21\n54.222.80.0/21\n54.222.88.0/22\n54.222.96.0/23\n54.222.112.0/22\n54.222.116.0/23\n54.222.128.0/17\n54.223.0.0/16\n58.16.0.0/13\n58.24.0.0/15\n58.30.0.0/15\n58.32.0.0/11\n58.66.192.0/18\n58.67.128.0/17\n58.68.234.0/24\n58.68.236.0/24\n58.68.247.0/24\n58.82.0.0/17\n58.83.0.0/16\n58.87.64.0/18\n58.99.128.0/17\n58.100.0.0/15\n58.116.0.0/14\n58.128.0.0/13\n58.144.0.0/16\n58.154.0.0/15\n58.192.0.0/11\n58.240.0.0/12\n59.32.0.0/13\n59.40.0.0/15\n59.42.0.0/16\n59.44.0.0/14\n59.48.0.0/12\n59.64.0.0/12\n59.80.0.0/17\n59.81.8.0/23\n59.81.12.0/23\n59.81.20.0/23\n59.81.24.0/23\n59.81.36.0/23\n59.81.40.0/23\n59.81.46.0/24\n59.81.64.0/23\n59.81.68.0/23\n59.81.72.0/23\n59.81.82.0/23\n59.81.86.0/23\n59.81.92.0/22\n59.81.98.0/23\n59.81.102.0/23\n59.81.104.0/22\n59.82.0.0/18\n59.82.64.0/19\n59.82.96.0/22\n59.82.104.0/21\n59.82.112.0/20\n59.82.128.0/21\n59.83.192.0/19\n59.83.224.0/21\n59.83.232.0/22\n59.107.0.0/17\n59.108.0.0/14\n59.151.0.0/17\n59.152.36.0/24\n59.152.38.0/23\n59.153.4.0/22\n59.153.32.0/22\n59.153.92.0/22\n59.153.168.0/23\n59.172.0.0/14\n59.191.0.0/17\n60.0.0.0/11\n60.63.0.0/16\n60.160.0.0/11\n60.194.0.0/15\n60.204.0.0/14\n60.208.0.0/12\n60.232.128.0/17\n60.235.0.0/16\n60.245.128.0/17\n60.247.0.0/16\n60.252.0.0/16\n60.253.128.0/17\n60.255.0.0/16\n61.4.176.0/20\n61.28.20.0/24\n61.28.22.0/24\n61.28.49.0/24\n61.28.108.0/24\n61.28.112.0/20\n61.29.128.0/18\n61.47.128.0/18\n61.48.0.0/13\n61.87.192.0/18\n61.128.0.0/10\n61.232.0.0/14\n61.236.0.0/15\n61.240.0.0/16\n61.241.0.0/17\n61.241.128.0/18\n61.241.192.0/19\n61.242.0.0/15\n62.234.0.0/16\n63.140.0.0/24\n64.188.38.0/23\n64.188.40.0/22\n64.188.44.0/23\n66.102.240.0/21\n66.102.248.0/22\n66.102.255.0/24\n68.79.0.0/18\n69.230.192.0/18\n69.231.128.0/18\n69.234.192.0/18\n69.235.128.0/18\n71.131.192.0/18\n71.132.0.0/18\n71.136.64.0/18\n71.137.0.0/18\n72.163.240.0/23\n72.163.248.0/22\n81.68.0.0/14\n81.173.18.0/23\n81.173.20.0/22\n82.156.0.0/15\n87.254.207.0/24\n93.183.14.0/24\n93.183.18.0/24\n94.191.0.0/17\n98.126.78.0/24\n101.1.0.0/22\n101.2.172.0/22\n101.4.0.0/14\n101.16.0.0/12\n101.33.128.0/17\n101.34.0.0/15\n101.36.0.0/18\n101.36.64.0/20\n101.36.128.0/17\n101.37.0.0/16\n101.38.0.0/15\n101.40.0.0/14\n101.49.206.0/23\n101.50.8.0/21\n101.50.56.0/22\n101.52.4.0/24\n101.52.6.0/24\n101.52.112.0/21\n101.52.124.0/22\n101.52.128.0/20\n101.52.212.0/22\n101.52.216.0/21\n101.52.236.0/22\n101.52.240.0/20\n101.53.100.0/22\n101.64.0.0/13\n101.72.0.0/14\n101.76.0.0/15\n101.78.0.0/22\n101.80.0.0/12\n101.96.10.0/23\n101.96.128.0/19\n101.104.144.0/20\n101.104.160.0/20\n101.106.0.0/19\n101.124.0.0/16\n101.125.0.0/22\n101.125.4.0/23\n101.125.6.0/24\n101.125.130.0/24\n101.125.250.0/23\n101.125.252.0/22\n101.126.0.0/18\n101.126.64.0/19\n101.126.96.0/20\n101.126.172.0/22\n101.126.176.0/20\n101.126.192.0/19\n101.126.228.0/22\n101.126.232.0/21\n101.126.240.0/20\n101.128.0.0/22\n101.129.0.0/16\n101.132.0.0/15\n101.144.0.0/12\n101.198.0.0/22\n101.198.196.0/22\n101.199.48.0/20\n101.199.97.0/24\n101.199.112.0/23\n101.199.114.0/24\n101.199.125.0/24\n101.199.128.0/23\n101.199.196.0/22\n101.199.252.0/22\n101.200.0.0/15\n101.203.172.0/22\n101.204.0.0/14\n101.224.0.0/13\n101.234.76.0/22\n101.236.0.0/16\n101.237.0.0/19\n101.237.33.0/24\n101.237.34.0/23\n101.237.36.0/22\n101.237.40.0/24\n101.240.0.0/14\n101.246.172.0/22\n101.246.176.0/20\n101.248.0.0/15\n101.251.0.0/22\n101.251.80.0/20\n101.251.128.0/19\n101.251.160.0/21\n101.251.192.0/18\n101.252.0.0/15\n101.254.0.0/20\n101.254.32.0/19\n101.254.64.0/18\n101.254.128.0/17\n103.1.10.0/23\n103.1.168.0/22\n103.2.108.0/22\n103.2.208.0/22\n103.3.96.0/22\n103.3.112.0/20\n103.3.128.0/22\n103.3.136.0/21\n103.3.152.0/21\n103.4.56.0/22\n103.5.168.0/22\n103.5.192.0/22\n103.6.220.0/22\n103.7.140.0/22\n103.7.212.0/22\n103.8.33.0/24\n103.8.34.0/23\n103.8.52.0/22\n103.8.68.0/22\n103.8.204.0/22\n103.8.220.0/22\n103.9.8.0/22\n103.9.248.0/21\n103.10.2.0/23\n103.10.84.0/22\n103.12.184.0/22\n103.12.232.0/22\n103.13.12.0/23\n103.13.244.0/22\n103.14.132.0/23\n103.14.136.0/22\n103.15.4.0/22\n103.15.96.0/22\n103.16.124.0/22\n103.17.40.0/22\n103.18.186.0/23\n103.18.224.0/22\n103.19.46.0/23\n103.19.64.0/22\n103.19.232.0/22\n103.20.32.0/24\n103.20.34.0/23\n103.20.112.0/22\n103.20.128.0/22\n103.20.248.0/22\n103.21.116.0/22\n103.21.140.0/22\n103.21.176.0/22\n103.22.188.0/22\n103.22.252.0/22\n103.23.8.0/22\n103.23.160.0/22\n103.24.116.0/22\n103.24.176.0/22\n103.24.228.0/22\n103.25.20.0/22\n103.25.24.0/22\n103.25.36.0/22\n103.25.64.0/23\n103.25.148.0/23\n103.25.156.0/24\n103.26.0.0/22\n103.26.64.0/22\n103.26.76.0/22\n103.27.4.0/22\n103.27.24.0/22\n103.27.240.0/22\n103.28.8.0/24\n103.28.204.0/22\n103.28.212.0/22\n103.29.16.0/22\n103.29.29.0/24\n103.29.136.0/22\n103.30.106.0/23\n103.30.148.0/24\n103.30.151.0/24\n103.31.48.0/22\n103.31.72.0/24\n103.31.200.0/22\n103.35.104.0/22\n103.35.220.0/23\n103.35.254.0/24\n103.36.28.0/22\n103.36.36.0/22\n103.36.60.0/22\n103.36.96.0/22\n103.36.132.0/22\n103.36.136.0/22\n103.36.164.0/22\n103.36.168.0/23\n103.36.172.0/22\n103.36.192.0/20\n103.36.208.0/22\n103.36.220.0/22\n103.37.12.0/22\n103.37.16.0/22\n103.37.44.0/22\n103.37.72.0/22\n103.37.136.0/21\n103.37.144.0/20\n103.37.160.0/21\n103.38.40.0/22\n103.38.76.0/22\n103.38.84.0/22\n103.38.92.0/23\n103.38.116.0/22\n103.38.224.0/22\n103.38.232.0/22\n103.38.252.0/23\n103.39.204.0/22\n103.39.208.0/20\n103.39.224.0/21\n103.39.232.0/22\n103.40.12.0/22\n103.40.192.0/22\n103.40.232.0/22\n103.40.240.0/20\n103.41.0.0/23\n103.41.3.0/24\n103.41.116.0/22\n103.41.164.0/22\n103.41.232.0/23\n103.42.76.0/22\n103.43.133.0/24\n103.43.184.0/22\n103.44.58.0/23\n103.44.80.0/22\n103.44.144.0/22\n103.44.168.0/22\n103.44.176.0/22\n103.44.236.0/22\n103.44.240.0/20\n103.45.72.0/21\n103.45.97.0/24\n103.45.98.0/23\n103.45.100.0/22\n103.45.104.0/21\n103.45.112.0/20\n103.45.128.0/19\n103.45.160.0/22\n103.45.172.0/22\n103.45.176.0/20\n103.45.248.0/22\n103.46.12.0/22\n103.46.16.0/20\n103.46.32.0/19\n103.46.64.0/18\n103.46.128.0/21\n103.46.136.0/22\n103.46.168.0/22\n103.47.48.0/22\n103.47.80.0/22\n103.48.232.0/23\n103.49.12.0/22\n103.49.180.0/22\n103.50.36.0/22\n103.52.104.0/23\n103.52.172.0/22\n103.52.176.0/22\n103.52.196.0/22\n103.53.124.0/22\n103.53.204.0/22\n103.53.208.0/22\n103.55.172.0/22\n103.55.228.0/22\n103.56.32.0/22\n103.56.60.0/22\n103.56.76.0/22\n103.56.100.0/22\n103.56.104.0/22\n103.56.152.0/22\n103.56.184.0/22\n103.57.12.0/22\n103.57.139.0/24\n103.59.112.0/22\n103.59.118.0/23\n103.59.124.0/22\n103.59.148.0/22\n103.59.164.0/22\n103.60.32.0/22\n103.60.164.0/22\n103.60.228.0/23\n103.61.60.0/22\n103.61.104.0/23\n103.61.143.0/24\n103.61.153.0/24\n103.61.154.0/23\n103.61.188.0/23\n103.61.190.0/24\n103.63.160.0/20\n103.63.176.0/21\n103.63.244.0/22\n103.64.156.0/22\n103.64.212.0/22\n103.65.8.0/22\n103.66.32.0/22\n103.68.128.0/22\n103.69.16.0/22\n103.71.68.0/22\n103.71.120.0/21\n103.71.128.0/22\n103.71.196.0/22\n103.71.200.0/22\n103.71.232.0/22\n103.72.12.0/22\n103.72.16.0/20\n103.72.32.0/20\n103.72.48.0/21\n103.72.112.0/23\n103.72.128.0/21\n103.72.172.0/24\n103.73.48.0/24\n103.73.116.0/22\n103.73.136.0/21\n103.73.204.0/22\n103.74.24.0/21\n103.74.32.0/20\n103.74.48.0/22\n103.74.125.0/24\n103.75.104.0/22\n103.75.152.0/22\n103.76.60.0/22\n103.76.220.0/22\n103.76.224.0/22\n103.77.28.0/22\n103.77.132.0/22\n103.78.64.0/22\n103.78.126.0/23\n103.78.228.0/22\n103.79.24.0/22\n103.79.200.0/22\n103.81.4.0/22\n103.81.48.0/22\n103.81.123.0/24\n103.81.200.0/22\n103.82.224.0/22\n103.83.44.0/22\n103.83.72.0/22\n103.84.170.0/23\n103.85.84.0/22\n103.85.164.0/22\n103.85.168.0/21\n103.85.176.0/22\n103.87.132.0/22\n103.87.180.0/22\n103.88.32.0/21\n103.88.64.0/22\n103.89.184.0/21\n103.89.192.0/19\n103.89.224.0/21\n103.90.92.0/22\n103.90.152.0/22\n103.90.173.0/24\n103.90.176.0/22\n103.90.188.0/22\n103.91.176.0/22\n103.91.208.0/22\n103.93.180.0/22\n103.94.12.0/22\n103.94.20.0/23\n103.95.68.0/22\n103.95.220.0/23\n103.95.222.0/24\n103.95.252.0/22\n103.96.8.0/22\n103.96.214.0/23\n103.96.224.0/23\n103.97.60.0/24\n103.97.112.0/24\n103.98.0.0/24\n103.98.44.0/22\n103.98.125.0/24\n103.98.127.0/24\n103.98.168.0/22\n103.98.220.0/22\n103.98.248.0/23\n103.98.252.0/22\n103.99.152.0/22\n103.100.64.0/22\n103.101.124.0/23\n103.101.180.0/22\n103.102.192.0/22\n103.102.196.0/24\n103.102.200.0/22\n103.103.12.0/24\n103.103.36.0/24\n103.103.200.0/22\n103.105.12.0/22\n103.107.188.0/22\n103.107.216.0/22\n103.108.244.0/24\n103.108.247.0/24\n103.110.92.0/22\n103.110.132.0/22\n103.110.156.0/22\n103.111.64.0/24\n103.113.4.0/22\n103.114.100.0/22\n103.114.156.0/23\n103.114.159.0/24\n103.114.212.0/23\n103.114.236.0/22\n103.115.120.0/24\n103.115.248.0/22\n103.116.76.0/22\n103.116.92.0/22\n103.116.120.0/23\n103.116.123.0/24\n103.117.16.0/22\n103.118.52.0/22\n103.118.60.0/22\n103.118.173.0/24\n103.120.72.0/22\n103.120.224.0/22\n103.121.52.0/22\n103.121.164.0/23\n103.121.166.0/24\n103.121.252.0/22\n103.123.4.0/23\n103.126.1.0/24\n103.126.124.0/22\n103.131.152.0/22\n103.131.168.0/22\n103.132.212.0/23\n103.135.160.0/22\n103.135.192.0/23\n103.135.194.0/24\n103.135.196.0/22\n103.137.60.0/24\n103.139.92.0/23\n103.139.212.0/23\n103.140.14.0/23\n103.141.10.0/23\n103.142.96.0/23\n103.142.154.0/23\n103.142.234.0/23\n103.143.16.0/22\n103.144.66.0/23\n103.144.70.0/24\n103.144.158.0/23\n103.145.42.0/23\n103.146.8.0/23\n103.147.124.0/24\n103.149.242.0/24\n103.149.244.0/22\n103.150.10.0/23\n103.150.24.0/23\n103.150.164.0/23\n103.151.142.0/23\n103.151.148.0/23\n103.152.28.0/23\n103.152.56.0/23\n103.152.76.0/23\n103.152.186.0/23\n103.154.30.0/23\n103.154.41.0/24\n103.154.162.0/23\n103.155.76.0/23\n103.156.68.0/23\n103.156.174.0/23\n103.156.186.0/23\n103.158.0.0/23\n103.159.122.0/23\n103.159.124.0/23\n103.161.220.0/23\n103.161.254.0/23\n103.162.10.0/23\n103.163.46.0/23\n103.163.180.0/24\n103.164.32.0/23\n103.165.110.0/23\n103.169.62.0/23\n103.170.4.0/23\n103.170.212.0/23\n103.174.94.0/23\n103.179.78.0/23\n103.181.234.0/24\n103.183.66.0/23\n103.184.46.0/23\n103.186.4.0/23\n103.186.108.0/23\n103.189.92.0/23\n103.189.154.0/23\n103.190.122.0/23\n103.191.102.0/24\n103.191.242.0/23\n103.192.0.0/23\n103.192.4.0/23\n103.192.8.0/21\n103.192.16.0/20\n103.192.132.0/22\n103.192.188.0/22\n103.192.208.0/21\n103.192.252.0/22\n103.193.188.0/22\n103.193.192.0/22\n103.196.64.0/22\n103.196.88.0/21\n103.197.0.0/22\n103.197.228.0/22\n103.198.64.0/22\n103.198.124.0/22\n103.200.136.0/21\n103.200.144.0/21\n103.202.0.0/19\n103.202.32.0/20\n103.202.92.0/22\n103.202.96.0/20\n103.202.112.0/22\n103.202.120.0/21\n103.202.128.0/20\n103.202.144.0/22\n103.203.140.0/23\n103.203.216.0/22\n103.204.72.0/22\n103.205.4.0/22\n103.205.40.0/23\n103.205.136.0/24\n103.205.139.0/24\n103.205.188.0/22\n103.205.192.0/22\n103.205.252.0/22\n103.207.228.0/22\n103.208.12.0/22\n103.208.48.0/22\n103.209.112.0/22\n103.209.136.0/22\n103.210.160.0/22\n103.210.169.0/24\n103.210.170.0/23\n103.211.44.0/22\n103.211.220.0/22\n103.212.0.0/21\n103.212.12.0/22\n103.212.48.0/23\n103.213.96.0/22\n103.213.132.0/22\n103.214.48.0/22\n103.215.36.0/22\n103.215.44.0/23\n103.215.140.0/22\n103.216.4.0/22\n103.216.152.0/22\n103.216.252.0/22\n103.218.216.0/22\n103.219.28.0/22\n103.219.32.0/21\n103.219.64.0/23\n103.219.84.0/22\n103.219.184.0/22\n103.220.52.0/22\n103.220.56.0/21\n103.220.64.0/22\n103.220.124.0/22\n103.220.128.0/19\n103.220.160.0/21\n103.220.240.0/22\n103.221.140.0/22\n103.222.33.0/24\n103.222.40.0/22\n103.222.176.0/21\n103.223.132.0/22\n103.224.220.0/22\n103.224.228.0/23\n103.224.232.0/22\n103.227.76.0/22\n103.227.80.0/22\n103.227.120.0/22\n103.227.136.0/22\n103.227.228.0/22\n103.228.136.0/22\n103.228.160.0/22\n103.228.204.0/23\n103.228.208.0/22\n103.228.228.0/22\n103.229.148.0/22\n103.229.212.0/22\n103.230.110.0/23\n103.230.212.0/22\n103.230.236.0/22\n103.231.16.0/24\n103.231.64.0/21\n103.231.144.0/23\n103.231.146.0/24\n103.232.144.0/22\n103.232.166.0/23\n103.233.4.0/22\n103.233.52.0/22\n103.233.128.0/22\n103.233.136.0/23\n103.233.138.0/24\n103.234.20.0/22\n103.234.56.0/22\n103.234.128.0/23\n103.235.85.0/24\n103.235.136.0/22\n103.235.144.0/24\n103.235.200.0/22\n103.235.220.0/22\n103.235.224.0/20\n103.235.244.0/22\n103.235.248.0/21\n103.236.120.0/22\n103.236.240.0/21\n103.236.252.0/22\n103.237.8.0/22\n103.237.28.0/23\n103.237.248.0/21\n103.238.0.0/21\n103.238.16.0/22\n103.238.52.0/22\n103.238.96.0/23\n103.238.98.0/24\n103.238.132.0/22\n103.238.144.0/22\n103.238.160.0/22\n103.238.184.0/23\n103.238.188.0/22\n103.238.204.0/22\n103.238.252.0/22\n103.239.68.0/22\n103.239.152.0/22\n103.239.204.0/22\n103.239.244.0/22\n103.240.16.0/22\n103.240.36.0/22\n103.240.84.0/22\n103.240.124.0/22\n103.240.244.0/22\n103.241.95.0/24\n103.242.168.0/23\n103.242.170.0/24\n103.242.172.0/22\n103.242.200.0/24\n103.242.202.0/24\n103.242.212.0/22\n103.243.136.0/22\n103.243.252.0/22\n103.244.26.0/23\n103.244.59.0/24\n103.244.64.0/22\n103.244.80.0/22\n103.244.164.0/22\n103.244.232.0/22\n103.245.128.0/22\n103.246.8.0/22\n103.246.152.0/22\n103.247.168.0/22\n103.247.176.0/22\n103.247.212.0/23\n103.248.102.0/23\n103.248.152.0/22\n103.249.12.0/22\n103.249.52.0/22\n103.249.136.0/24\n103.249.192.0/22\n103.249.244.0/22\n103.249.252.0/22\n103.250.32.0/22\n103.250.192.0/22\n103.250.216.0/22\n103.250.248.0/22\n103.251.32.0/22\n103.251.84.0/22\n103.251.96.0/22\n103.251.124.0/22\n103.251.160.0/22\n103.251.204.0/22\n103.251.240.0/22\n103.252.36.0/22\n103.252.172.0/22\n103.252.248.0/22\n103.253.60.0/22\n103.253.204.0/22\n103.253.224.0/22\n103.253.232.0/22\n103.254.68.0/22\n103.254.76.0/22\n103.254.112.0/22\n103.254.188.0/22\n103.255.68.0/22\n103.255.88.0/21\n103.255.140.0/22\n103.255.200.0/22\n106.0.4.0/22\n106.2.16.0/20\n106.2.32.0/19\n106.2.64.0/18\n106.2.128.0/19\n106.2.224.0/24\n106.2.232.0/21\n106.3.16.0/20\n106.3.32.0/20\n106.3.96.0/22\n106.3.128.0/19\n106.3.192.0/20\n106.3.208.0/21\n106.3.224.0/21\n106.4.0.0/14\n106.8.0.0/15\n106.11.0.0/16\n106.12.0.0/17\n106.12.128.0/18\n106.12.192.0/19\n106.12.224.0/20\n106.12.240.0/21\n106.12.250.0/23\n106.12.252.0/23\n106.12.254.0/24\n106.13.0.0/16\n106.14.0.0/15\n106.16.0.0/14\n106.32.0.0/12\n106.48.0.0/21\n106.48.16.0/21\n106.52.0.0/14\n106.56.0.0/14\n106.60.0.0/15\n106.62.0.0/16\n106.63.0.0/17\n106.74.0.0/16\n106.75.0.0/17\n106.75.128.0/18\n106.75.208.0/20\n106.75.224.0/19\n106.80.0.0/13\n106.88.0.0/14\n106.92.0.0/16\n106.108.0.0/14\n106.112.0.0/13\n106.120.0.0/18\n106.120.96.0/19\n106.120.128.0/17\n106.121.0.0/16\n106.122.0.0/15\n106.124.0.0/14\n106.224.0.0/14\n106.228.0.0/15\n106.230.0.0/16\n109.244.0.0/16\n110.6.0.0/15\n110.16.0.0/14\n110.40.0.0/24\n110.40.2.0/24\n110.40.9.0/24\n110.40.10.0/23\n110.40.12.0/22\n110.40.16.0/24\n110.40.128.0/17\n110.41.0.0/16\n110.42.0.0/18\n110.42.64.0/19\n110.42.96.0/20\n110.42.128.0/17\n110.43.0.0/16\n110.44.12.0/22\n110.51.0.0/16\n110.52.0.0/15\n110.56.0.0/13\n110.64.0.0/15\n110.72.0.0/15\n110.75.0.0/16\n110.76.0.0/18\n110.76.156.0/22\n110.76.184.0/22\n110.80.0.0/13\n110.88.0.0/14\n110.96.0.0/14\n110.100.0.0/15\n110.105.0.0/16\n110.106.0.0/15\n110.115.128.0/17\n110.116.0.0/16\n110.118.0.0/16\n110.120.0.0/14\n110.124.0.0/15\n110.126.0.0/16\n110.152.0.0/14\n110.156.0.0/15\n110.166.0.0/15\n110.172.211.0/24\n110.172.213.0/24\n110.172.217.0/24\n110.172.221.0/24\n110.173.32.0/20\n110.173.192.0/19\n110.176.0.0/12\n110.192.0.0/11\n110.228.0.0/14\n110.232.32.0/19\n110.236.0.0/15\n110.240.0.0/12\n111.0.0.0/10\n111.67.192.0/20\n111.72.0.0/13\n111.85.0.0/16\n111.112.0.0/14\n111.116.0.0/15\n111.118.200.0/21\n111.120.0.0/14\n111.124.0.0/16\n111.126.0.0/15\n111.128.0.0/16\n111.132.0.0/16\n111.142.0.0/15\n111.144.0.0/14\n111.148.0.0/16\n111.152.0.0/13\n111.160.0.0/13\n111.170.0.0/16\n111.172.0.0/14\n111.176.0.0/13\n111.186.0.0/15\n111.192.0.0/12\n111.208.121.0/24\n111.212.0.0/14\n111.221.28.0/24\n111.221.128.0/17\n111.222.0.0/16\n111.223.8.0/21\n111.224.0.0/14\n111.229.0.0/16\n111.230.0.0/15\n111.235.156.0/22\n111.235.160.0/22\n111.235.164.0/23\n111.235.170.0/23\n111.235.172.0/23\n111.235.174.0/24\n111.235.178.0/24\n111.235.180.0/23\n111.235.182.0/24\n112.0.0.0/10\n112.64.0.0/14\n112.73.64.0/18\n112.74.0.0/16\n112.80.0.0/12\n112.96.0.0/13\n112.109.128.0/17\n112.111.0.0/16\n112.112.0.0/14\n112.116.0.0/15\n112.122.0.0/15\n112.124.0.0/14\n112.132.0.0/16\n112.192.0.0/14\n112.224.0.0/11\n113.0.0.0/13\n113.8.0.0/15\n113.12.0.0/14\n113.16.0.0/15\n113.18.0.0/16\n113.21.232.0/23\n113.21.234.0/24\n113.21.236.0/22\n113.24.0.0/14\n113.31.29.0/24\n113.31.31.0/24\n113.31.88.0/23\n113.31.96.0/19\n113.31.144.0/20\n113.31.160.0/19\n113.48.48.0/20\n113.50.0.0/20\n113.50.32.0/24\n113.50.48.0/20\n113.50.64.0/20\n113.54.0.0/15\n113.56.0.0/15\n113.58.0.0/16\n113.59.0.0/17\n113.59.224.0/22\n113.62.0.0/15\n113.64.0.0/10\n113.128.0.0/15\n113.130.96.0/20\n113.130.112.0/21\n113.132.0.0/14\n113.136.0.0/13\n113.194.0.0/15\n113.197.104.0/23\n113.200.0.0/15\n113.204.0.0/14\n113.208.112.0/21\n113.209.0.0/16\n113.213.0.0/18\n113.213.64.0/19\n113.213.96.0/20\n113.214.0.0/15\n113.218.0.0/15\n113.220.0.0/14\n113.224.0.0/12\n113.240.0.0/13\n113.248.0.0/14\n114.28.68.0/22\n114.28.72.0/21\n114.28.128.0/18\n114.28.248.0/21\n114.55.0.0/16\n114.60.0.0/14\n114.64.0.0/16\n114.66.0.0/18\n114.66.64.0/23\n114.66.80.0/23\n114.66.236.0/22\n114.66.240.0/20\n114.67.16.0/21\n114.67.48.0/24\n114.67.57.0/24\n114.67.58.0/24\n114.67.60.0/23\n114.67.62.0/24\n114.67.64.0/18\n114.67.128.0/17\n114.80.0.0/13\n114.88.0.0/14\n114.92.0.0/15\n114.95.0.0/16\n114.96.0.0/13\n114.104.0.0/14\n114.110.96.0/22\n114.111.0.0/23\n114.111.16.0/20\n114.112.32.0/19\n114.112.64.0/19\n114.112.96.0/21\n114.112.104.0/22\n114.112.124.0/23\n114.112.136.0/21\n114.112.144.0/20\n114.112.160.0/20\n114.112.200.0/21\n114.112.208.0/20\n114.113.16.0/20\n114.113.32.0/19\n114.113.64.0/18\n114.113.144.0/20\n114.113.196.0/22\n114.113.200.0/22\n114.113.221.0/24\n114.113.223.0/24\n114.113.224.0/20\n114.114.112.0/21\n114.115.0.0/16\n114.116.0.0/15\n114.118.0.0/17\n114.119.41.0/24\n114.119.116.0/23\n114.119.119.0/24\n114.132.0.0/16\n114.135.0.0/16\n114.138.0.0/15\n114.141.128.0/18\n114.196.0.0/15\n114.212.0.0/14\n114.216.0.0/13\n114.224.0.0/11\n115.24.0.0/14\n115.28.0.0/15\n115.31.64.0/22\n115.44.0.0/14\n115.48.0.0/12\n115.84.0.0/18\n115.85.192.0/18\n115.124.16.0/20\n115.148.0.0/14\n115.152.0.0/13\n115.168.0.0/14\n115.173.0.0/19\n115.174.64.0/19\n115.182.0.0/15\n115.192.0.0/11\n115.224.0.0/12\n116.1.0.0/16\n116.2.0.0/15\n116.4.0.0/14\n116.8.0.0/14\n116.13.0.0/16\n116.16.0.0/12\n116.52.0.0/14\n116.56.0.0/15\n116.62.0.0/15\n116.66.36.0/24\n116.66.48.0/21\n116.66.98.0/24\n116.68.136.0/21\n116.68.176.0/21\n116.70.64.0/18\n116.76.0.0/15\n116.78.0.0/16\n116.85.0.0/20\n116.85.17.0/24\n116.85.18.0/23\n116.85.20.0/22\n116.85.24.0/21\n116.85.32.0/19\n116.85.64.0/20\n116.85.240.0/20\n116.90.80.0/20\n116.95.0.0/16\n116.112.0.0/14\n116.116.0.0/15\n116.128.0.0/17\n116.128.128.0/18\n116.128.200.0/21\n116.128.208.0/20\n116.128.224.0/19\n116.129.0.0/16\n116.130.0.0/15\n116.132.0.0/15\n116.135.0.0/16\n116.136.0.0/13\n116.147.0.0/16\n116.148.0.0/15\n116.153.0.0/16\n116.154.0.0/15\n116.162.0.0/16\n116.163.0.0/18\n116.167.0.0/16\n116.168.0.0/15\n116.171.0.0/16\n116.172.64.0/18\n116.172.128.0/17\n116.174.0.0/15\n116.176.0.0/14\n116.181.0.0/16\n116.182.0.0/16\n116.193.16.0/23\n116.193.18.0/24\n116.196.64.0/18\n116.196.144.0/24\n116.196.148.0/24\n116.196.192.0/21\n116.196.218.0/23\n116.196.220.0/22\n116.197.160.0/21\n116.198.0.0/18\n116.198.64.0/21\n116.198.72.0/22\n116.198.144.0/20\n116.198.160.0/20\n116.198.176.0/21\n116.198.192.0/18\n116.199.0.0/17\n116.204.0.0/17\n116.205.0.0/18\n116.205.128.0/17\n116.207.0.0/16\n116.208.0.0/14\n116.213.64.0/18\n116.213.128.0/17\n116.214.32.0/19\n116.214.128.0/22\n116.214.132.0/23\n116.214.134.0/24\n116.224.0.0/12\n116.242.0.0/16\n116.246.0.0/15\n116.248.0.0/15\n116.252.0.0/15\n116.254.104.0/21\n116.255.128.0/17\n117.8.0.0/13\n117.21.0.0/16\n117.22.0.0/15\n117.24.0.0/13\n117.32.0.0/13\n117.40.0.0/14\n117.44.0.0/15\n117.48.0.0/18\n117.48.64.0/19\n117.48.96.0/23\n117.48.100.0/22\n117.48.104.0/21\n117.48.112.0/20\n117.48.128.0/19\n117.48.160.0/20\n117.48.192.0/20\n117.48.216.0/21\n117.48.224.0/20\n117.50.0.0/16\n117.51.128.0/19\n117.51.160.0/23\n117.51.168.0/22\n117.57.0.0/16\n117.59.0.0/19\n117.59.32.0/22\n117.59.36.0/23\n117.59.38.0/24\n117.59.40.0/21\n117.59.48.0/20\n117.59.64.0/18\n117.59.128.0/17\n117.60.0.0/14\n117.64.0.0/13\n117.72.0.0/23\n117.72.8.0/21\n117.72.16.0/23\n117.72.32.0/20\n117.72.248.0/22\n117.72.255.0/24\n117.73.0.0/20\n117.73.16.0/21\n117.73.252.0/22\n117.74.64.0/20\n117.74.128.0/21\n117.74.136.0/22\n117.78.0.0/18\n117.79.80.0/20\n117.79.128.0/21\n117.79.144.0/20\n117.79.224.0/20\n117.79.241.0/24\n117.79.242.0/24\n117.80.0.0/12\n117.100.128.0/17\n117.106.0.0/15\n117.112.0.0/13\n117.121.0.0/17\n117.121.128.0/18\n117.122.128.0/17\n117.124.0.0/14\n117.128.0.0/10\n118.24.0.0/15\n118.26.64.0/21\n118.26.72.0/22\n118.26.96.0/21\n118.26.116.0/22\n118.26.128.0/22\n118.26.136.0/22\n118.26.160.0/20\n118.26.192.0/24\n118.26.194.0/23\n118.26.197.0/24\n118.26.198.0/23\n118.26.200.0/21\n118.26.208.0/20\n118.26.224.0/19\n118.30.0.0/15\n118.64.0.0/22\n118.64.252.0/22\n118.72.0.0/13\n118.80.0.0/15\n118.84.0.0/15\n118.88.32.0/19\n118.88.64.0/18\n118.88.128.0/17\n118.89.0.0/16\n118.102.16.0/20\n118.103.164.0/22\n118.112.0.0/13\n118.120.0.0/14\n118.124.0.0/15\n118.126.1.0/24\n118.126.2.0/23\n118.126.4.0/23\n118.126.8.0/23\n118.126.10.0/24\n118.126.12.0/22\n118.126.16.0/23\n118.126.18.0/24\n118.126.32.0/19\n118.126.64.0/18\n118.126.128.0/17\n118.132.0.0/14\n118.144.0.0/16\n118.145.0.0/19\n118.145.32.0/20\n118.145.128.0/19\n118.145.160.0/21\n118.178.0.0/16\n118.180.0.0/14\n118.184.128.0/17\n118.186.0.0/19\n118.186.32.0/24\n118.186.34.0/23\n118.186.36.0/22\n118.186.56.0/21\n118.186.64.0/21\n118.186.80.0/20\n118.186.96.0/20\n118.186.112.0/21\n118.186.160.0/19\n118.186.208.0/21\n118.186.240.0/21\n118.187.0.0/16\n118.188.18.0/23\n118.188.20.0/22\n118.188.24.0/23\n118.190.0.0/16\n118.191.0.0/21\n118.191.8.0/22\n118.191.12.0/24\n118.191.192.0/23\n118.191.248.0/21\n118.192.0.0/17\n118.193.96.0/19\n118.194.32.0/19\n118.194.128.0/21\n118.194.240.0/21\n118.195.0.0/16\n118.199.0.0/16\n118.202.0.0/15\n118.212.0.0/15\n118.215.192.0/19\n118.228.0.0/15\n118.230.0.0/16\n118.239.0.0/16\n118.242.0.0/22\n118.242.16.0/22\n118.242.24.0/22\n118.242.32.0/22\n118.242.40.0/24\n118.242.236.0/22\n118.244.0.0/21\n118.244.128.0/17\n118.247.0.0/16\n118.248.0.0/13\n119.0.0.0/15\n119.2.128.0/24\n119.3.0.0/16\n119.4.0.0/14\n119.10.112.0/21\n119.15.136.0/23\n119.15.140.0/23\n119.18.192.0/20\n119.18.208.0/21\n119.23.0.0/16\n119.27.64.0/18\n119.27.160.0/19\n119.28.28.0/24\n119.29.0.0/16\n119.32.0.0/15\n119.34.0.0/16\n119.36.0.0/16\n119.37.0.0/23\n119.37.2.0/24\n119.37.12.0/24\n119.37.192.0/21\n119.38.0.0/21\n119.38.128.0/18\n119.38.192.0/19\n119.39.0.0/16\n119.40.0.0/19\n119.40.32.0/21\n119.40.128.0/17\n119.41.0.0/16\n119.42.0.0/19\n119.42.136.0/21\n119.42.224.0/19\n119.44.0.0/22\n119.44.4.0/23\n119.44.7.0/24\n119.44.9.0/24\n119.44.10.0/23\n119.44.12.0/24\n119.44.16.0/22\n119.44.20.0/23\n119.44.23.0/24\n119.44.24.0/23\n119.44.45.0/24\n119.44.46.0/24\n119.44.56.0/21\n119.44.192.0/24\n119.44.200.0/24\n119.44.205.0/24\n119.44.217.0/24\n119.44.218.0/24\n119.44.220.0/22\n119.44.224.0/24\n119.44.254.0/23\n119.45.0.0/16\n119.48.0.0/13\n119.57.0.0/16\n119.59.128.0/18\n119.60.0.0/15\n119.62.0.0/16\n119.75.208.0/20\n119.78.0.0/15\n119.80.0.0/21\n119.80.32.0/20\n119.80.48.0/21\n119.80.160.0/19\n119.80.192.0/21\n119.80.200.0/23\n119.80.202.0/24\n119.80.240.0/22\n119.80.248.0/21\n119.84.0.0/14\n119.88.128.0/17\n119.90.32.0/19\n119.91.0.0/16\n119.96.0.0/13\n119.108.0.0/15\n119.112.0.0/12\n119.128.0.0/12\n119.144.0.0/14\n119.148.160.0/20\n119.161.120.0/22\n119.161.168.0/22\n119.161.180.0/23\n119.161.182.0/24\n119.162.0.0/15\n119.164.0.0/14\n119.176.0.0/12\n119.233.128.0/17\n119.235.128.0/24\n119.235.130.0/24\n119.235.136.0/24\n119.235.138.0/24\n119.235.143.0/24\n119.235.144.0/24\n119.235.146.0/24\n119.235.151.0/24\n119.235.160.0/23\n119.235.162.0/24\n119.235.164.0/24\n119.235.167.0/24\n119.235.184.0/22\n119.248.0.0/14\n119.253.0.0/20\n119.253.32.0/19\n119.253.64.0/19\n119.253.128.0/17\n119.254.0.0/16\n119.255.0.0/18\n119.255.128.0/17\n120.0.0.0/12\n120.24.0.0/14\n120.31.0.0/16\n120.32.0.0/12\n120.48.0.0/16\n120.49.0.0/18\n120.52.0.0/15\n120.55.0.0/16\n120.65.0.0/16\n120.68.0.0/14\n120.72.32.0/19\n120.72.160.0/24\n120.72.162.0/23\n120.72.164.0/22\n120.72.168.0/24\n120.72.170.0/23\n120.72.172.0/23\n120.72.174.0/24\n120.72.177.0/24\n120.72.178.0/24\n120.72.180.0/24\n120.72.182.0/23\n120.72.184.0/22\n120.72.188.0/23\n120.72.190.0/24\n120.76.0.0/14\n120.80.0.0/13\n120.92.0.0/17\n120.92.128.0/18\n120.92.192.0/19\n120.92.224.0/20\n120.94.0.0/15\n120.128.0.0/21\n120.131.0.0/20\n120.131.64.0/19\n120.131.124.0/22\n120.132.0.0/18\n120.132.64.0/19\n120.132.96.0/20\n120.132.112.0/24\n120.132.116.0/22\n120.132.120.0/21\n120.132.128.0/17\n120.133.0.0/16\n120.134.0.0/15\n120.136.16.0/24\n120.136.20.0/22\n120.136.128.0/21\n120.136.156.0/22\n120.136.160.0/20\n120.136.176.0/22\n120.136.184.0/23\n120.192.0.0/10\n121.0.16.0/20\n121.4.0.0/15\n121.8.0.0/13\n121.16.0.0/12\n121.32.0.0/14\n121.36.0.0/15\n121.40.0.0/14\n121.46.0.0/19\n121.46.128.0/21\n121.46.192.0/21\n121.46.200.0/22\n121.46.224.0/20\n121.46.244.0/22\n121.46.248.0/22\n121.46.252.0/23\n121.46.254.0/24\n121.48.0.0/15\n121.51.0.0/16\n121.52.160.0/19\n121.52.208.0/20\n121.52.224.0/19\n121.55.0.0/18\n121.56.0.0/15\n121.58.0.0/17\n121.58.156.0/22\n121.60.0.0/14\n121.69.0.0/16\n121.76.0.0/15\n121.79.128.0/20\n121.79.144.0/22\n121.89.0.0/16\n121.91.104.0/21\n121.101.208.0/20\n121.192.0.0/13\n121.201.0.0/16\n121.204.0.0/14\n121.224.0.0/12\n121.248.0.0/14\n121.255.0.0/16\n122.0.64.0/18\n122.4.0.0/14\n122.9.0.0/16\n122.10.133.0/24\n122.10.136.0/23\n122.11.32.0/19\n122.13.0.0/16\n122.14.0.0/18\n122.14.192.0/18\n122.48.0.0/16\n122.49.8.0/21\n122.49.16.0/20\n122.49.32.0/20\n122.51.0.0/16\n122.64.0.0/12\n122.80.0.0/13\n122.88.0.0/15\n122.90.0.0/16\n122.91.0.0/17\n122.92.0.0/14\n122.96.0.0/15\n122.102.64.0/20\n122.112.0.0/18\n122.112.64.0/19\n122.112.132.0/22\n122.112.136.0/21\n122.112.144.0/20\n122.112.160.0/19\n122.112.192.0/18\n122.114.0.0/16\n122.115.0.0/20\n122.115.32.0/19\n122.115.224.0/20\n122.119.4.0/23\n122.119.12.0/22\n122.119.20.0/22\n122.119.24.0/23\n122.119.32.0/24\n122.119.50.0/24\n122.119.73.0/24\n122.119.96.0/23\n122.119.110.0/23\n122.119.112.0/23\n122.119.114.0/24\n122.119.120.0/24\n122.119.122.0/24\n122.119.124.0/23\n122.119.129.0/24\n122.119.147.0/24\n122.119.160.0/23\n122.119.172.0/24\n122.119.180.0/22\n122.119.190.0/24\n122.136.0.0/13\n122.144.128.0/17\n122.152.192.0/18\n122.156.0.0/14\n122.188.0.0/14\n122.192.0.0/14\n122.200.40.0/21\n122.200.64.0/18\n122.204.0.0/14\n122.224.0.0/12\n122.240.0.0/13\n122.248.48.0/21\n122.248.56.0/22\n123.4.0.0/14\n123.8.0.0/13\n123.49.241.0/24\n123.49.245.0/24\n123.52.0.0/14\n123.56.0.0/15\n123.58.0.0/18\n123.58.96.0/19\n123.58.160.0/19\n123.58.224.0/19\n123.59.0.0/16\n123.60.0.0/15\n123.64.0.0/12\n123.80.0.0/13\n123.90.0.0/15\n123.92.0.0/14\n123.96.0.0/15\n123.99.192.0/18\n123.101.0.0/16\n123.103.0.0/20\n123.103.16.0/21\n123.103.24.0/22\n123.103.28.0/23\n123.103.30.0/24\n123.103.40.0/21\n123.103.48.0/20\n123.103.64.0/18\n123.108.208.0/22\n123.108.212.0/23\n123.108.220.0/22\n123.112.0.0/12\n123.128.0.0/13\n123.138.0.0/15\n123.144.0.0/12\n123.160.0.0/12\n123.176.60.0/22\n123.177.0.0/16\n123.178.0.0/15\n123.180.0.0/14\n123.184.0.0/13\n123.196.112.0/20\n123.206.0.0/15\n123.232.0.0/14\n123.242.192.0/21\n123.244.0.0/14\n123.249.0.0/17\n123.254.96.0/21\n124.6.64.0/18\n124.14.1.0/24\n124.14.2.0/23\n124.14.5.0/24\n124.14.7.0/24\n124.14.8.0/22\n124.14.12.0/23\n124.14.15.0/24\n124.14.16.0/23\n124.14.18.0/24\n124.14.20.0/22\n124.14.64.0/18\n124.14.224.0/19\n124.16.0.0/15\n124.28.192.0/18\n124.29.0.0/17\n124.31.0.0/16\n124.40.112.0/20\n124.40.128.0/18\n124.42.0.0/16\n124.64.0.0/15\n124.66.0.0/17\n124.67.0.0/16\n124.70.0.0/16\n124.71.0.0/17\n124.71.128.0/18\n124.71.192.0/19\n124.71.224.0/20\n124.71.250.0/23\n124.72.0.0/13\n124.88.0.0/13\n124.112.0.0/13\n124.126.0.0/15\n124.128.0.0/13\n124.151.0.0/16\n124.152.0.0/16\n124.160.0.0/13\n124.172.0.0/15\n124.192.0.0/15\n124.196.0.0/20\n124.196.16.0/22\n124.196.20.0/24\n124.196.22.0/23\n124.196.24.0/22\n124.196.28.0/24\n124.196.30.0/23\n124.196.32.0/23\n124.196.34.0/24\n124.196.40.0/22\n124.196.48.0/22\n124.196.52.0/23\n124.196.55.0/24\n124.196.56.0/22\n124.196.60.0/23\n124.196.65.0/24\n124.196.66.0/24\n124.196.72.0/24\n124.196.74.0/24\n124.196.76.0/23\n124.196.78.0/24\n124.196.80.0/22\n124.200.0.0/16\n124.202.0.0/16\n124.203.176.0/20\n124.203.192.0/18\n124.204.0.0/14\n124.220.0.0/14\n124.224.0.0/12\n124.240.0.0/17\n124.240.128.0/18\n124.243.192.0/18\n124.248.0.0/22\n124.248.64.0/18\n124.249.0.0/17\n124.250.0.0/15\n124.254.0.0/18\n125.32.0.0/12\n125.58.128.0/17\n125.61.128.0/19\n125.62.0.0/18\n125.64.0.0/11\n125.96.48.0/20\n125.96.176.0/20\n125.96.240.0/21\n125.97.0.0/16\n125.98.122.0/23\n125.98.128.0/17\n125.104.0.0/13\n125.112.0.0/12\n125.171.0.0/16\n125.208.0.0/19\n125.208.32.0/24\n125.208.37.0/24\n125.208.40.0/24\n125.208.42.0/24\n125.208.46.0/24\n125.210.0.0/15\n125.213.32.0/20\n125.214.96.0/19\n125.215.0.0/18\n125.216.0.0/13\n125.254.128.0/19\n125.254.160.0/20\n125.254.176.0/21\n125.254.184.0/22\n125.254.188.0/23\n125.254.190.0/24\n128.108.0.0/16\n129.28.0.0/16\n129.204.0.0/16\n129.211.0.0/16\n130.36.146.0/23\n131.228.96.0/23\n132.232.0.0/16\n132.237.134.0/24\n134.175.0.0/16\n139.5.60.0/22\n139.9.0.0/17\n139.9.128.0/18\n139.9.192.0/19\n139.9.224.0/20\n139.9.240.0/21\n139.9.248.0/22\n139.129.0.0/16\n139.155.0.0/16\n139.159.0.0/19\n139.159.32.0/20\n139.159.96.0/20\n139.159.112.0/22\n139.159.132.0/22\n139.159.136.0/21\n139.159.144.0/20\n139.159.160.0/19\n139.159.192.0/18\n139.170.0.0/16\n139.186.0.0/16\n139.189.0.0/16\n139.196.0.0/16\n139.198.0.0/18\n139.199.0.0/16\n139.200.0.0/13\n139.208.0.0/13\n139.217.0.0/16\n139.219.0.0/16\n139.220.192.0/22\n139.220.240.0/22\n139.224.0.0/16\n139.226.0.0/15\n140.75.0.0/16\n140.143.0.0/16\n140.179.0.0/16\n140.205.0.0/16\n140.206.0.0/15\n140.210.0.0/19\n140.210.64.0/18\n140.210.128.0/19\n140.210.192.0/19\n140.210.224.0/20\n140.224.0.0/16\n140.237.0.0/16\n140.240.0.0/16\n140.242.223.0/24\n140.242.224.0/24\n140.243.0.0/16\n140.246.0.0/16\n140.249.0.0/16\n140.250.0.0/16\n140.255.0.0/16\n143.64.0.0/16\n144.0.0.0/16\n144.7.0.0/17\n144.12.0.0/16\n144.48.64.0/22\n144.48.212.0/22\n144.52.0.0/16\n144.123.0.0/16\n144.255.0.0/16\n146.56.192.0/18\n146.196.56.0/22\n146.196.68.0/22\n146.196.112.0/21\n146.217.137.0/24\n146.222.79.0/24\n146.222.81.0/24\n146.222.94.0/24\n148.70.0.0/16\n150.129.136.0/22\n150.129.192.0/22\n150.129.252.0/22\n150.138.0.0/15\n150.158.0.0/16\n150.223.0.0/16\n150.242.8.0/23\n150.242.56.0/22\n150.242.80.0/22\n150.242.96.0/22\n150.242.120.0/24\n150.242.122.0/23\n150.242.168.0/22\n150.242.184.0/22\n150.242.232.0/22\n150.242.238.0/23\n150.242.248.0/22\n150.255.0.0/16\n152.104.128.0/17\n152.136.0.0/16\n153.0.0.0/16\n153.3.0.0/16\n153.34.0.0/15\n153.36.0.0/15\n153.99.0.0/16\n153.101.0.0/16\n153.118.0.0/15\n154.8.128.0/17\n155.126.176.0/23\n156.107.160.0/24\n156.107.170.0/24\n156.107.179.0/24\n156.107.181.0/24\n156.248.0.0/22\n156.248.4.0/24\n157.0.0.0/16\n157.18.0.0/16\n157.61.0.0/16\n157.119.28.0/22\n157.119.172.0/22\n157.122.0.0/16\n157.148.0.0/16\n157.156.0.0/16\n157.255.0.0/16\n159.27.0.0/16\n159.75.0.0/16\n159.226.0.0/16\n160.19.208.0/21\n160.83.110.0/24\n160.202.60.0/22\n160.202.212.0/22\n161.163.0.0/21\n161.163.28.0/23\n161.189.0.0/16\n161.207.0.0/16\n162.14.0.0/16\n162.105.0.0/16\n163.0.0.0/16\n163.47.4.0/22\n163.53.36.0/22\n163.53.60.0/22\n163.53.88.0/21\n163.53.168.0/22\n163.125.0.0/16\n163.142.0.0/16\n163.177.0.0/16\n163.179.0.0/16\n163.204.0.0/16\n163.228.0.0/16\n163.244.246.0/24\n166.111.0.0/16\n167.139.0.0/16\n167.189.0.0/16\n167.220.244.0/22\n168.159.144.0/21\n168.159.152.0/22\n168.159.156.0/23\n168.159.158.0/24\n168.160.0.0/17\n168.160.152.0/24\n168.160.158.0/23\n168.160.160.0/21\n168.160.168.0/24\n168.160.224.0/19\n171.8.0.0/13\n171.34.0.0/15\n171.36.0.0/14\n171.40.0.0/14\n171.44.0.0/16\n171.80.0.0/12\n171.104.0.0/13\n171.112.0.0/12\n171.208.0.0/12\n172.81.192.0/18\n173.39.200.0/23\n175.0.0.0/12\n175.16.0.0/13\n175.24.0.0/15\n175.27.0.0/16\n175.30.0.0/15\n175.42.0.0/15\n175.44.0.0/16\n175.46.0.0/15\n175.48.0.0/12\n175.64.0.0/11\n175.102.0.0/19\n175.102.32.0/22\n175.102.128.0/21\n175.102.160.0/19\n175.102.192.0/22\n175.102.196.0/24\n175.106.128.0/17\n175.146.0.0/15\n175.148.0.0/14\n175.152.0.0/14\n175.160.0.0/12\n175.178.0.0/16\n175.184.128.0/18\n175.185.0.0/16\n175.186.0.0/15\n175.188.188.0/22\n175.190.24.0/21\n175.190.126.0/23\n180.76.16.0/20\n180.76.32.0/19\n180.76.64.0/18\n180.76.128.0/17\n180.77.0.0/16\n180.78.0.0/15\n180.84.0.0/15\n180.88.96.0/19\n180.88.128.0/18\n180.89.56.0/22\n180.89.60.0/23\n180.89.64.0/19\n180.91.192.0/20\n180.92.176.0/23\n180.95.128.0/17\n180.96.0.0/11\n180.129.128.0/17\n180.130.0.0/16\n180.136.0.0/13\n180.149.128.0/19\n180.150.176.0/20\n180.152.0.0/13\n180.160.0.0/12\n180.178.252.0/22\n180.184.0.0/21\n180.184.8.0/22\n180.184.12.0/23\n180.184.14.0/24\n180.184.16.0/24\n180.184.24.0/21\n180.184.32.0/19\n180.184.64.0/18\n180.184.128.0/20\n180.184.144.0/21\n180.184.152.0/22\n180.184.160.0/20\n180.184.176.0/21\n180.184.184.0/22\n180.184.190.0/23\n180.184.192.0/18\n180.186.38.0/23\n180.186.40.0/22\n180.186.44.0/24\n180.188.24.0/21\n180.188.32.0/22\n180.188.44.0/22\n180.200.252.0/22\n180.201.0.0/16\n180.203.0.0/23\n180.203.3.0/24\n180.208.0.0/15\n180.210.212.0/22\n180.212.0.0/15\n180.233.0.0/20\n180.235.64.0/21\n180.235.72.0/23\n182.18.5.0/24\n182.18.32.0/19\n182.18.64.0/18\n182.32.0.0/12\n182.48.96.0/20\n182.48.112.0/21\n182.50.8.0/21\n182.50.112.0/20\n182.51.0.0/24\n182.54.0.0/17\n182.61.0.0/18\n182.61.128.0/19\n182.61.192.0/22\n182.61.200.0/21\n182.61.216.0/21\n182.61.224.0/19\n182.84.0.0/14\n182.88.0.0/14\n182.92.0.0/16\n182.96.0.0/11\n182.128.0.0/12\n182.144.0.0/13\n182.157.0.0/16\n182.174.0.0/15\n182.200.0.0/13\n182.236.160.0/19\n182.240.0.0/13\n182.254.0.0/16\n183.0.0.0/10\n183.64.0.0/13\n183.78.180.0/22\n183.81.180.0/22\n183.84.0.0/15\n183.91.40.0/21\n183.91.56.0/24\n183.91.144.0/20\n183.92.0.0/14\n183.128.0.0/11\n183.160.0.0/13\n183.168.0.0/15\n183.170.0.0/16\n183.172.0.0/14\n183.184.0.0/13\n183.192.0.0/10\n188.131.128.0/17\n192.55.46.0/24\n192.55.68.0/22\n192.102.204.0/22\n192.140.208.0/21\n192.144.128.0/17\n192.163.11.0/24\n192.232.97.0/24\n193.17.120.0/22\n193.112.0.0/16\n194.138.202.0/23\n194.138.245.0/24\n198.175.100.0/22\n198.208.17.0/24\n198.208.19.0/24\n198.208.30.0/24\n198.208.61.0/24\n198.208.63.0/24\n198.208.67.0/24\n198.208.112.0/23\n199.244.144.0/24\n202.1.86.0/23\n202.1.90.0/23\n202.1.110.0/23\n202.1.112.0/23\n202.4.128.0/19\n202.4.252.0/22\n202.10.74.0/23\n202.10.76.0/22\n202.14.235.0/24\n202.14.236.0/23\n202.14.238.0/24\n202.30.124.0/24\n202.38.2.0/23\n202.38.8.0/21\n202.38.64.0/18\n202.38.128.0/23\n202.38.132.0/23\n202.38.134.0/24\n202.38.140.0/23\n202.38.152.0/23\n202.38.164.0/22\n202.38.184.0/21\n202.38.192.0/18\n202.41.152.0/21\n202.41.241.0/24\n202.41.242.0/23\n202.41.244.0/22\n202.41.248.0/21\n202.43.144.0/20\n202.47.104.0/21\n202.59.214.0/24\n202.60.112.0/20\n202.60.132.0/22\n202.61.88.0/22\n202.62.112.0/22\n202.63.160.0/20\n202.69.16.0/20\n202.72.112.0/20\n202.73.128.0/22\n202.73.240.0/20\n202.75.208.0/20\n202.76.247.0/24\n202.80.192.0/22\n202.81.176.0/20\n202.84.17.0/24\n202.85.208.0/20\n202.89.96.0/24\n202.89.232.0/21\n202.90.20.0/22\n202.90.96.0/20\n202.91.176.0/21\n202.91.184.0/23\n202.91.186.0/24\n202.91.188.0/24\n202.91.190.0/23\n202.91.224.0/20\n202.91.240.0/21\n202.91.248.0/22\n202.93.252.0/22\n202.94.1.0/24\n202.95.0.0/19\n202.96.0.0/12\n202.112.0.0/13\n202.120.0.0/15\n202.122.32.0/21\n202.122.112.0/21\n202.123.96.0/24\n202.123.98.0/24\n202.123.106.0/23\n202.123.108.0/24\n202.123.110.0/23\n202.123.120.0/22\n202.125.176.0/20\n202.127.0.0/21\n202.127.12.0/22\n202.127.16.0/20\n202.127.40.0/21\n202.127.48.0/23\n202.127.144.0/20\n202.127.200.0/21\n202.127.216.0/21\n202.127.224.0/19\n202.130.0.0/19\n202.130.224.0/20\n202.130.240.0/21\n202.136.48.0/20\n202.136.208.0/21\n202.136.216.0/23\n202.136.218.0/24\n202.136.220.0/24\n202.136.222.0/23\n202.136.255.0/24\n202.141.160.0/19\n202.143.16.0/23\n202.143.100.0/22\n202.148.96.0/19\n202.149.224.0/19\n202.152.176.0/20\n202.158.160.0/19\n202.165.208.0/20\n202.168.160.0/19\n202.170.128.0/19\n202.170.216.0/21\n202.173.8.0/22\n202.173.14.0/23\n202.173.224.0/19\n202.181.28.0/24\n202.181.124.0/22\n202.189.0.0/20\n202.192.0.0/12\n203.0.104.0/21\n203.2.64.0/21\n203.2.112.0/21\n203.2.160.0/22\n203.3.80.0/21\n203.3.112.0/21\n203.6.224.0/20\n203.15.0.0/20\n203.25.208.0/20\n203.32.204.0/23\n203.33.64.0/24\n203.33.145.0/24\n203.33.156.0/24\n203.33.174.0/24\n203.33.202.0/23\n203.33.206.0/23\n203.33.214.0/23\n203.33.224.0/23\n203.33.243.0/24\n203.33.250.0/24\n203.34.4.0/24\n203.34.21.0/24\n203.34.27.0/24\n203.34.39.0/24\n203.34.48.0/23\n203.34.54.0/24\n203.34.56.0/23\n203.34.67.0/24\n203.34.69.0/24\n203.34.76.0/24\n203.34.92.0/24\n203.34.106.0/24\n203.34.113.0/24\n203.34.147.0/24\n203.34.150.0/24\n203.34.152.0/23\n203.34.161.0/24\n203.34.162.0/24\n203.34.187.0/24\n203.34.232.0/24\n203.34.240.0/24\n203.34.242.0/24\n203.34.245.0/24\n203.34.251.0/24\n203.55.2.0/23\n203.55.4.0/24\n203.55.10.0/24\n203.55.13.0/24\n203.55.22.0/24\n203.55.30.0/24\n203.55.93.0/24\n203.55.101.0/24\n203.55.109.0/24\n203.55.110.0/24\n203.55.116.0/23\n203.55.119.0/24\n203.55.128.0/23\n203.55.146.0/23\n203.55.192.0/24\n203.55.196.0/24\n203.55.218.0/23\n203.55.221.0/24\n203.55.224.0/24\n203.56.1.0/24\n203.56.4.0/24\n203.56.12.0/24\n203.56.24.0/24\n203.56.38.0/24\n203.56.40.0/24\n203.56.46.0/24\n203.56.68.0/23\n203.56.82.0/23\n203.56.84.0/23\n203.56.95.0/24\n203.56.110.0/24\n203.56.121.0/24\n203.56.161.0/24\n203.56.169.0/24\n203.56.172.0/23\n203.56.175.0/24\n203.56.183.0/24\n203.56.185.0/24\n203.56.187.0/24\n203.56.192.0/24\n203.56.198.0/24\n203.56.201.0/24\n203.56.208.0/23\n203.56.210.0/24\n203.56.214.0/24\n203.56.228.0/24\n203.56.232.0/24\n203.56.240.0/24\n203.56.252.0/24\n203.56.254.0/24\n203.57.5.0/24\n203.57.6.0/24\n203.57.12.0/23\n203.57.28.0/24\n203.57.39.0/24\n203.57.46.0/24\n203.57.58.0/24\n203.57.61.0/24\n203.57.70.0/23\n203.57.101.0/24\n203.57.109.0/24\n203.57.123.0/24\n203.57.157.0/24\n203.57.200.0/24\n203.57.202.0/24\n203.57.206.0/24\n203.57.222.0/24\n203.57.224.0/20\n203.57.249.0/24\n203.57.254.0/23\n203.62.2.0/24\n203.62.131.0/24\n203.62.139.0/24\n203.65.240.0/22\n203.76.208.0/21\n203.76.216.0/22\n203.76.240.0/22\n203.78.48.0/20\n203.80.57.0/24\n203.80.144.0/20\n203.82.0.0/23\n203.83.56.0/21\n203.86.0.0/18\n203.86.64.0/19\n203.86.254.0/23\n203.88.32.0/19\n203.88.192.0/19\n203.90.128.0/18\n203.90.192.0/19\n203.91.32.0/19\n203.91.120.0/21\n203.93.0.0/18\n203.93.64.0/19\n203.93.96.0/20\n203.93.117.0/24\n203.93.120.0/21\n203.93.128.0/19\n203.93.160.0/20\n203.93.208.0/20\n203.93.224.0/19\n203.94.0.0/19\n203.95.0.0/21\n203.95.96.0/22\n203.95.104.0/21\n203.99.20.0/24\n203.99.22.0/23\n203.99.24.0/22\n203.99.30.0/23\n203.100.87.0/24\n203.100.92.0/22\n203.100.192.0/20\n203.104.32.0/20\n203.107.1.0/24\n203.107.6.0/24\n203.107.13.0/24\n203.107.20.0/22\n203.107.26.0/23\n203.107.28.0/22\n203.107.32.0/19\n203.107.72.0/21\n203.107.80.0/21\n203.107.96.0/23\n203.107.100.0/22\n203.107.104.0/22\n203.107.108.0/23\n203.110.160.0/19\n203.110.208.0/20\n203.114.244.0/22\n203.118.248.0/22\n203.119.25.0/24\n203.119.30.0/24\n203.119.80.0/23\n203.119.83.0/24\n203.119.85.0/24\n203.119.128.0/19\n203.119.168.0/21\n203.119.176.0/20\n203.119.192.0/18\n203.130.32.0/22\n203.130.40.0/21\n203.132.32.0/19\n203.134.240.0/21\n203.135.96.0/19\n203.148.0.0/18\n203.148.64.0/20\n203.156.192.0/18\n203.160.129.0/24\n203.160.212.0/24\n203.161.192.0/19\n203.166.160.0/22\n203.166.165.0/24\n203.166.166.0/24\n203.166.168.0/24\n203.166.172.0/24\n203.166.176.0/23\n203.166.180.0/24\n203.166.186.0/23\n203.166.188.0/23\n203.166.191.0/24\n203.168.0.0/23\n203.168.2.0/24\n203.168.16.0/23\n203.168.18.0/24\n203.174.4.0/24\n203.175.128.0/19\n203.176.168.0/24\n203.176.170.0/24\n203.187.160.0/19\n203.189.0.0/23\n203.189.6.0/23\n203.189.192.0/19\n203.189.240.0/22\n203.191.0.0/23\n203.191.144.0/21\n203.192.1.0/24\n203.192.2.0/23\n203.192.4.0/22\n203.192.8.0/21\n203.192.16.0/24\n203.192.24.0/23\n203.193.224.0/19\n203.195.64.0/19\n203.195.128.0/17\n203.196.0.0/21\n203.202.236.0/23\n203.205.64.0/19\n203.207.64.0/19\n203.207.96.0/21\n203.207.104.0/22\n203.207.112.0/20\n203.207.128.0/18\n203.207.192.0/21\n203.207.200.0/22\n203.207.208.0/20\n203.207.224.0/19\n203.208.32.0/19\n203.209.224.0/19\n203.212.0.0/20\n203.212.80.0/23\n203.215.232.0/23\n203.215.236.0/24\n206.119.53.0/24\n210.2.4.0/24\n210.5.18.0/24\n210.5.25.0/24\n210.5.29.0/24\n210.5.128.0/19\n210.12.0.0/16\n210.13.0.0/17\n210.13.192.0/19\n210.13.224.0/24\n210.13.227.0/24\n210.13.230.0/23\n210.13.232.0/24\n210.13.236.0/23\n210.13.238.0/24\n210.13.240.0/20\n210.14.64.0/19\n210.14.112.0/20\n210.14.128.0/19\n210.14.192.0/18\n210.15.0.0/17\n210.16.180.0/24\n210.16.185.0/24\n210.16.186.0/23\n210.16.188.0/22\n210.21.0.0/17\n210.21.192.0/18\n210.22.0.0/19\n210.22.32.0/22\n210.22.48.0/20\n210.22.64.0/18\n210.22.128.0/17\n210.25.0.0/16\n210.26.0.0/15\n210.28.0.0/14\n210.32.0.0/12\n210.51.0.0/16\n210.52.0.0/15\n210.72.0.0/17\n210.72.128.0/18\n210.72.192.0/19\n210.72.224.0/20\n210.72.240.0/21\n210.73.0.0/16\n210.74.0.0/20\n210.74.35.0/24\n210.74.36.0/23\n210.74.38.0/24\n210.74.40.0/22\n210.74.44.0/23\n210.74.47.0/24\n210.74.64.0/23\n210.74.107.0/24\n210.74.108.0/23\n210.74.128.0/18\n210.74.224.0/19\n210.75.0.0/18\n210.75.88.0/24\n210.75.96.0/19\n210.75.192.0/18\n210.76.32.0/19\n210.76.64.0/18\n210.76.160.0/19\n210.76.192.0/19\n210.77.0.0/18\n210.77.64.0/19\n210.77.128.0/19\n210.77.176.0/21\n210.77.184.0/23\n210.77.189.0/24\n210.77.190.0/23\n210.77.192.0/18\n210.78.128.0/24\n210.78.133.0/24\n210.78.134.0/23\n210.78.136.0/22\n210.78.144.0/23\n210.78.147.0/24\n210.79.224.0/19\n210.82.0.0/15\n210.185.192.0/18\n210.192.96.0/20\n210.192.116.0/22\n210.192.120.0/21\n211.64.0.0/13\n211.80.0.0/13\n211.88.0.0/15\n211.90.0.0/17\n211.90.128.0/18\n211.90.216.0/21\n211.90.224.0/19\n211.91.0.0/18\n211.91.64.0/19\n211.91.96.0/20\n211.91.120.0/21\n211.91.128.0/19\n211.91.160.0/20\n211.91.176.0/21\n211.91.216.0/21\n211.91.224.0/19\n211.92.0.0/17\n211.92.128.0/18\n211.92.192.0/19\n211.92.224.0/20\n211.92.240.0/21\n211.93.0.0/17\n211.93.128.0/18\n211.93.192.0/21\n211.93.200.0/23\n211.93.204.0/22\n211.93.211.0/24\n211.93.212.0/23\n211.93.224.0/19\n211.94.64.0/18\n211.94.128.0/17\n211.95.0.0/17\n211.95.128.0/19\n211.95.192.0/18\n211.96.0.0/16\n211.97.0.0/17\n211.97.128.0/19\n211.97.160.0/21\n211.97.192.0/18\n211.98.0.0/16\n211.99.8.0/21\n211.99.16.0/23\n211.99.25.0/24\n211.99.26.0/24\n211.99.28.0/23\n211.99.30.0/24\n211.99.32.0/19\n211.99.64.0/19\n211.99.96.0/20\n211.99.112.0/21\n211.99.120.0/23\n211.99.122.0/24\n211.99.128.0/17\n211.100.0.0/17\n211.100.192.0/20\n211.100.224.0/19\n211.101.0.0/18\n211.101.192.0/20\n211.101.232.0/21\n211.101.240.0/21\n211.102.80.0/20\n211.102.128.0/18\n211.102.192.0/23\n211.102.208.0/20\n211.103.0.0/16\n211.136.0.0/13\n211.144.9.0/24\n211.144.10.0/24\n211.144.12.0/22\n211.144.16.0/24\n211.144.18.0/23\n211.144.20.0/24\n211.144.22.0/24\n211.144.24.0/24\n211.144.27.0/24\n211.144.28.0/23\n211.144.64.0/18\n211.144.192.0/18\n211.145.0.0/18\n211.145.64.0/20\n211.146.0.0/16\n211.147.0.0/18\n211.147.64.0/19\n211.147.128.0/18\n211.147.208.0/20\n211.147.224.0/19\n211.148.0.0/17\n211.148.128.0/19\n211.148.160.0/22\n211.148.164.0/23\n211.148.166.0/24\n211.148.168.0/22\n211.148.172.0/24\n211.148.180.0/24\n211.148.184.0/24\n211.148.187.0/24\n211.148.188.0/22\n211.148.192.0/18\n211.149.128.0/17\n211.150.0.0/18\n211.150.64.0/19\n211.150.98.0/24\n211.150.100.0/23\n211.150.114.0/23\n211.150.122.0/24\n211.150.124.0/23\n211.150.127.0/24\n211.150.128.0/24\n211.151.0.0/16\n211.152.0.0/17\n211.152.192.0/22\n211.152.196.0/23\n211.152.208.0/20\n211.153.0.0/16\n211.154.0.0/19\n211.154.64.0/18\n211.154.128.0/17\n211.155.0.0/18\n211.155.80.0/20\n211.155.120.0/21\n211.155.128.0/19\n211.155.160.0/20\n211.155.176.0/22\n211.155.184.0/21\n211.155.224.0/21\n211.155.232.0/22\n211.155.236.0/24\n211.155.240.0/20\n211.156.0.0/19\n211.156.128.0/19\n211.156.176.0/20\n211.156.192.0/20\n211.156.208.0/21\n211.156.216.0/22\n211.156.220.0/23\n211.156.223.0/24\n211.157.0.0/19\n211.157.96.0/19\n211.157.128.0/17\n211.158.0.0/16\n211.159.64.0/21\n211.159.128.0/17\n211.160.0.0/22\n211.160.4.0/24\n211.160.9.0/24\n211.160.10.0/23\n211.160.15.0/24\n211.160.16.0/24\n211.160.19.0/24\n211.160.20.0/22\n211.160.24.0/24\n211.160.27.0/24\n211.160.28.0/23\n211.160.36.0/23\n211.160.46.0/24\n211.160.62.0/24\n211.160.72.0/21\n211.160.80.0/20\n211.160.112.0/23\n211.160.115.0/24\n211.160.120.0/24\n211.160.160.0/19\n211.160.195.0/24\n211.160.196.0/24\n211.160.203.0/24\n211.160.205.0/24\n211.160.240.0/20\n211.161.0.0/20\n211.161.20.0/22\n211.161.24.0/22\n211.161.32.0/20\n211.161.52.0/22\n211.161.56.0/21\n211.161.80.0/20\n211.161.97.0/24\n211.161.101.0/24\n211.161.102.0/23\n211.161.120.0/21\n211.161.128.0/20\n211.161.192.0/22\n211.161.203.0/24\n211.161.209.0/24\n211.161.221.0/24\n211.162.0.0/21\n211.162.32.0/21\n211.162.64.0/20\n211.162.112.0/20\n211.162.192.0/22\n211.162.200.0/22\n211.162.236.0/22\n211.162.240.0/20\n211.165.0.0/16\n211.166.0.0/16\n211.167.64.0/24\n211.167.96.0/19\n211.167.128.0/19\n211.167.176.0/20\n211.167.224.0/19\n212.64.0.0/17\n212.129.128.0/17\n218.0.0.0/11\n218.56.0.0/13\n218.64.0.0/11\n218.96.0.0/24\n218.96.64.0/22\n218.96.104.0/22\n218.96.108.0/23\n218.96.241.0/24\n218.96.244.0/24\n218.96.255.0/24\n218.97.0.0/17\n218.97.160.0/19\n218.97.192.0/19\n218.97.240.0/20\n218.98.0.0/18\n218.98.96.0/21\n218.98.104.0/22\n218.98.108.0/23\n218.98.111.0/24\n218.98.112.0/22\n218.98.160.0/24\n218.98.176.0/24\n218.104.0.0/15\n218.106.0.0/16\n218.107.0.0/18\n218.107.128.0/17\n218.108.0.0/15\n218.192.0.0/12\n218.213.85.0/24\n218.240.0.0/18\n218.240.128.0/17\n218.241.16.0/21\n218.241.96.0/20\n218.241.112.0/24\n218.241.115.0/24\n218.241.116.0/22\n218.241.120.0/21\n218.241.128.0/17\n218.242.0.0/16\n218.244.0.0/19\n218.244.44.0/22\n218.244.49.0/24\n218.244.52.0/23\n218.244.55.0/24\n218.244.56.0/23\n218.244.58.0/24\n218.244.96.0/19\n218.244.128.0/18\n218.244.192.0/20\n218.244.224.0/19\n218.245.0.0/17\n218.246.22.0/24\n218.246.32.0/22\n218.246.64.0/18\n218.246.160.0/19\n218.246.192.0/19\n218.247.0.0/18\n218.247.128.0/17\n218.249.0.0/16\n219.72.0.0/16\n219.82.0.0/16\n219.83.160.0/19\n219.128.0.0/12\n219.144.0.0/14\n219.148.0.0/15\n219.150.0.0/16\n219.151.0.0/18\n219.151.128.0/17\n219.152.0.0/14\n219.156.0.0/15\n219.158.0.0/19\n219.158.32.0/20\n219.158.58.0/23\n219.158.60.0/22\n219.158.96.0/19\n219.158.128.0/17\n219.159.0.0/16\n219.216.0.0/13\n219.224.0.0/13\n219.232.0.0/17\n219.232.160.0/19\n219.232.192.0/19\n219.233.0.0/16\n219.234.0.0/21\n219.234.80.0/20\n219.234.96.0/19\n219.234.128.0/17\n219.235.0.0/17\n219.235.128.0/20\n219.235.144.0/21\n219.235.192.0/18\n219.236.0.0/14\n219.242.0.0/15\n219.244.0.0/14\n220.101.192.0/18\n220.112.0.0/18\n220.112.192.0/20\n220.112.224.0/19\n220.113.0.0/18\n220.113.96.0/21\n220.113.128.0/21\n220.113.136.0/22\n220.113.144.0/20\n220.113.160.0/20\n220.113.180.0/22\n220.113.184.0/22\n220.113.224.0/19\n220.114.64.0/21\n220.114.248.0/22\n220.115.8.0/21\n220.115.16.0/20\n220.115.228.0/22\n220.115.232.0/21\n220.115.240.0/21\n220.152.128.0/17\n220.160.0.0/12\n220.176.0.0/14\n220.180.0.0/16\n220.181.0.0/17\n220.181.128.0/20\n220.181.144.0/24\n220.181.148.0/22\n220.181.152.0/21\n220.181.160.0/20\n220.181.176.0/21\n220.181.184.0/22\n220.181.188.0/23\n220.181.190.0/24\n220.182.0.0/18\n220.184.0.0/13\n220.192.0.0/16\n220.193.0.0/17\n220.194.0.0/16\n220.195.0.0/17\n220.195.128.0/19\n220.195.192.0/18\n220.196.0.0/16\n220.197.0.0/17\n220.197.160.0/19\n220.197.192.0/18\n220.198.0.0/15\n220.200.0.0/17\n220.200.128.0/20\n220.200.148.0/22\n220.200.152.0/21\n220.200.160.0/19\n220.200.192.0/18\n220.201.0.0/16\n220.202.0.0/16\n220.203.0.0/18\n220.203.216.0/23\n220.203.220.0/22\n220.203.224.0/19\n220.205.0.0/16\n220.206.192.0/22\n220.207.0.0/22\n220.207.80.0/20\n220.207.176.0/22\n220.207.184.0/22\n220.207.254.0/23\n220.231.0.0/18\n220.231.128.0/17\n220.232.64.0/18\n220.234.0.0/16\n220.243.128.0/18\n220.248.0.0/16\n220.249.0.0/17\n220.249.128.0/18\n220.249.192.0/19\n220.249.240.0/20\n220.250.0.0/17\n221.0.0.0/13\n221.8.0.0/14\n221.12.0.0/17\n221.12.128.0/18\n221.13.0.0/16\n221.14.0.0/15\n221.122.0.0/16\n221.123.128.0/17\n221.129.16.0/23\n221.129.64.0/23\n221.129.72.0/22\n221.129.76.0/23\n221.129.80.0/24\n221.129.230.0/23\n221.129.242.0/23\n221.129.244.0/22\n221.129.248.0/23\n221.129.252.0/24\n221.130.0.0/15\n221.133.225.0/24\n221.133.226.0/23\n221.133.228.0/22\n221.133.232.0/22\n221.133.240.0/20\n221.137.0.0/16\n221.172.0.0/14\n221.176.0.0/13\n221.192.0.0/14\n221.196.0.0/15\n221.198.0.0/16\n221.199.0.0/17\n221.199.128.0/18\n221.199.192.0/20\n221.199.224.0/19\n221.200.0.0/13\n221.208.0.0/12\n221.224.0.0/12\n222.16.0.0/12\n222.32.0.0/11\n222.64.0.0/11\n222.125.0.0/16\n222.126.128.0/17\n222.128.0.0/12\n222.160.0.0/14\n222.168.0.0/13\n222.176.0.0/12\n222.192.0.0/11\n222.240.0.0/13\n222.248.0.0/15\n223.0.1.0/24\n223.0.2.0/24\n223.0.8.0/23\n223.0.10.0/24\n223.0.12.0/23\n223.0.15.0/24\n223.0.16.0/24\n223.0.20.0/24\n223.0.30.0/24\n223.0.126.0/24\n223.2.0.0/15\n223.4.0.0/14\n223.8.0.0/13\n223.27.184.0/22\n223.64.0.0/10\n223.128.0.0/15\n223.144.0.0/12\n223.160.0.0/20\n223.160.16.0/21\n223.160.112.0/20\n223.160.128.0/22\n223.160.134.0/23\n223.160.136.0/21\n223.160.144.0/20\n223.160.160.0/19\n223.160.192.0/19\n223.160.224.0/21\n223.160.232.0/22\n223.160.236.0/23\n223.166.0.0/15\n223.192.0.0/15\n223.198.0.0/15\n223.202.0.0/24\n223.202.17.0/24\n223.202.20.0/24\n223.202.25.0/24\n223.202.67.0/24\n223.202.131.0/24\n223.202.132.0/24\n223.202.134.0/23\n223.202.193.0/24\n223.202.196.0/24\n223.202.198.0/23\n223.202.208.0/24\n223.202.211.0/24\n223.202.212.0/24\n223.203.3.0/24\n223.203.9.0/24\n223.203.96.0/24\n223.203.100.0/24\n223.203.208.0/24\n223.210.0.0/19\n223.210.48.0/22\n223.212.0.0/14\n223.220.0.0/15\n223.223.176.0/20\n223.223.192.0/20\n223.240.0.0/13\n223.248.0.0/14\n223.252.192.0/19\n223.255.236.0/22\n223.255.252.0/23\n"
  },
  {
    "path": "crypto-js.js",
    "content": ";(function (root, factory) {\n\tif (typeof exports === \"object\") {\n\t\t// CommonJS\n\t\tmodule.exports = exports = factory();\n\t}\n\telse if (typeof define === \"function\" && define.amd) {\n\t\t// AMD\n\t\tdefine([], factory);\n\t}\n\telse {\n\t\t// Global (browser)\n\t\troot.CryptoJS = factory();\n\t}\n}(this, function () {\n\n\t/*globals window, global, require*/\n\n\t/**\n\t * CryptoJS core components.\n\t */\n\tvar CryptoJS = CryptoJS || (function (Math, undefined) {\n\n\t    var crypto;\n\n\t    // Native crypto from window (Browser)\n\t    if (typeof window !== 'undefined' && window.crypto) {\n\t        crypto = window.crypto;\n\t    }\n\n\t    // Native (experimental IE 11) crypto from window (Browser)\n\t    if (!crypto && typeof window !== 'undefined' && window.msCrypto) {\n\t        crypto = window.msCrypto;\n\t    }\n\n\t    // Native crypto from global (NodeJS)\n\t    if (!crypto && typeof global !== 'undefined' && global.crypto) {\n\t        crypto = global.crypto;\n\t    }\n\n\t    // Native crypto import via require (NodeJS)\n\t    if (!crypto && typeof require === 'function') {\n\t        try {\n\t            crypto = require('crypto');\n\t        } catch (err) {}\n\t    }\n\n\t    /*\n\t     * Cryptographically secure pseudorandom number generator\n\t     *\n\t     * As Math.random() is cryptographically not safe to use\n\t     */\n\t    var cryptoSecureRandomInt = function () {\n\t        if (crypto) {\n\t            // Use getRandomValues method (Browser)\n\t            if (typeof crypto.getRandomValues === 'function') {\n\t                try {\n\t                    return crypto.getRandomValues(new Uint32Array(1))[0];\n\t                } catch (err) {}\n\t            }\n\n\t            // Use randomBytes method (NodeJS)\n\t            if (typeof crypto.randomBytes === 'function') {\n\t                try {\n\t                    return crypto.randomBytes(4).readInt32LE();\n\t                } catch (err) {}\n\t            }\n\t        }\n\n\t        throw new Error('Native crypto module could not be used to get secure random number.');\n\t    };\n\n\t    /*\n\t     * Local polyfill of Object.create\n\n\t     */\n\t    var create = Object.create || (function () {\n\t        function F() {}\n\n\t        return function (obj) {\n\t            var subtype;\n\n\t            F.prototype = obj;\n\n\t            subtype = new F();\n\n\t            F.prototype = null;\n\n\t            return subtype;\n\t        };\n\t    }())\n\n\t    /**\n\t     * CryptoJS namespace.\n\t     */\n\t    var C = {};\n\n\t    /**\n\t     * Library namespace.\n\t     */\n\t    var C_lib = C.lib = {};\n\n\t    /**\n\t     * Base object for prototypal inheritance.\n\t     */\n\t    var Base = C_lib.Base = (function () {\n\n\n\t        return {\n\t            /**\n\t             * Creates a new object that inherits from this object.\n\t             *\n\t             * @param {Object} overrides Properties to copy into the new object.\n\t             *\n\t             * @return {Object} The new object.\n\t             *\n\t             * @static\n\t             *\n\t             * @example\n\t             *\n\t             *     var MyType = CryptoJS.lib.Base.extend({\n\t             *         field: 'value',\n\t             *\n\t             *         method: function () {\n\t             *         }\n\t             *     });\n\t             */\n\t            extend: function (overrides) {\n\t                // Spawn\n\t                var subtype = create(this);\n\n\t                // Augment\n\t                if (overrides) {\n\t                    subtype.mixIn(overrides);\n\t                }\n\n\t                // Create default initializer\n\t                if (!subtype.hasOwnProperty('init') || this.init === subtype.init) {\n\t                    subtype.init = function () {\n\t                        subtype.$super.init.apply(this, arguments);\n\t                    };\n\t                }\n\n\t                // Initializer's prototype is the subtype object\n\t                subtype.init.prototype = subtype;\n\n\t                // Reference supertype\n\t                subtype.$super = this;\n\n\t                return subtype;\n\t            },\n\n\t            /**\n\t             * Extends this object and runs the init method.\n\t             * Arguments to create() will be passed to init().\n\t             *\n\t             * @return {Object} The new object.\n\t             *\n\t             * @static\n\t             *\n\t             * @example\n\t             *\n\t             *     var instance = MyType.create();\n\t             */\n\t            create: function () {\n\t                var instance = this.extend();\n\t                instance.init.apply(instance, arguments);\n\n\t                return instance;\n\t            },\n\n\t            /**\n\t             * Initializes a newly created object.\n\t             * Override this method to add some logic when your objects are created.\n\t             *\n\t             * @example\n\t             *\n\t             *     var MyType = CryptoJS.lib.Base.extend({\n\t             *         init: function () {\n\t             *             // ...\n\t             *         }\n\t             *     });\n\t             */\n\t            init: function () {\n\t            },\n\n\t            /**\n\t             * Copies properties into this object.\n\t             *\n\t             * @param {Object} properties The properties to mix in.\n\t             *\n\t             * @example\n\t             *\n\t             *     MyType.mixIn({\n\t             *         field: 'value'\n\t             *     });\n\t             */\n\t            mixIn: function (properties) {\n\t                for (var propertyName in properties) {\n\t                    if (properties.hasOwnProperty(propertyName)) {\n\t                        this[propertyName] = properties[propertyName];\n\t                    }\n\t                }\n\n\t                // IE won't copy toString using the loop above\n\t                if (properties.hasOwnProperty('toString')) {\n\t                    this.toString = properties.toString;\n\t                }\n\t            },\n\n\t            /**\n\t             * Creates a copy of this object.\n\t             *\n\t             * @return {Object} The clone.\n\t             *\n\t             * @example\n\t             *\n\t             *     var clone = instance.clone();\n\t             */\n\t            clone: function () {\n\t                return this.init.prototype.extend(this);\n\t            }\n\t        };\n\t    }());\n\n\t    /**\n\t     * An array of 32-bit words.\n\t     *\n\t     * @property {Array} words The array of 32-bit words.\n\t     * @property {number} sigBytes The number of significant bytes in this word array.\n\t     */\n\t    var WordArray = C_lib.WordArray = Base.extend({\n\t        /**\n\t         * Initializes a newly created word array.\n\t         *\n\t         * @param {Array} words (Optional) An array of 32-bit words.\n\t         * @param {number} sigBytes (Optional) The number of significant bytes in the words.\n\t         *\n\t         * @example\n\t         *\n\t         *     var wordArray = CryptoJS.lib.WordArray.create();\n\t         *     var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]);\n\t         *     var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6);\n\t         */\n\t        init: function (words, sigBytes) {\n\t            words = this.words = words || [];\n\n\t            if (sigBytes != undefined) {\n\t                this.sigBytes = sigBytes;\n\t            } else {\n\t                this.sigBytes = words.length * 4;\n\t            }\n\t        },\n\n\t        /**\n\t         * Converts this word array to a string.\n\t         *\n\t         * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex\n\t         *\n\t         * @return {string} The stringified word array.\n\t         *\n\t         * @example\n\t         *\n\t         *     var string = wordArray + '';\n\t         *     var string = wordArray.toString();\n\t         *     var string = wordArray.toString(CryptoJS.enc.Utf8);\n\t         */\n\t        toString: function (encoder) {\n\t            return (encoder || Hex).stringify(this);\n\t        },\n\n\t        /**\n\t         * Concatenates a word array to this word array.\n\t         *\n\t         * @param {WordArray} wordArray The word array to append.\n\t         *\n\t         * @return {WordArray} This word array.\n\t         *\n\t         * @example\n\t         *\n\t         *     wordArray1.concat(wordArray2);\n\t         */\n\t        concat: function (wordArray) {\n\t            // Shortcuts\n\t            var thisWords = this.words;\n\t            var thatWords = wordArray.words;\n\t            var thisSigBytes = this.sigBytes;\n\t            var thatSigBytes = wordArray.sigBytes;\n\n\t            // Clamp excess bits\n\t            this.clamp();\n\n\t            // Concat\n\t            if (thisSigBytes % 4) {\n\t                // Copy one byte at a time\n\t                for (var i = 0; i < thatSigBytes; i++) {\n\t                    var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;\n\t                    thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8);\n\t                }\n\t            } else {\n\t                // Copy one word at a time\n\t                for (var i = 0; i < thatSigBytes; i += 4) {\n\t                    thisWords[(thisSigBytes + i) >>> 2] = thatWords[i >>> 2];\n\t                }\n\t            }\n\t            this.sigBytes += thatSigBytes;\n\n\t            // Chainable\n\t            return this;\n\t        },\n\n\t        /**\n\t         * Removes insignificant bits.\n\t         *\n\t         * @example\n\t         *\n\t         *     wordArray.clamp();\n\t         */\n\t        clamp: function () {\n\t            // Shortcuts\n\t            var words = this.words;\n\t            var sigBytes = this.sigBytes;\n\n\t            // Clamp\n\t            words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8);\n\t            words.length = Math.ceil(sigBytes / 4);\n\t        },\n\n\t        /**\n\t         * Creates a copy of this word array.\n\t         *\n\t         * @return {WordArray} The clone.\n\t         *\n\t         * @example\n\t         *\n\t         *     var clone = wordArray.clone();\n\t         */\n\t        clone: function () {\n\t            var clone = Base.clone.call(this);\n\t            clone.words = this.words.slice(0);\n\n\t            return clone;\n\t        },\n\n\t        /**\n\t         * Creates a word array filled with random bytes.\n\t         *\n\t         * @param {number} nBytes The number of random bytes to generate.\n\t         *\n\t         * @return {WordArray} The random word array.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var wordArray = CryptoJS.lib.WordArray.random(16);\n\t         */\n\t        random: function (nBytes) {\n\t            var words = [];\n\n\t            for (var i = 0; i < nBytes; i += 4) {\n\t                words.push(cryptoSecureRandomInt());\n\t            }\n\n\t            return new WordArray.init(words, nBytes);\n\t        }\n\t    });\n\n\t    /**\n\t     * Encoder namespace.\n\t     */\n\t    var C_enc = C.enc = {};\n\n\t    /**\n\t     * Hex encoding strategy.\n\t     */\n\t    var Hex = C_enc.Hex = {\n\t        /**\n\t         * Converts a word array to a hex string.\n\t         *\n\t         * @param {WordArray} wordArray The word array.\n\t         *\n\t         * @return {string} The hex string.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var hexString = CryptoJS.enc.Hex.stringify(wordArray);\n\t         */\n\t        stringify: function (wordArray) {\n\t            // Shortcuts\n\t            var words = wordArray.words;\n\t            var sigBytes = wordArray.sigBytes;\n\n\t            // Convert\n\t            var hexChars = [];\n\t            for (var i = 0; i < sigBytes; i++) {\n\t                var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;\n\t                hexChars.push((bite >>> 4).toString(16));\n\t                hexChars.push((bite & 0x0f).toString(16));\n\t            }\n\n\t            return hexChars.join('');\n\t        },\n\n\t        /**\n\t         * Converts a hex string to a word array.\n\t         *\n\t         * @param {string} hexStr The hex string.\n\t         *\n\t         * @return {WordArray} The word array.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var wordArray = CryptoJS.enc.Hex.parse(hexString);\n\t         */\n\t        parse: function (hexStr) {\n\t            // Shortcut\n\t            var hexStrLength = hexStr.length;\n\n\t            // Convert\n\t            var words = [];\n\t            for (var i = 0; i < hexStrLength; i += 2) {\n\t                words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4);\n\t            }\n\n\t            return new WordArray.init(words, hexStrLength / 2);\n\t        }\n\t    };\n\n\t    /**\n\t     * Latin1 encoding strategy.\n\t     */\n\t    var Latin1 = C_enc.Latin1 = {\n\t        /**\n\t         * Converts a word array to a Latin1 string.\n\t         *\n\t         * @param {WordArray} wordArray The word array.\n\t         *\n\t         * @return {string} The Latin1 string.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var latin1String = CryptoJS.enc.Latin1.stringify(wordArray);\n\t         */\n\t        stringify: function (wordArray) {\n\t            // Shortcuts\n\t            var words = wordArray.words;\n\t            var sigBytes = wordArray.sigBytes;\n\n\t            // Convert\n\t            var latin1Chars = [];\n\t            for (var i = 0; i < sigBytes; i++) {\n\t                var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;\n\t                latin1Chars.push(String.fromCharCode(bite));\n\t            }\n\n\t            return latin1Chars.join('');\n\t        },\n\n\t        /**\n\t         * Converts a Latin1 string to a word array.\n\t         *\n\t         * @param {string} latin1Str The Latin1 string.\n\t         *\n\t         * @return {WordArray} The word array.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var wordArray = CryptoJS.enc.Latin1.parse(latin1String);\n\t         */\n\t        parse: function (latin1Str) {\n\t            // Shortcut\n\t            var latin1StrLength = latin1Str.length;\n\n\t            // Convert\n\t            var words = [];\n\t            for (var i = 0; i < latin1StrLength; i++) {\n\t                words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8);\n\t            }\n\n\t            return new WordArray.init(words, latin1StrLength);\n\t        }\n\t    };\n\n\t    /**\n\t     * UTF-8 encoding strategy.\n\t     */\n\t    var Utf8 = C_enc.Utf8 = {\n\t        /**\n\t         * Converts a word array to a UTF-8 string.\n\t         *\n\t         * @param {WordArray} wordArray The word array.\n\t         *\n\t         * @return {string} The UTF-8 string.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var utf8String = CryptoJS.enc.Utf8.stringify(wordArray);\n\t         */\n\t        stringify: function (wordArray) {\n\t            try {\n\t                return decodeURIComponent(escape(Latin1.stringify(wordArray)));\n\t            } catch (e) {\n\t                throw new Error('Malformed UTF-8 data');\n\t            }\n\t        },\n\n\t        /**\n\t         * Converts a UTF-8 string to a word array.\n\t         *\n\t         * @param {string} utf8Str The UTF-8 string.\n\t         *\n\t         * @return {WordArray} The word array.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var wordArray = CryptoJS.enc.Utf8.parse(utf8String);\n\t         */\n\t        parse: function (utf8Str) {\n\t            return Latin1.parse(unescape(encodeURIComponent(utf8Str)));\n\t        }\n\t    };\n\n\t    /**\n\t     * Abstract buffered block algorithm template.\n\t     *\n\t     * The property blockSize must be implemented in a concrete subtype.\n\t     *\n\t     * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0\n\t     */\n\t    var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({\n\t        /**\n\t         * Resets this block algorithm's data buffer to its initial state.\n\t         *\n\t         * @example\n\t         *\n\t         *     bufferedBlockAlgorithm.reset();\n\t         */\n\t        reset: function () {\n\t            // Initial values\n\t            this._data = new WordArray.init();\n\t            this._nDataBytes = 0;\n\t        },\n\n\t        /**\n\t         * Adds new data to this block algorithm's buffer.\n\t         *\n\t         * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8.\n\t         *\n\t         * @example\n\t         *\n\t         *     bufferedBlockAlgorithm._append('data');\n\t         *     bufferedBlockAlgorithm._append(wordArray);\n\t         */\n\t        _append: function (data) {\n\t            // Convert string to WordArray, else assume WordArray already\n\t            if (typeof data == 'string') {\n\t                data = Utf8.parse(data);\n\t            }\n\n\t            // Append\n\t            this._data.concat(data);\n\t            this._nDataBytes += data.sigBytes;\n\t        },\n\n\t        /**\n\t         * Processes available data blocks.\n\t         *\n\t         * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype.\n\t         *\n\t         * @param {boolean} doFlush Whether all blocks and partial blocks should be processed.\n\t         *\n\t         * @return {WordArray} The processed data.\n\t         *\n\t         * @example\n\t         *\n\t         *     var processedData = bufferedBlockAlgorithm._process();\n\t         *     var processedData = bufferedBlockAlgorithm._process(!!'flush');\n\t         */\n\t        _process: function (doFlush) {\n\t            var processedWords;\n\n\t            // Shortcuts\n\t            var data = this._data;\n\t            var dataWords = data.words;\n\t            var dataSigBytes = data.sigBytes;\n\t            var blockSize = this.blockSize;\n\t            var blockSizeBytes = blockSize * 4;\n\n\t            // Count blocks ready\n\t            var nBlocksReady = dataSigBytes / blockSizeBytes;\n\t            if (doFlush) {\n\t                // Round up to include partial blocks\n\t                nBlocksReady = Math.ceil(nBlocksReady);\n\t            } else {\n\t                // Round down to include only full blocks,\n\t                // less the number of blocks that must remain in the buffer\n\t                nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);\n\t            }\n\n\t            // Count words ready\n\t            var nWordsReady = nBlocksReady * blockSize;\n\n\t            // Count bytes ready\n\t            var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes);\n\n\t            // Process blocks\n\t            if (nWordsReady) {\n\t                for (var offset = 0; offset < nWordsReady; offset += blockSize) {\n\t                    // Perform concrete-algorithm logic\n\t                    this._doProcessBlock(dataWords, offset);\n\t                }\n\n\t                // Remove processed words\n\t                processedWords = dataWords.splice(0, nWordsReady);\n\t                data.sigBytes -= nBytesReady;\n\t            }\n\n\t            // Return processed words\n\t            return new WordArray.init(processedWords, nBytesReady);\n\t        },\n\n\t        /**\n\t         * Creates a copy of this object.\n\t         *\n\t         * @return {Object} The clone.\n\t         *\n\t         * @example\n\t         *\n\t         *     var clone = bufferedBlockAlgorithm.clone();\n\t         */\n\t        clone: function () {\n\t            var clone = Base.clone.call(this);\n\t            clone._data = this._data.clone();\n\n\t            return clone;\n\t        },\n\n\t        _minBufferSize: 0\n\t    });\n\n\t    /**\n\t     * Abstract hasher template.\n\t     *\n\t     * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits)\n\t     */\n\t    var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({\n\t        /**\n\t         * Configuration options.\n\t         */\n\t        cfg: Base.extend(),\n\n\t        /**\n\t         * Initializes a newly created hasher.\n\t         *\n\t         * @param {Object} cfg (Optional) The configuration options to use for this hash computation.\n\t         *\n\t         * @example\n\t         *\n\t         *     var hasher = CryptoJS.algo.SHA256.create();\n\t         */\n\t        init: function (cfg) {\n\t            // Apply config defaults\n\t            this.cfg = this.cfg.extend(cfg);\n\n\t            // Set initial values\n\t            this.reset();\n\t        },\n\n\t        /**\n\t         * Resets this hasher to its initial state.\n\t         *\n\t         * @example\n\t         *\n\t         *     hasher.reset();\n\t         */\n\t        reset: function () {\n\t            // Reset data buffer\n\t            BufferedBlockAlgorithm.reset.call(this);\n\n\t            // Perform concrete-hasher logic\n\t            this._doReset();\n\t        },\n\n\t        /**\n\t         * Updates this hasher with a message.\n\t         *\n\t         * @param {WordArray|string} messageUpdate The message to append.\n\t         *\n\t         * @return {Hasher} This hasher.\n\t         *\n\t         * @example\n\t         *\n\t         *     hasher.update('message');\n\t         *     hasher.update(wordArray);\n\t         */\n\t        update: function (messageUpdate) {\n\t            // Append\n\t            this._append(messageUpdate);\n\n\t            // Update the hash\n\t            this._process();\n\n\t            // Chainable\n\t            return this;\n\t        },\n\n\t        /**\n\t         * Finalizes the hash computation.\n\t         * Note that the finalize operation is effectively a destructive, read-once operation.\n\t         *\n\t         * @param {WordArray|string} messageUpdate (Optional) A final message update.\n\t         *\n\t         * @return {WordArray} The hash.\n\t         *\n\t         * @example\n\t         *\n\t         *     var hash = hasher.finalize();\n\t         *     var hash = hasher.finalize('message');\n\t         *     var hash = hasher.finalize(wordArray);\n\t         */\n\t        finalize: function (messageUpdate) {\n\t            // Final message update\n\t            if (messageUpdate) {\n\t                this._append(messageUpdate);\n\t            }\n\n\t            // Perform concrete-hasher logic\n\t            var hash = this._doFinalize();\n\n\t            return hash;\n\t        },\n\n\t        blockSize: 512/32,\n\n\t        /**\n\t         * Creates a shortcut function to a hasher's object interface.\n\t         *\n\t         * @param {Hasher} hasher The hasher to create a helper for.\n\t         *\n\t         * @return {Function} The shortcut function.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256);\n\t         */\n\t        _createHelper: function (hasher) {\n\t            return function (message, cfg) {\n\t                return new hasher.init(cfg).finalize(message);\n\t            };\n\t        },\n\n\t        /**\n\t         * Creates a shortcut function to the HMAC's object interface.\n\t         *\n\t         * @param {Hasher} hasher The hasher to use in this HMAC helper.\n\t         *\n\t         * @return {Function} The shortcut function.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256);\n\t         */\n\t        _createHmacHelper: function (hasher) {\n\t            return function (message, key) {\n\t                return new C_algo.HMAC.init(hasher, key).finalize(message);\n\t            };\n\t        }\n\t    });\n\n\t    /**\n\t     * Algorithm namespace.\n\t     */\n\t    var C_algo = C.algo = {};\n\n\t    return C;\n\t}(Math));\n\n\n\t(function () {\n\t    // Shortcuts\n\t    var C = CryptoJS;\n\t    var C_lib = C.lib;\n\t    var WordArray = C_lib.WordArray;\n\t    var C_enc = C.enc;\n\n\t    /**\n\t     * Base64 encoding strategy.\n\t     */\n\t    var Base64 = C_enc.Base64 = {\n\t        /**\n\t         * Converts a word array to a Base64 string.\n\t         *\n\t         * @param {WordArray} wordArray The word array.\n\t         *\n\t         * @return {string} The Base64 string.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var base64String = CryptoJS.enc.Base64.stringify(wordArray);\n\t         */\n\t        stringify: function (wordArray) {\n\t            // Shortcuts\n\t            var words = wordArray.words;\n\t            var sigBytes = wordArray.sigBytes;\n\t            var map = this._map;\n\n\t            // Clamp excess bits\n\t            wordArray.clamp();\n\n\t            // Convert\n\t            var base64Chars = [];\n\t            for (var i = 0; i < sigBytes; i += 3) {\n\t                var byte1 = (words[i >>> 2]       >>> (24 - (i % 4) * 8))       & 0xff;\n\t                var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff;\n\t                var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff;\n\n\t                var triplet = (byte1 << 16) | (byte2 << 8) | byte3;\n\n\t                for (var j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j++) {\n\t                    base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f));\n\t                }\n\t            }\n\n\t            // Add padding\n\t            var paddingChar = map.charAt(64);\n\t            if (paddingChar) {\n\t                while (base64Chars.length % 4) {\n\t                    base64Chars.push(paddingChar);\n\t                }\n\t            }\n\n\t            return base64Chars.join('');\n\t        },\n\n\t        /**\n\t         * Converts a Base64 string to a word array.\n\t         *\n\t         * @param {string} base64Str The Base64 string.\n\t         *\n\t         * @return {WordArray} The word array.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var wordArray = CryptoJS.enc.Base64.parse(base64String);\n\t         */\n\t        parse: function (base64Str) {\n\t            // Shortcuts\n\t            var base64StrLength = base64Str.length;\n\t            var map = this._map;\n\t            var reverseMap = this._reverseMap;\n\n\t            if (!reverseMap) {\n\t                    reverseMap = this._reverseMap = [];\n\t                    for (var j = 0; j < map.length; j++) {\n\t                        reverseMap[map.charCodeAt(j)] = j;\n\t                    }\n\t            }\n\n\t            // Ignore padding\n\t            var paddingChar = map.charAt(64);\n\t            if (paddingChar) {\n\t                var paddingIndex = base64Str.indexOf(paddingChar);\n\t                if (paddingIndex !== -1) {\n\t                    base64StrLength = paddingIndex;\n\t                }\n\t            }\n\n\t            // Convert\n\t            return parseLoop(base64Str, base64StrLength, reverseMap);\n\n\t        },\n\n\t        _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='\n\t    };\n\n\t    function parseLoop(base64Str, base64StrLength, reverseMap) {\n\t      var words = [];\n\t      var nBytes = 0;\n\t      for (var i = 0; i < base64StrLength; i++) {\n\t          if (i % 4) {\n\t              var bits1 = reverseMap[base64Str.charCodeAt(i - 1)] << ((i % 4) * 2);\n\t              var bits2 = reverseMap[base64Str.charCodeAt(i)] >>> (6 - (i % 4) * 2);\n\t              var bitsCombined = bits1 | bits2;\n\t              words[nBytes >>> 2] |= bitsCombined << (24 - (nBytes % 4) * 8);\n\t              nBytes++;\n\t          }\n\t      }\n\t      return WordArray.create(words, nBytes);\n\t    }\n\t}());\n\n\n\t(function (Math) {\n\t    // Shortcuts\n\t    var C = CryptoJS;\n\t    var C_lib = C.lib;\n\t    var WordArray = C_lib.WordArray;\n\t    var Hasher = C_lib.Hasher;\n\t    var C_algo = C.algo;\n\n\t    // Constants table\n\t    var T = [];\n\n\t    // Compute constants\n\t    (function () {\n\t        for (var i = 0; i < 64; i++) {\n\t            T[i] = (Math.abs(Math.sin(i + 1)) * 0x100000000) | 0;\n\t        }\n\t    }());\n\n\t    /**\n\t     * MD5 hash algorithm.\n\t     */\n\t    var MD5 = C_algo.MD5 = Hasher.extend({\n\t        _doReset: function () {\n\t            this._hash = new WordArray.init([\n\t                0x67452301, 0xefcdab89,\n\t                0x98badcfe, 0x10325476\n\t            ]);\n\t        },\n\n\t        _doProcessBlock: function (M, offset) {\n\t            // Swap endian\n\t            for (var i = 0; i < 16; i++) {\n\t                // Shortcuts\n\t                var offset_i = offset + i;\n\t                var M_offset_i = M[offset_i];\n\n\t                M[offset_i] = (\n\t                    (((M_offset_i << 8)  | (M_offset_i >>> 24)) & 0x00ff00ff) |\n\t                    (((M_offset_i << 24) | (M_offset_i >>> 8))  & 0xff00ff00)\n\t                );\n\t            }\n\n\t            // Shortcuts\n\t            var H = this._hash.words;\n\n\t            var M_offset_0  = M[offset + 0];\n\t            var M_offset_1  = M[offset + 1];\n\t            var M_offset_2  = M[offset + 2];\n\t            var M_offset_3  = M[offset + 3];\n\t            var M_offset_4  = M[offset + 4];\n\t            var M_offset_5  = M[offset + 5];\n\t            var M_offset_6  = M[offset + 6];\n\t            var M_offset_7  = M[offset + 7];\n\t            var M_offset_8  = M[offset + 8];\n\t            var M_offset_9  = M[offset + 9];\n\t            var M_offset_10 = M[offset + 10];\n\t            var M_offset_11 = M[offset + 11];\n\t            var M_offset_12 = M[offset + 12];\n\t            var M_offset_13 = M[offset + 13];\n\t            var M_offset_14 = M[offset + 14];\n\t            var M_offset_15 = M[offset + 15];\n\n\t            // Working varialbes\n\t            var a = H[0];\n\t            var b = H[1];\n\t            var c = H[2];\n\t            var d = H[3];\n\n\t            // Computation\n\t            a = FF(a, b, c, d, M_offset_0,  7,  T[0]);\n\t            d = FF(d, a, b, c, M_offset_1,  12, T[1]);\n\t            c = FF(c, d, a, b, M_offset_2,  17, T[2]);\n\t            b = FF(b, c, d, a, M_offset_3,  22, T[3]);\n\t            a = FF(a, b, c, d, M_offset_4,  7,  T[4]);\n\t            d = FF(d, a, b, c, M_offset_5,  12, T[5]);\n\t            c = FF(c, d, a, b, M_offset_6,  17, T[6]);\n\t            b = FF(b, c, d, a, M_offset_7,  22, T[7]);\n\t            a = FF(a, b, c, d, M_offset_8,  7,  T[8]);\n\t            d = FF(d, a, b, c, M_offset_9,  12, T[9]);\n\t            c = FF(c, d, a, b, M_offset_10, 17, T[10]);\n\t            b = FF(b, c, d, a, M_offset_11, 22, T[11]);\n\t            a = FF(a, b, c, d, M_offset_12, 7,  T[12]);\n\t            d = FF(d, a, b, c, M_offset_13, 12, T[13]);\n\t            c = FF(c, d, a, b, M_offset_14, 17, T[14]);\n\t            b = FF(b, c, d, a, M_offset_15, 22, T[15]);\n\n\t            a = GG(a, b, c, d, M_offset_1,  5,  T[16]);\n\t            d = GG(d, a, b, c, M_offset_6,  9,  T[17]);\n\t            c = GG(c, d, a, b, M_offset_11, 14, T[18]);\n\t            b = GG(b, c, d, a, M_offset_0,  20, T[19]);\n\t            a = GG(a, b, c, d, M_offset_5,  5,  T[20]);\n\t            d = GG(d, a, b, c, M_offset_10, 9,  T[21]);\n\t            c = GG(c, d, a, b, M_offset_15, 14, T[22]);\n\t            b = GG(b, c, d, a, M_offset_4,  20, T[23]);\n\t            a = GG(a, b, c, d, M_offset_9,  5,  T[24]);\n\t            d = GG(d, a, b, c, M_offset_14, 9,  T[25]);\n\t            c = GG(c, d, a, b, M_offset_3,  14, T[26]);\n\t            b = GG(b, c, d, a, M_offset_8,  20, T[27]);\n\t            a = GG(a, b, c, d, M_offset_13, 5,  T[28]);\n\t            d = GG(d, a, b, c, M_offset_2,  9,  T[29]);\n\t            c = GG(c, d, a, b, M_offset_7,  14, T[30]);\n\t            b = GG(b, c, d, a, M_offset_12, 20, T[31]);\n\n\t            a = HH(a, b, c, d, M_offset_5,  4,  T[32]);\n\t            d = HH(d, a, b, c, M_offset_8,  11, T[33]);\n\t            c = HH(c, d, a, b, M_offset_11, 16, T[34]);\n\t            b = HH(b, c, d, a, M_offset_14, 23, T[35]);\n\t            a = HH(a, b, c, d, M_offset_1,  4,  T[36]);\n\t            d = HH(d, a, b, c, M_offset_4,  11, T[37]);\n\t            c = HH(c, d, a, b, M_offset_7,  16, T[38]);\n\t            b = HH(b, c, d, a, M_offset_10, 23, T[39]);\n\t            a = HH(a, b, c, d, M_offset_13, 4,  T[40]);\n\t            d = HH(d, a, b, c, M_offset_0,  11, T[41]);\n\t            c = HH(c, d, a, b, M_offset_3,  16, T[42]);\n\t            b = HH(b, c, d, a, M_offset_6,  23, T[43]);\n\t            a = HH(a, b, c, d, M_offset_9,  4,  T[44]);\n\t            d = HH(d, a, b, c, M_offset_12, 11, T[45]);\n\t            c = HH(c, d, a, b, M_offset_15, 16, T[46]);\n\t            b = HH(b, c, d, a, M_offset_2,  23, T[47]);\n\n\t            a = II(a, b, c, d, M_offset_0,  6,  T[48]);\n\t            d = II(d, a, b, c, M_offset_7,  10, T[49]);\n\t            c = II(c, d, a, b, M_offset_14, 15, T[50]);\n\t            b = II(b, c, d, a, M_offset_5,  21, T[51]);\n\t            a = II(a, b, c, d, M_offset_12, 6,  T[52]);\n\t            d = II(d, a, b, c, M_offset_3,  10, T[53]);\n\t            c = II(c, d, a, b, M_offset_10, 15, T[54]);\n\t            b = II(b, c, d, a, M_offset_1,  21, T[55]);\n\t            a = II(a, b, c, d, M_offset_8,  6,  T[56]);\n\t            d = II(d, a, b, c, M_offset_15, 10, T[57]);\n\t            c = II(c, d, a, b, M_offset_6,  15, T[58]);\n\t            b = II(b, c, d, a, M_offset_13, 21, T[59]);\n\t            a = II(a, b, c, d, M_offset_4,  6,  T[60]);\n\t            d = II(d, a, b, c, M_offset_11, 10, T[61]);\n\t            c = II(c, d, a, b, M_offset_2,  15, T[62]);\n\t            b = II(b, c, d, a, M_offset_9,  21, T[63]);\n\n\t            // Intermediate hash value\n\t            H[0] = (H[0] + a) | 0;\n\t            H[1] = (H[1] + b) | 0;\n\t            H[2] = (H[2] + c) | 0;\n\t            H[3] = (H[3] + d) | 0;\n\t        },\n\n\t        _doFinalize: function () {\n\t            // Shortcuts\n\t            var data = this._data;\n\t            var dataWords = data.words;\n\n\t            var nBitsTotal = this._nDataBytes * 8;\n\t            var nBitsLeft = data.sigBytes * 8;\n\n\t            // Add padding\n\t            dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);\n\n\t            var nBitsTotalH = Math.floor(nBitsTotal / 0x100000000);\n\t            var nBitsTotalL = nBitsTotal;\n\t            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = (\n\t                (((nBitsTotalH << 8)  | (nBitsTotalH >>> 24)) & 0x00ff00ff) |\n\t                (((nBitsTotalH << 24) | (nBitsTotalH >>> 8))  & 0xff00ff00)\n\t            );\n\t            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = (\n\t                (((nBitsTotalL << 8)  | (nBitsTotalL >>> 24)) & 0x00ff00ff) |\n\t                (((nBitsTotalL << 24) | (nBitsTotalL >>> 8))  & 0xff00ff00)\n\t            );\n\n\t            data.sigBytes = (dataWords.length + 1) * 4;\n\n\t            // Hash final blocks\n\t            this._process();\n\n\t            // Shortcuts\n\t            var hash = this._hash;\n\t            var H = hash.words;\n\n\t            // Swap endian\n\t            for (var i = 0; i < 4; i++) {\n\t                // Shortcut\n\t                var H_i = H[i];\n\n\t                H[i] = (((H_i << 8)  | (H_i >>> 24)) & 0x00ff00ff) |\n\t                       (((H_i << 24) | (H_i >>> 8))  & 0xff00ff00);\n\t            }\n\n\t            // Return final computed hash\n\t            return hash;\n\t        },\n\n\t        clone: function () {\n\t            var clone = Hasher.clone.call(this);\n\t            clone._hash = this._hash.clone();\n\n\t            return clone;\n\t        }\n\t    });\n\n\t    function FF(a, b, c, d, x, s, t) {\n\t        var n = a + ((b & c) | (~b & d)) + x + t;\n\t        return ((n << s) | (n >>> (32 - s))) + b;\n\t    }\n\n\t    function GG(a, b, c, d, x, s, t) {\n\t        var n = a + ((b & d) | (c & ~d)) + x + t;\n\t        return ((n << s) | (n >>> (32 - s))) + b;\n\t    }\n\n\t    function HH(a, b, c, d, x, s, t) {\n\t        var n = a + (b ^ c ^ d) + x + t;\n\t        return ((n << s) | (n >>> (32 - s))) + b;\n\t    }\n\n\t    function II(a, b, c, d, x, s, t) {\n\t        var n = a + (c ^ (b | ~d)) + x + t;\n\t        return ((n << s) | (n >>> (32 - s))) + b;\n\t    }\n\n\t    /**\n\t     * Shortcut function to the hasher's object interface.\n\t     *\n\t     * @param {WordArray|string} message The message to hash.\n\t     *\n\t     * @return {WordArray} The hash.\n\t     *\n\t     * @static\n\t     *\n\t     * @example\n\t     *\n\t     *     var hash = CryptoJS.MD5('message');\n\t     *     var hash = CryptoJS.MD5(wordArray);\n\t     */\n\t    C.MD5 = Hasher._createHelper(MD5);\n\n\t    /**\n\t     * Shortcut function to the HMAC's object interface.\n\t     *\n\t     * @param {WordArray|string} message The message to hash.\n\t     * @param {WordArray|string} key The secret key.\n\t     *\n\t     * @return {WordArray} The HMAC.\n\t     *\n\t     * @static\n\t     *\n\t     * @example\n\t     *\n\t     *     var hmac = CryptoJS.HmacMD5(message, key);\n\t     */\n\t    C.HmacMD5 = Hasher._createHmacHelper(MD5);\n\t}(Math));\n\n\n\t(function () {\n\t    // Shortcuts\n\t    var C = CryptoJS;\n\t    var C_lib = C.lib;\n\t    var WordArray = C_lib.WordArray;\n\t    var Hasher = C_lib.Hasher;\n\t    var C_algo = C.algo;\n\n\t    // Reusable object\n\t    var W = [];\n\n\t    /**\n\t     * SHA-1 hash algorithm.\n\t     */\n\t    var SHA1 = C_algo.SHA1 = Hasher.extend({\n\t        _doReset: function () {\n\t            this._hash = new WordArray.init([\n\t                0x67452301, 0xefcdab89,\n\t                0x98badcfe, 0x10325476,\n\t                0xc3d2e1f0\n\t            ]);\n\t        },\n\n\t        _doProcessBlock: function (M, offset) {\n\t            // Shortcut\n\t            var H = this._hash.words;\n\n\t            // Working variables\n\t            var a = H[0];\n\t            var b = H[1];\n\t            var c = H[2];\n\t            var d = H[3];\n\t            var e = H[4];\n\n\t            // Computation\n\t            for (var i = 0; i < 80; i++) {\n\t                if (i < 16) {\n\t                    W[i] = M[offset + i] | 0;\n\t                } else {\n\t                    var n = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16];\n\t                    W[i] = (n << 1) | (n >>> 31);\n\t                }\n\n\t                var t = ((a << 5) | (a >>> 27)) + e + W[i];\n\t                if (i < 20) {\n\t                    t += ((b & c) | (~b & d)) + 0x5a827999;\n\t                } else if (i < 40) {\n\t                    t += (b ^ c ^ d) + 0x6ed9eba1;\n\t                } else if (i < 60) {\n\t                    t += ((b & c) | (b & d) | (c & d)) - 0x70e44324;\n\t                } else /* if (i < 80) */ {\n\t                    t += (b ^ c ^ d) - 0x359d3e2a;\n\t                }\n\n\t                e = d;\n\t                d = c;\n\t                c = (b << 30) | (b >>> 2);\n\t                b = a;\n\t                a = t;\n\t            }\n\n\t            // Intermediate hash value\n\t            H[0] = (H[0] + a) | 0;\n\t            H[1] = (H[1] + b) | 0;\n\t            H[2] = (H[2] + c) | 0;\n\t            H[3] = (H[3] + d) | 0;\n\t            H[4] = (H[4] + e) | 0;\n\t        },\n\n\t        _doFinalize: function () {\n\t            // Shortcuts\n\t            var data = this._data;\n\t            var dataWords = data.words;\n\n\t            var nBitsTotal = this._nDataBytes * 8;\n\t            var nBitsLeft = data.sigBytes * 8;\n\n\t            // Add padding\n\t            dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);\n\t            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000);\n\t            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal;\n\t            data.sigBytes = dataWords.length * 4;\n\n\t            // Hash final blocks\n\t            this._process();\n\n\t            // Return final computed hash\n\t            return this._hash;\n\t        },\n\n\t        clone: function () {\n\t            var clone = Hasher.clone.call(this);\n\t            clone._hash = this._hash.clone();\n\n\t            return clone;\n\t        }\n\t    });\n\n\t    /**\n\t     * Shortcut function to the hasher's object interface.\n\t     *\n\t     * @param {WordArray|string} message The message to hash.\n\t     *\n\t     * @return {WordArray} The hash.\n\t     *\n\t     * @static\n\t     *\n\t     * @example\n\t     *\n\t     *     var hash = CryptoJS.SHA1('message');\n\t     *     var hash = CryptoJS.SHA1(wordArray);\n\t     */\n\t    C.SHA1 = Hasher._createHelper(SHA1);\n\n\t    /**\n\t     * Shortcut function to the HMAC's object interface.\n\t     *\n\t     * @param {WordArray|string} message The message to hash.\n\t     * @param {WordArray|string} key The secret key.\n\t     *\n\t     * @return {WordArray} The HMAC.\n\t     *\n\t     * @static\n\t     *\n\t     * @example\n\t     *\n\t     *     var hmac = CryptoJS.HmacSHA1(message, key);\n\t     */\n\t    C.HmacSHA1 = Hasher._createHmacHelper(SHA1);\n\t}());\n\n\n\t(function (Math) {\n\t    // Shortcuts\n\t    var C = CryptoJS;\n\t    var C_lib = C.lib;\n\t    var WordArray = C_lib.WordArray;\n\t    var Hasher = C_lib.Hasher;\n\t    var C_algo = C.algo;\n\n\t    // Initialization and round constants tables\n\t    var H = [];\n\t    var K = [];\n\n\t    // Compute constants\n\t    (function () {\n\t        function isPrime(n) {\n\t            var sqrtN = Math.sqrt(n);\n\t            for (var factor = 2; factor <= sqrtN; factor++) {\n\t                if (!(n % factor)) {\n\t                    return false;\n\t                }\n\t            }\n\n\t            return true;\n\t        }\n\n\t        function getFractionalBits(n) {\n\t            return ((n - (n | 0)) * 0x100000000) | 0;\n\t        }\n\n\t        var n = 2;\n\t        var nPrime = 0;\n\t        while (nPrime < 64) {\n\t            if (isPrime(n)) {\n\t                if (nPrime < 8) {\n\t                    H[nPrime] = getFractionalBits(Math.pow(n, 1 / 2));\n\t                }\n\t                K[nPrime] = getFractionalBits(Math.pow(n, 1 / 3));\n\n\t                nPrime++;\n\t            }\n\n\t            n++;\n\t        }\n\t    }());\n\n\t    // Reusable object\n\t    var W = [];\n\n\t    /**\n\t     * SHA-256 hash algorithm.\n\t     */\n\t    var SHA256 = C_algo.SHA256 = Hasher.extend({\n\t        _doReset: function () {\n\t            this._hash = new WordArray.init(H.slice(0));\n\t        },\n\n\t        _doProcessBlock: function (M, offset) {\n\t            // Shortcut\n\t            var H = this._hash.words;\n\n\t            // Working variables\n\t            var a = H[0];\n\t            var b = H[1];\n\t            var c = H[2];\n\t            var d = H[3];\n\t            var e = H[4];\n\t            var f = H[5];\n\t            var g = H[6];\n\t            var h = H[7];\n\n\t            // Computation\n\t            for (var i = 0; i < 64; i++) {\n\t                if (i < 16) {\n\t                    W[i] = M[offset + i] | 0;\n\t                } else {\n\t                    var gamma0x = W[i - 15];\n\t                    var gamma0  = ((gamma0x << 25) | (gamma0x >>> 7))  ^\n\t                                  ((gamma0x << 14) | (gamma0x >>> 18)) ^\n\t                                   (gamma0x >>> 3);\n\n\t                    var gamma1x = W[i - 2];\n\t                    var gamma1  = ((gamma1x << 15) | (gamma1x >>> 17)) ^\n\t                                  ((gamma1x << 13) | (gamma1x >>> 19)) ^\n\t                                   (gamma1x >>> 10);\n\n\t                    W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16];\n\t                }\n\n\t                var ch  = (e & f) ^ (~e & g);\n\t                var maj = (a & b) ^ (a & c) ^ (b & c);\n\n\t                var sigma0 = ((a << 30) | (a >>> 2)) ^ ((a << 19) | (a >>> 13)) ^ ((a << 10) | (a >>> 22));\n\t                var sigma1 = ((e << 26) | (e >>> 6)) ^ ((e << 21) | (e >>> 11)) ^ ((e << 7)  | (e >>> 25));\n\n\t                var t1 = h + sigma1 + ch + K[i] + W[i];\n\t                var t2 = sigma0 + maj;\n\n\t                h = g;\n\t                g = f;\n\t                f = e;\n\t                e = (d + t1) | 0;\n\t                d = c;\n\t                c = b;\n\t                b = a;\n\t                a = (t1 + t2) | 0;\n\t            }\n\n\t            // Intermediate hash value\n\t            H[0] = (H[0] + a) | 0;\n\t            H[1] = (H[1] + b) | 0;\n\t            H[2] = (H[2] + c) | 0;\n\t            H[3] = (H[3] + d) | 0;\n\t            H[4] = (H[4] + e) | 0;\n\t            H[5] = (H[5] + f) | 0;\n\t            H[6] = (H[6] + g) | 0;\n\t            H[7] = (H[7] + h) | 0;\n\t        },\n\n\t        _doFinalize: function () {\n\t            // Shortcuts\n\t            var data = this._data;\n\t            var dataWords = data.words;\n\n\t            var nBitsTotal = this._nDataBytes * 8;\n\t            var nBitsLeft = data.sigBytes * 8;\n\n\t            // Add padding\n\t            dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);\n\t            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000);\n\t            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal;\n\t            data.sigBytes = dataWords.length * 4;\n\n\t            // Hash final blocks\n\t            this._process();\n\n\t            // Return final computed hash\n\t            return this._hash;\n\t        },\n\n\t        clone: function () {\n\t            var clone = Hasher.clone.call(this);\n\t            clone._hash = this._hash.clone();\n\n\t            return clone;\n\t        }\n\t    });\n\n\t    /**\n\t     * Shortcut function to the hasher's object interface.\n\t     *\n\t     * @param {WordArray|string} message The message to hash.\n\t     *\n\t     * @return {WordArray} The hash.\n\t     *\n\t     * @static\n\t     *\n\t     * @example\n\t     *\n\t     *     var hash = CryptoJS.SHA256('message');\n\t     *     var hash = CryptoJS.SHA256(wordArray);\n\t     */\n\t    C.SHA256 = Hasher._createHelper(SHA256);\n\n\t    /**\n\t     * Shortcut function to the HMAC's object interface.\n\t     *\n\t     * @param {WordArray|string} message The message to hash.\n\t     * @param {WordArray|string} key The secret key.\n\t     *\n\t     * @return {WordArray} The HMAC.\n\t     *\n\t     * @static\n\t     *\n\t     * @example\n\t     *\n\t     *     var hmac = CryptoJS.HmacSHA256(message, key);\n\t     */\n\t    C.HmacSHA256 = Hasher._createHmacHelper(SHA256);\n\t}(Math));\n\n\n\t(function () {\n\t    // Shortcuts\n\t    var C = CryptoJS;\n\t    var C_lib = C.lib;\n\t    var WordArray = C_lib.WordArray;\n\t    var C_enc = C.enc;\n\n\t    /**\n\t     * UTF-16 BE encoding strategy.\n\t     */\n\t    var Utf16BE = C_enc.Utf16 = C_enc.Utf16BE = {\n\t        /**\n\t         * Converts a word array to a UTF-16 BE string.\n\t         *\n\t         * @param {WordArray} wordArray The word array.\n\t         *\n\t         * @return {string} The UTF-16 BE string.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var utf16String = CryptoJS.enc.Utf16.stringify(wordArray);\n\t         */\n\t        stringify: function (wordArray) {\n\t            // Shortcuts\n\t            var words = wordArray.words;\n\t            var sigBytes = wordArray.sigBytes;\n\n\t            // Convert\n\t            var utf16Chars = [];\n\t            for (var i = 0; i < sigBytes; i += 2) {\n\t                var codePoint = (words[i >>> 2] >>> (16 - (i % 4) * 8)) & 0xffff;\n\t                utf16Chars.push(String.fromCharCode(codePoint));\n\t            }\n\n\t            return utf16Chars.join('');\n\t        },\n\n\t        /**\n\t         * Converts a UTF-16 BE string to a word array.\n\t         *\n\t         * @param {string} utf16Str The UTF-16 BE string.\n\t         *\n\t         * @return {WordArray} The word array.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var wordArray = CryptoJS.enc.Utf16.parse(utf16String);\n\t         */\n\t        parse: function (utf16Str) {\n\t            // Shortcut\n\t            var utf16StrLength = utf16Str.length;\n\n\t            // Convert\n\t            var words = [];\n\t            for (var i = 0; i < utf16StrLength; i++) {\n\t                words[i >>> 1] |= utf16Str.charCodeAt(i) << (16 - (i % 2) * 16);\n\t            }\n\n\t            return WordArray.create(words, utf16StrLength * 2);\n\t        }\n\t    };\n\n\t    /**\n\t     * UTF-16 LE encoding strategy.\n\t     */\n\t    C_enc.Utf16LE = {\n\t        /**\n\t         * Converts a word array to a UTF-16 LE string.\n\t         *\n\t         * @param {WordArray} wordArray The word array.\n\t         *\n\t         * @return {string} The UTF-16 LE string.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var utf16Str = CryptoJS.enc.Utf16LE.stringify(wordArray);\n\t         */\n\t        stringify: function (wordArray) {\n\t            // Shortcuts\n\t            var words = wordArray.words;\n\t            var sigBytes = wordArray.sigBytes;\n\n\t            // Convert\n\t            var utf16Chars = [];\n\t            for (var i = 0; i < sigBytes; i += 2) {\n\t                var codePoint = swapEndian((words[i >>> 2] >>> (16 - (i % 4) * 8)) & 0xffff);\n\t                utf16Chars.push(String.fromCharCode(codePoint));\n\t            }\n\n\t            return utf16Chars.join('');\n\t        },\n\n\t        /**\n\t         * Converts a UTF-16 LE string to a word array.\n\t         *\n\t         * @param {string} utf16Str The UTF-16 LE string.\n\t         *\n\t         * @return {WordArray} The word array.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var wordArray = CryptoJS.enc.Utf16LE.parse(utf16Str);\n\t         */\n\t        parse: function (utf16Str) {\n\t            // Shortcut\n\t            var utf16StrLength = utf16Str.length;\n\n\t            // Convert\n\t            var words = [];\n\t            for (var i = 0; i < utf16StrLength; i++) {\n\t                words[i >>> 1] |= swapEndian(utf16Str.charCodeAt(i) << (16 - (i % 2) * 16));\n\t            }\n\n\t            return WordArray.create(words, utf16StrLength * 2);\n\t        }\n\t    };\n\n\t    function swapEndian(word) {\n\t        return ((word << 8) & 0xff00ff00) | ((word >>> 8) & 0x00ff00ff);\n\t    }\n\t}());\n\n\n\t(function () {\n\t    // Check if typed arrays are supported\n\t    if (typeof ArrayBuffer != 'function') {\n\t        return;\n\t    }\n\n\t    // Shortcuts\n\t    var C = CryptoJS;\n\t    var C_lib = C.lib;\n\t    var WordArray = C_lib.WordArray;\n\n\t    // Reference original init\n\t    var superInit = WordArray.init;\n\n\t    // Augment WordArray.init to handle typed arrays\n\t    var subInit = WordArray.init = function (typedArray) {\n\t        // Convert buffers to uint8\n\t        if (typedArray instanceof ArrayBuffer) {\n\t            typedArray = new Uint8Array(typedArray);\n\t        }\n\n\t        // Convert other array views to uint8\n\t        if (\n\t            typedArray instanceof Int8Array ||\n\t            (typeof Uint8ClampedArray !== \"undefined\" && typedArray instanceof Uint8ClampedArray) ||\n\t            typedArray instanceof Int16Array ||\n\t            typedArray instanceof Uint16Array ||\n\t            typedArray instanceof Int32Array ||\n\t            typedArray instanceof Uint32Array ||\n\t            typedArray instanceof Float32Array ||\n\t            typedArray instanceof Float64Array\n\t        ) {\n\t            typedArray = new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength);\n\t        }\n\n\t        // Handle Uint8Array\n\t        if (typedArray instanceof Uint8Array) {\n\t            // Shortcut\n\t            var typedArrayByteLength = typedArray.byteLength;\n\n\t            // Extract bytes\n\t            var words = [];\n\t            for (var i = 0; i < typedArrayByteLength; i++) {\n\t                words[i >>> 2] |= typedArray[i] << (24 - (i % 4) * 8);\n\t            }\n\n\t            // Initialize this word array\n\t            superInit.call(this, words, typedArrayByteLength);\n\t        } else {\n\t            // Else call normal init\n\t            superInit.apply(this, arguments);\n\t        }\n\t    };\n\n\t    subInit.prototype = WordArray;\n\t}());\n\n\n\t/** @preserve\n\t(c) 2012 by Cédric Mesnil. All rights reserved.\n\n\tRedistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n\n\t    - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n\t    - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\n\n\tTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\t*/\n\n\t(function (Math) {\n\t    // Shortcuts\n\t    var C = CryptoJS;\n\t    var C_lib = C.lib;\n\t    var WordArray = C_lib.WordArray;\n\t    var Hasher = C_lib.Hasher;\n\t    var C_algo = C.algo;\n\n\t    // Constants table\n\t    var _zl = WordArray.create([\n\t        0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,\n\t        7,  4, 13,  1, 10,  6, 15,  3, 12,  0,  9,  5,  2, 14, 11,  8,\n\t        3, 10, 14,  4,  9, 15,  8,  1,  2,  7,  0,  6, 13, 11,  5, 12,\n\t        1,  9, 11, 10,  0,  8, 12,  4, 13,  3,  7, 15, 14,  5,  6,  2,\n\t        4,  0,  5,  9,  7, 12,  2, 10, 14,  1,  3,  8, 11,  6, 15, 13]);\n\t    var _zr = WordArray.create([\n\t        5, 14,  7,  0,  9,  2, 11,  4, 13,  6, 15,  8,  1, 10,  3, 12,\n\t        6, 11,  3,  7,  0, 13,  5, 10, 14, 15,  8, 12,  4,  9,  1,  2,\n\t        15,  5,  1,  3,  7, 14,  6,  9, 11,  8, 12,  2, 10,  0,  4, 13,\n\t        8,  6,  4,  1,  3, 11, 15,  0,  5, 12,  2, 13,  9,  7, 10, 14,\n\t        12, 15, 10,  4,  1,  5,  8,  7,  6,  2, 13, 14,  0,  3,  9, 11]);\n\t    var _sl = WordArray.create([\n\t         11, 14, 15, 12,  5,  8,  7,  9, 11, 13, 14, 15,  6,  7,  9,  8,\n\t        7, 6,   8, 13, 11,  9,  7, 15,  7, 12, 15,  9, 11,  7, 13, 12,\n\t        11, 13,  6,  7, 14,  9, 13, 15, 14,  8, 13,  6,  5, 12,  7,  5,\n\t          11, 12, 14, 15, 14, 15,  9,  8,  9, 14,  5,  6,  8,  6,  5, 12,\n\t        9, 15,  5, 11,  6,  8, 13, 12,  5, 12, 13, 14, 11,  8,  5,  6 ]);\n\t    var _sr = WordArray.create([\n\t        8,  9,  9, 11, 13, 15, 15,  5,  7,  7,  8, 11, 14, 14, 12,  6,\n\t        9, 13, 15,  7, 12,  8,  9, 11,  7,  7, 12,  7,  6, 15, 13, 11,\n\t        9,  7, 15, 11,  8,  6,  6, 14, 12, 13,  5, 14, 13, 13,  7,  5,\n\t        15,  5,  8, 11, 14, 14,  6, 14,  6,  9, 12,  9, 12,  5, 15,  8,\n\t        8,  5, 12,  9, 12,  5, 14,  6,  8, 13,  6,  5, 15, 13, 11, 11 ]);\n\n\t    var _hl =  WordArray.create([ 0x00000000, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E]);\n\t    var _hr =  WordArray.create([ 0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x7A6D76E9, 0x00000000]);\n\n\t    /**\n\t     * RIPEMD160 hash algorithm.\n\t     */\n\t    var RIPEMD160 = C_algo.RIPEMD160 = Hasher.extend({\n\t        _doReset: function () {\n\t            this._hash  = WordArray.create([0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0]);\n\t        },\n\n\t        _doProcessBlock: function (M, offset) {\n\n\t            // Swap endian\n\t            for (var i = 0; i < 16; i++) {\n\t                // Shortcuts\n\t                var offset_i = offset + i;\n\t                var M_offset_i = M[offset_i];\n\n\t                // Swap\n\t                M[offset_i] = (\n\t                    (((M_offset_i << 8)  | (M_offset_i >>> 24)) & 0x00ff00ff) |\n\t                    (((M_offset_i << 24) | (M_offset_i >>> 8))  & 0xff00ff00)\n\t                );\n\t            }\n\t            // Shortcut\n\t            var H  = this._hash.words;\n\t            var hl = _hl.words;\n\t            var hr = _hr.words;\n\t            var zl = _zl.words;\n\t            var zr = _zr.words;\n\t            var sl = _sl.words;\n\t            var sr = _sr.words;\n\n\t            // Working variables\n\t            var al, bl, cl, dl, el;\n\t            var ar, br, cr, dr, er;\n\n\t            ar = al = H[0];\n\t            br = bl = H[1];\n\t            cr = cl = H[2];\n\t            dr = dl = H[3];\n\t            er = el = H[4];\n\t            // Computation\n\t            var t;\n\t            for (var i = 0; i < 80; i += 1) {\n\t                t = (al +  M[offset+zl[i]])|0;\n\t                if (i<16){\n\t\t            t +=  f1(bl,cl,dl) + hl[0];\n\t                } else if (i<32) {\n\t\t            t +=  f2(bl,cl,dl) + hl[1];\n\t                } else if (i<48) {\n\t\t            t +=  f3(bl,cl,dl) + hl[2];\n\t                } else if (i<64) {\n\t\t            t +=  f4(bl,cl,dl) + hl[3];\n\t                } else {// if (i<80) {\n\t\t            t +=  f5(bl,cl,dl) + hl[4];\n\t                }\n\t                t = t|0;\n\t                t =  rotl(t,sl[i]);\n\t                t = (t+el)|0;\n\t                al = el;\n\t                el = dl;\n\t                dl = rotl(cl, 10);\n\t                cl = bl;\n\t                bl = t;\n\n\t                t = (ar + M[offset+zr[i]])|0;\n\t                if (i<16){\n\t\t            t +=  f5(br,cr,dr) + hr[0];\n\t                } else if (i<32) {\n\t\t            t +=  f4(br,cr,dr) + hr[1];\n\t                } else if (i<48) {\n\t\t            t +=  f3(br,cr,dr) + hr[2];\n\t                } else if (i<64) {\n\t\t            t +=  f2(br,cr,dr) + hr[3];\n\t                } else {// if (i<80) {\n\t\t            t +=  f1(br,cr,dr) + hr[4];\n\t                }\n\t                t = t|0;\n\t                t =  rotl(t,sr[i]) ;\n\t                t = (t+er)|0;\n\t                ar = er;\n\t                er = dr;\n\t                dr = rotl(cr, 10);\n\t                cr = br;\n\t                br = t;\n\t            }\n\t            // Intermediate hash value\n\t            t    = (H[1] + cl + dr)|0;\n\t            H[1] = (H[2] + dl + er)|0;\n\t            H[2] = (H[3] + el + ar)|0;\n\t            H[3] = (H[4] + al + br)|0;\n\t            H[4] = (H[0] + bl + cr)|0;\n\t            H[0] =  t;\n\t        },\n\n\t        _doFinalize: function () {\n\t            // Shortcuts\n\t            var data = this._data;\n\t            var dataWords = data.words;\n\n\t            var nBitsTotal = this._nDataBytes * 8;\n\t            var nBitsLeft = data.sigBytes * 8;\n\n\t            // Add padding\n\t            dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);\n\t            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = (\n\t                (((nBitsTotal << 8)  | (nBitsTotal >>> 24)) & 0x00ff00ff) |\n\t                (((nBitsTotal << 24) | (nBitsTotal >>> 8))  & 0xff00ff00)\n\t            );\n\t            data.sigBytes = (dataWords.length + 1) * 4;\n\n\t            // Hash final blocks\n\t            this._process();\n\n\t            // Shortcuts\n\t            var hash = this._hash;\n\t            var H = hash.words;\n\n\t            // Swap endian\n\t            for (var i = 0; i < 5; i++) {\n\t                // Shortcut\n\t                var H_i = H[i];\n\n\t                // Swap\n\t                H[i] = (((H_i << 8)  | (H_i >>> 24)) & 0x00ff00ff) |\n\t                       (((H_i << 24) | (H_i >>> 8))  & 0xff00ff00);\n\t            }\n\n\t            // Return final computed hash\n\t            return hash;\n\t        },\n\n\t        clone: function () {\n\t            var clone = Hasher.clone.call(this);\n\t            clone._hash = this._hash.clone();\n\n\t            return clone;\n\t        }\n\t    });\n\n\n\t    function f1(x, y, z) {\n\t        return ((x) ^ (y) ^ (z));\n\n\t    }\n\n\t    function f2(x, y, z) {\n\t        return (((x)&(y)) | ((~x)&(z)));\n\t    }\n\n\t    function f3(x, y, z) {\n\t        return (((x) | (~(y))) ^ (z));\n\t    }\n\n\t    function f4(x, y, z) {\n\t        return (((x) & (z)) | ((y)&(~(z))));\n\t    }\n\n\t    function f5(x, y, z) {\n\t        return ((x) ^ ((y) |(~(z))));\n\n\t    }\n\n\t    function rotl(x,n) {\n\t        return (x<<n) | (x>>>(32-n));\n\t    }\n\n\n\t    /**\n\t     * Shortcut function to the hasher's object interface.\n\t     *\n\t     * @param {WordArray|string} message The message to hash.\n\t     *\n\t     * @return {WordArray} The hash.\n\t     *\n\t     * @static\n\t     *\n\t     * @example\n\t     *\n\t     *     var hash = CryptoJS.RIPEMD160('message');\n\t     *     var hash = CryptoJS.RIPEMD160(wordArray);\n\t     */\n\t    C.RIPEMD160 = Hasher._createHelper(RIPEMD160);\n\n\t    /**\n\t     * Shortcut function to the HMAC's object interface.\n\t     *\n\t     * @param {WordArray|string} message The message to hash.\n\t     * @param {WordArray|string} key The secret key.\n\t     *\n\t     * @return {WordArray} The HMAC.\n\t     *\n\t     * @static\n\t     *\n\t     * @example\n\t     *\n\t     *     var hmac = CryptoJS.HmacRIPEMD160(message, key);\n\t     */\n\t    C.HmacRIPEMD160 = Hasher._createHmacHelper(RIPEMD160);\n\t}(Math));\n\n\n\t(function () {\n\t    // Shortcuts\n\t    var C = CryptoJS;\n\t    var C_lib = C.lib;\n\t    var Base = C_lib.Base;\n\t    var C_enc = C.enc;\n\t    var Utf8 = C_enc.Utf8;\n\t    var C_algo = C.algo;\n\n\t    /**\n\t     * HMAC algorithm.\n\t     */\n\t    var HMAC = C_algo.HMAC = Base.extend({\n\t        /**\n\t         * Initializes a newly created HMAC.\n\t         *\n\t         * @param {Hasher} hasher The hash algorithm to use.\n\t         * @param {WordArray|string} key The secret key.\n\t         *\n\t         * @example\n\t         *\n\t         *     var hmacHasher = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, key);\n\t         */\n\t        init: function (hasher, key) {\n\t            // Init hasher\n\t            hasher = this._hasher = new hasher.init();\n\n\t            // Convert string to WordArray, else assume WordArray already\n\t            if (typeof key == 'string') {\n\t                key = Utf8.parse(key);\n\t            }\n\n\t            // Shortcuts\n\t            var hasherBlockSize = hasher.blockSize;\n\t            var hasherBlockSizeBytes = hasherBlockSize * 4;\n\n\t            // Allow arbitrary length keys\n\t            if (key.sigBytes > hasherBlockSizeBytes) {\n\t                key = hasher.finalize(key);\n\t            }\n\n\t            // Clamp excess bits\n\t            key.clamp();\n\n\t            // Clone key for inner and outer pads\n\t            var oKey = this._oKey = key.clone();\n\t            var iKey = this._iKey = key.clone();\n\n\t            // Shortcuts\n\t            var oKeyWords = oKey.words;\n\t            var iKeyWords = iKey.words;\n\n\t            // XOR keys with pad constants\n\t            for (var i = 0; i < hasherBlockSize; i++) {\n\t                oKeyWords[i] ^= 0x5c5c5c5c;\n\t                iKeyWords[i] ^= 0x36363636;\n\t            }\n\t            oKey.sigBytes = iKey.sigBytes = hasherBlockSizeBytes;\n\n\t            // Set initial values\n\t            this.reset();\n\t        },\n\n\t        /**\n\t         * Resets this HMAC to its initial state.\n\t         *\n\t         * @example\n\t         *\n\t         *     hmacHasher.reset();\n\t         */\n\t        reset: function () {\n\t            // Shortcut\n\t            var hasher = this._hasher;\n\n\t            // Reset\n\t            hasher.reset();\n\t            hasher.update(this._iKey);\n\t        },\n\n\t        /**\n\t         * Updates this HMAC with a message.\n\t         *\n\t         * @param {WordArray|string} messageUpdate The message to append.\n\t         *\n\t         * @return {HMAC} This HMAC instance.\n\t         *\n\t         * @example\n\t         *\n\t         *     hmacHasher.update('message');\n\t         *     hmacHasher.update(wordArray);\n\t         */\n\t        update: function (messageUpdate) {\n\t            this._hasher.update(messageUpdate);\n\n\t            // Chainable\n\t            return this;\n\t        },\n\n\t        /**\n\t         * Finalizes the HMAC computation.\n\t         * Note that the finalize operation is effectively a destructive, read-once operation.\n\t         *\n\t         * @param {WordArray|string} messageUpdate (Optional) A final message update.\n\t         *\n\t         * @return {WordArray} The HMAC.\n\t         *\n\t         * @example\n\t         *\n\t         *     var hmac = hmacHasher.finalize();\n\t         *     var hmac = hmacHasher.finalize('message');\n\t         *     var hmac = hmacHasher.finalize(wordArray);\n\t         */\n\t        finalize: function (messageUpdate) {\n\t            // Shortcut\n\t            var hasher = this._hasher;\n\n\t            // Compute HMAC\n\t            var innerHash = hasher.finalize(messageUpdate);\n\t            hasher.reset();\n\t            var hmac = hasher.finalize(this._oKey.clone().concat(innerHash));\n\n\t            return hmac;\n\t        }\n\t    });\n\t}());\n\n\n\t(function () {\n\t    // Shortcuts\n\t    var C = CryptoJS;\n\t    var C_lib = C.lib;\n\t    var Base = C_lib.Base;\n\t    var WordArray = C_lib.WordArray;\n\t    var C_algo = C.algo;\n\t    var SHA1 = C_algo.SHA1;\n\t    var HMAC = C_algo.HMAC;\n\n\t    /**\n\t     * Password-Based Key Derivation Function 2 algorithm.\n\t     */\n\t    var PBKDF2 = C_algo.PBKDF2 = Base.extend({\n\t        /**\n\t         * Configuration options.\n\t         *\n\t         * @property {number} keySize The key size in words to generate. Default: 4 (128 bits)\n\t         * @property {Hasher} hasher The hasher to use. Default: SHA1\n\t         * @property {number} iterations The number of iterations to perform. Default: 1\n\t         */\n\t        cfg: Base.extend({\n\t            keySize: 128/32,\n\t            hasher: SHA1,\n\t            iterations: 1\n\t        }),\n\n\t        /**\n\t         * Initializes a newly created key derivation function.\n\t         *\n\t         * @param {Object} cfg (Optional) The configuration options to use for the derivation.\n\t         *\n\t         * @example\n\t         *\n\t         *     var kdf = CryptoJS.algo.PBKDF2.create();\n\t         *     var kdf = CryptoJS.algo.PBKDF2.create({ keySize: 8 });\n\t         *     var kdf = CryptoJS.algo.PBKDF2.create({ keySize: 8, iterations: 1000 });\n\t         */\n\t        init: function (cfg) {\n\t            this.cfg = this.cfg.extend(cfg);\n\t        },\n\n\t        /**\n\t         * Computes the Password-Based Key Derivation Function 2.\n\t         *\n\t         * @param {WordArray|string} password The password.\n\t         * @param {WordArray|string} salt A salt.\n\t         *\n\t         * @return {WordArray} The derived key.\n\t         *\n\t         * @example\n\t         *\n\t         *     var key = kdf.compute(password, salt);\n\t         */\n\t        compute: function (password, salt) {\n\t            // Shortcut\n\t            var cfg = this.cfg;\n\n\t            // Init HMAC\n\t            var hmac = HMAC.create(cfg.hasher, password);\n\n\t            // Initial values\n\t            var derivedKey = WordArray.create();\n\t            var blockIndex = WordArray.create([0x00000001]);\n\n\t            // Shortcuts\n\t            var derivedKeyWords = derivedKey.words;\n\t            var blockIndexWords = blockIndex.words;\n\t            var keySize = cfg.keySize;\n\t            var iterations = cfg.iterations;\n\n\t            // Generate key\n\t            while (derivedKeyWords.length < keySize) {\n\t                var block = hmac.update(salt).finalize(blockIndex);\n\t                hmac.reset();\n\n\t                // Shortcuts\n\t                var blockWords = block.words;\n\t                var blockWordsLength = blockWords.length;\n\n\t                // Iterations\n\t                var intermediate = block;\n\t                for (var i = 1; i < iterations; i++) {\n\t                    intermediate = hmac.finalize(intermediate);\n\t                    hmac.reset();\n\n\t                    // Shortcut\n\t                    var intermediateWords = intermediate.words;\n\n\t                    // XOR intermediate with block\n\t                    for (var j = 0; j < blockWordsLength; j++) {\n\t                        blockWords[j] ^= intermediateWords[j];\n\t                    }\n\t                }\n\n\t                derivedKey.concat(block);\n\t                blockIndexWords[0]++;\n\t            }\n\t            derivedKey.sigBytes = keySize * 4;\n\n\t            return derivedKey;\n\t        }\n\t    });\n\n\t    /**\n\t     * Computes the Password-Based Key Derivation Function 2.\n\t     *\n\t     * @param {WordArray|string} password The password.\n\t     * @param {WordArray|string} salt A salt.\n\t     * @param {Object} cfg (Optional) The configuration options to use for this computation.\n\t     *\n\t     * @return {WordArray} The derived key.\n\t     *\n\t     * @static\n\t     *\n\t     * @example\n\t     *\n\t     *     var key = CryptoJS.PBKDF2(password, salt);\n\t     *     var key = CryptoJS.PBKDF2(password, salt, { keySize: 8 });\n\t     *     var key = CryptoJS.PBKDF2(password, salt, { keySize: 8, iterations: 1000 });\n\t     */\n\t    C.PBKDF2 = function (password, salt, cfg) {\n\t        return PBKDF2.create(cfg).compute(password, salt);\n\t    };\n\t}());\n\n\n\t(function () {\n\t    // Shortcuts\n\t    var C = CryptoJS;\n\t    var C_lib = C.lib;\n\t    var Base = C_lib.Base;\n\t    var WordArray = C_lib.WordArray;\n\t    var C_algo = C.algo;\n\t    var MD5 = C_algo.MD5;\n\n\t    /**\n\t     * This key derivation function is meant to conform with EVP_BytesToKey.\n\t     * www.openssl.org/docs/crypto/EVP_BytesToKey.html\n\t     */\n\t    var EvpKDF = C_algo.EvpKDF = Base.extend({\n\t        /**\n\t         * Configuration options.\n\t         *\n\t         * @property {number} keySize The key size in words to generate. Default: 4 (128 bits)\n\t         * @property {Hasher} hasher The hash algorithm to use. Default: MD5\n\t         * @property {number} iterations The number of iterations to perform. Default: 1\n\t         */\n\t        cfg: Base.extend({\n\t            keySize: 128/32,\n\t            hasher: MD5,\n\t            iterations: 1\n\t        }),\n\n\t        /**\n\t         * Initializes a newly created key derivation function.\n\t         *\n\t         * @param {Object} cfg (Optional) The configuration options to use for the derivation.\n\t         *\n\t         * @example\n\t         *\n\t         *     var kdf = CryptoJS.algo.EvpKDF.create();\n\t         *     var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8 });\n\t         *     var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8, iterations: 1000 });\n\t         */\n\t        init: function (cfg) {\n\t            this.cfg = this.cfg.extend(cfg);\n\t        },\n\n\t        /**\n\t         * Derives a key from a password.\n\t         *\n\t         * @param {WordArray|string} password The password.\n\t         * @param {WordArray|string} salt A salt.\n\t         *\n\t         * @return {WordArray} The derived key.\n\t         *\n\t         * @example\n\t         *\n\t         *     var key = kdf.compute(password, salt);\n\t         */\n\t        compute: function (password, salt) {\n\t            var block;\n\n\t            // Shortcut\n\t            var cfg = this.cfg;\n\n\t            // Init hasher\n\t            var hasher = cfg.hasher.create();\n\n\t            // Initial values\n\t            var derivedKey = WordArray.create();\n\n\t            // Shortcuts\n\t            var derivedKeyWords = derivedKey.words;\n\t            var keySize = cfg.keySize;\n\t            var iterations = cfg.iterations;\n\n\t            // Generate key\n\t            while (derivedKeyWords.length < keySize) {\n\t                if (block) {\n\t                    hasher.update(block);\n\t                }\n\t                block = hasher.update(password).finalize(salt);\n\t                hasher.reset();\n\n\t                // Iterations\n\t                for (var i = 1; i < iterations; i++) {\n\t                    block = hasher.finalize(block);\n\t                    hasher.reset();\n\t                }\n\n\t                derivedKey.concat(block);\n\t            }\n\t            derivedKey.sigBytes = keySize * 4;\n\n\t            return derivedKey;\n\t        }\n\t    });\n\n\t    /**\n\t     * Derives a key from a password.\n\t     *\n\t     * @param {WordArray|string} password The password.\n\t     * @param {WordArray|string} salt A salt.\n\t     * @param {Object} cfg (Optional) The configuration options to use for this computation.\n\t     *\n\t     * @return {WordArray} The derived key.\n\t     *\n\t     * @static\n\t     *\n\t     * @example\n\t     *\n\t     *     var key = CryptoJS.EvpKDF(password, salt);\n\t     *     var key = CryptoJS.EvpKDF(password, salt, { keySize: 8 });\n\t     *     var key = CryptoJS.EvpKDF(password, salt, { keySize: 8, iterations: 1000 });\n\t     */\n\t    C.EvpKDF = function (password, salt, cfg) {\n\t        return EvpKDF.create(cfg).compute(password, salt);\n\t    };\n\t}());\n\n\n\t(function () {\n\t    // Shortcuts\n\t    var C = CryptoJS;\n\t    var C_lib = C.lib;\n\t    var WordArray = C_lib.WordArray;\n\t    var C_algo = C.algo;\n\t    var SHA256 = C_algo.SHA256;\n\n\t    /**\n\t     * SHA-224 hash algorithm.\n\t     */\n\t    var SHA224 = C_algo.SHA224 = SHA256.extend({\n\t        _doReset: function () {\n\t            this._hash = new WordArray.init([\n\t                0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,\n\t                0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4\n\t            ]);\n\t        },\n\n\t        _doFinalize: function () {\n\t            var hash = SHA256._doFinalize.call(this);\n\n\t            hash.sigBytes -= 4;\n\n\t            return hash;\n\t        }\n\t    });\n\n\t    /**\n\t     * Shortcut function to the hasher's object interface.\n\t     *\n\t     * @param {WordArray|string} message The message to hash.\n\t     *\n\t     * @return {WordArray} The hash.\n\t     *\n\t     * @static\n\t     *\n\t     * @example\n\t     *\n\t     *     var hash = CryptoJS.SHA224('message');\n\t     *     var hash = CryptoJS.SHA224(wordArray);\n\t     */\n\t    C.SHA224 = SHA256._createHelper(SHA224);\n\n\t    /**\n\t     * Shortcut function to the HMAC's object interface.\n\t     *\n\t     * @param {WordArray|string} message The message to hash.\n\t     * @param {WordArray|string} key The secret key.\n\t     *\n\t     * @return {WordArray} The HMAC.\n\t     *\n\t     * @static\n\t     *\n\t     * @example\n\t     *\n\t     *     var hmac = CryptoJS.HmacSHA224(message, key);\n\t     */\n\t    C.HmacSHA224 = SHA256._createHmacHelper(SHA224);\n\t}());\n\n\n\t(function (undefined) {\n\t    // Shortcuts\n\t    var C = CryptoJS;\n\t    var C_lib = C.lib;\n\t    var Base = C_lib.Base;\n\t    var X32WordArray = C_lib.WordArray;\n\n\t    /**\n\t     * x64 namespace.\n\t     */\n\t    var C_x64 = C.x64 = {};\n\n\t    /**\n\t     * A 64-bit word.\n\t     */\n\t    var X64Word = C_x64.Word = Base.extend({\n\t        /**\n\t         * Initializes a newly created 64-bit word.\n\t         *\n\t         * @param {number} high The high 32 bits.\n\t         * @param {number} low The low 32 bits.\n\t         *\n\t         * @example\n\t         *\n\t         *     var x64Word = CryptoJS.x64.Word.create(0x00010203, 0x04050607);\n\t         */\n\t        init: function (high, low) {\n\t            this.high = high;\n\t            this.low = low;\n\t        }\n\n\t        /**\n\t         * Bitwise NOTs this word.\n\t         *\n\t         * @return {X64Word} A new x64-Word object after negating.\n\t         *\n\t         * @example\n\t         *\n\t         *     var negated = x64Word.not();\n\t         */\n\t        // not: function () {\n\t            // var high = ~this.high;\n\t            // var low = ~this.low;\n\n\t            // return X64Word.create(high, low);\n\t        // },\n\n\t        /**\n\t         * Bitwise ANDs this word with the passed word.\n\t         *\n\t         * @param {X64Word} word The x64-Word to AND with this word.\n\t         *\n\t         * @return {X64Word} A new x64-Word object after ANDing.\n\t         *\n\t         * @example\n\t         *\n\t         *     var anded = x64Word.and(anotherX64Word);\n\t         */\n\t        // and: function (word) {\n\t            // var high = this.high & word.high;\n\t            // var low = this.low & word.low;\n\n\t            // return X64Word.create(high, low);\n\t        // },\n\n\t        /**\n\t         * Bitwise ORs this word with the passed word.\n\t         *\n\t         * @param {X64Word} word The x64-Word to OR with this word.\n\t         *\n\t         * @return {X64Word} A new x64-Word object after ORing.\n\t         *\n\t         * @example\n\t         *\n\t         *     var ored = x64Word.or(anotherX64Word);\n\t         */\n\t        // or: function (word) {\n\t            // var high = this.high | word.high;\n\t            // var low = this.low | word.low;\n\n\t            // return X64Word.create(high, low);\n\t        // },\n\n\t        /**\n\t         * Bitwise XORs this word with the passed word.\n\t         *\n\t         * @param {X64Word} word The x64-Word to XOR with this word.\n\t         *\n\t         * @return {X64Word} A new x64-Word object after XORing.\n\t         *\n\t         * @example\n\t         *\n\t         *     var xored = x64Word.xor(anotherX64Word);\n\t         */\n\t        // xor: function (word) {\n\t            // var high = this.high ^ word.high;\n\t            // var low = this.low ^ word.low;\n\n\t            // return X64Word.create(high, low);\n\t        // },\n\n\t        /**\n\t         * Shifts this word n bits to the left.\n\t         *\n\t         * @param {number} n The number of bits to shift.\n\t         *\n\t         * @return {X64Word} A new x64-Word object after shifting.\n\t         *\n\t         * @example\n\t         *\n\t         *     var shifted = x64Word.shiftL(25);\n\t         */\n\t        // shiftL: function (n) {\n\t            // if (n < 32) {\n\t                // var high = (this.high << n) | (this.low >>> (32 - n));\n\t                // var low = this.low << n;\n\t            // } else {\n\t                // var high = this.low << (n - 32);\n\t                // var low = 0;\n\t            // }\n\n\t            // return X64Word.create(high, low);\n\t        // },\n\n\t        /**\n\t         * Shifts this word n bits to the right.\n\t         *\n\t         * @param {number} n The number of bits to shift.\n\t         *\n\t         * @return {X64Word} A new x64-Word object after shifting.\n\t         *\n\t         * @example\n\t         *\n\t         *     var shifted = x64Word.shiftR(7);\n\t         */\n\t        // shiftR: function (n) {\n\t            // if (n < 32) {\n\t                // var low = (this.low >>> n) | (this.high << (32 - n));\n\t                // var high = this.high >>> n;\n\t            // } else {\n\t                // var low = this.high >>> (n - 32);\n\t                // var high = 0;\n\t            // }\n\n\t            // return X64Word.create(high, low);\n\t        // },\n\n\t        /**\n\t         * Rotates this word n bits to the left.\n\t         *\n\t         * @param {number} n The number of bits to rotate.\n\t         *\n\t         * @return {X64Word} A new x64-Word object after rotating.\n\t         *\n\t         * @example\n\t         *\n\t         *     var rotated = x64Word.rotL(25);\n\t         */\n\t        // rotL: function (n) {\n\t            // return this.shiftL(n).or(this.shiftR(64 - n));\n\t        // },\n\n\t        /**\n\t         * Rotates this word n bits to the right.\n\t         *\n\t         * @param {number} n The number of bits to rotate.\n\t         *\n\t         * @return {X64Word} A new x64-Word object after rotating.\n\t         *\n\t         * @example\n\t         *\n\t         *     var rotated = x64Word.rotR(7);\n\t         */\n\t        // rotR: function (n) {\n\t            // return this.shiftR(n).or(this.shiftL(64 - n));\n\t        // },\n\n\t        /**\n\t         * Adds this word with the passed word.\n\t         *\n\t         * @param {X64Word} word The x64-Word to add with this word.\n\t         *\n\t         * @return {X64Word} A new x64-Word object after adding.\n\t         *\n\t         * @example\n\t         *\n\t         *     var added = x64Word.add(anotherX64Word);\n\t         */\n\t        // add: function (word) {\n\t            // var low = (this.low + word.low) | 0;\n\t            // var carry = (low >>> 0) < (this.low >>> 0) ? 1 : 0;\n\t            // var high = (this.high + word.high + carry) | 0;\n\n\t            // return X64Word.create(high, low);\n\t        // }\n\t    });\n\n\t    /**\n\t     * An array of 64-bit words.\n\t     *\n\t     * @property {Array} words The array of CryptoJS.x64.Word objects.\n\t     * @property {number} sigBytes The number of significant bytes in this word array.\n\t     */\n\t    var X64WordArray = C_x64.WordArray = Base.extend({\n\t        /**\n\t         * Initializes a newly created word array.\n\t         *\n\t         * @param {Array} words (Optional) An array of CryptoJS.x64.Word objects.\n\t         * @param {number} sigBytes (Optional) The number of significant bytes in the words.\n\t         *\n\t         * @example\n\t         *\n\t         *     var wordArray = CryptoJS.x64.WordArray.create();\n\t         *\n\t         *     var wordArray = CryptoJS.x64.WordArray.create([\n\t         *         CryptoJS.x64.Word.create(0x00010203, 0x04050607),\n\t         *         CryptoJS.x64.Word.create(0x18191a1b, 0x1c1d1e1f)\n\t         *     ]);\n\t         *\n\t         *     var wordArray = CryptoJS.x64.WordArray.create([\n\t         *         CryptoJS.x64.Word.create(0x00010203, 0x04050607),\n\t         *         CryptoJS.x64.Word.create(0x18191a1b, 0x1c1d1e1f)\n\t         *     ], 10);\n\t         */\n\t        init: function (words, sigBytes) {\n\t            words = this.words = words || [];\n\n\t            if (sigBytes != undefined) {\n\t                this.sigBytes = sigBytes;\n\t            } else {\n\t                this.sigBytes = words.length * 8;\n\t            }\n\t        },\n\n\t        /**\n\t         * Converts this 64-bit word array to a 32-bit word array.\n\t         *\n\t         * @return {CryptoJS.lib.WordArray} This word array's data as a 32-bit word array.\n\t         *\n\t         * @example\n\t         *\n\t         *     var x32WordArray = x64WordArray.toX32();\n\t         */\n\t        toX32: function () {\n\t            // Shortcuts\n\t            var x64Words = this.words;\n\t            var x64WordsLength = x64Words.length;\n\n\t            // Convert\n\t            var x32Words = [];\n\t            for (var i = 0; i < x64WordsLength; i++) {\n\t                var x64Word = x64Words[i];\n\t                x32Words.push(x64Word.high);\n\t                x32Words.push(x64Word.low);\n\t            }\n\n\t            return X32WordArray.create(x32Words, this.sigBytes);\n\t        },\n\n\t        /**\n\t         * Creates a copy of this word array.\n\t         *\n\t         * @return {X64WordArray} The clone.\n\t         *\n\t         * @example\n\t         *\n\t         *     var clone = x64WordArray.clone();\n\t         */\n\t        clone: function () {\n\t            var clone = Base.clone.call(this);\n\n\t            // Clone \"words\" array\n\t            var words = clone.words = this.words.slice(0);\n\n\t            // Clone each X64Word object\n\t            var wordsLength = words.length;\n\t            for (var i = 0; i < wordsLength; i++) {\n\t                words[i] = words[i].clone();\n\t            }\n\n\t            return clone;\n\t        }\n\t    });\n\t}());\n\n\n\t(function (Math) {\n\t    // Shortcuts\n\t    var C = CryptoJS;\n\t    var C_lib = C.lib;\n\t    var WordArray = C_lib.WordArray;\n\t    var Hasher = C_lib.Hasher;\n\t    var C_x64 = C.x64;\n\t    var X64Word = C_x64.Word;\n\t    var C_algo = C.algo;\n\n\t    // Constants tables\n\t    var RHO_OFFSETS = [];\n\t    var PI_INDEXES  = [];\n\t    var ROUND_CONSTANTS = [];\n\n\t    // Compute Constants\n\t    (function () {\n\t        // Compute rho offset constants\n\t        var x = 1, y = 0;\n\t        for (var t = 0; t < 24; t++) {\n\t            RHO_OFFSETS[x + 5 * y] = ((t + 1) * (t + 2) / 2) % 64;\n\n\t            var newX = y % 5;\n\t            var newY = (2 * x + 3 * y) % 5;\n\t            x = newX;\n\t            y = newY;\n\t        }\n\n\t        // Compute pi index constants\n\t        for (var x = 0; x < 5; x++) {\n\t            for (var y = 0; y < 5; y++) {\n\t                PI_INDEXES[x + 5 * y] = y + ((2 * x + 3 * y) % 5) * 5;\n\t            }\n\t        }\n\n\t        // Compute round constants\n\t        var LFSR = 0x01;\n\t        for (var i = 0; i < 24; i++) {\n\t            var roundConstantMsw = 0;\n\t            var roundConstantLsw = 0;\n\n\t            for (var j = 0; j < 7; j++) {\n\t                if (LFSR & 0x01) {\n\t                    var bitPosition = (1 << j) - 1;\n\t                    if (bitPosition < 32) {\n\t                        roundConstantLsw ^= 1 << bitPosition;\n\t                    } else /* if (bitPosition >= 32) */ {\n\t                        roundConstantMsw ^= 1 << (bitPosition - 32);\n\t                    }\n\t                }\n\n\t                // Compute next LFSR\n\t                if (LFSR & 0x80) {\n\t                    // Primitive polynomial over GF(2): x^8 + x^6 + x^5 + x^4 + 1\n\t                    LFSR = (LFSR << 1) ^ 0x71;\n\t                } else {\n\t                    LFSR <<= 1;\n\t                }\n\t            }\n\n\t            ROUND_CONSTANTS[i] = X64Word.create(roundConstantMsw, roundConstantLsw);\n\t        }\n\t    }());\n\n\t    // Reusable objects for temporary values\n\t    var T = [];\n\t    (function () {\n\t        for (var i = 0; i < 25; i++) {\n\t            T[i] = X64Word.create();\n\t        }\n\t    }());\n\n\t    /**\n\t     * SHA-3 hash algorithm.\n\t     */\n\t    var SHA3 = C_algo.SHA3 = Hasher.extend({\n\t        /**\n\t         * Configuration options.\n\t         *\n\t         * @property {number} outputLength\n\t         *   The desired number of bits in the output hash.\n\t         *   Only values permitted are: 224, 256, 384, 512.\n\t         *   Default: 512\n\t         */\n\t        cfg: Hasher.cfg.extend({\n\t            outputLength: 512\n\t        }),\n\n\t        _doReset: function () {\n\t            var state = this._state = []\n\t            for (var i = 0; i < 25; i++) {\n\t                state[i] = new X64Word.init();\n\t            }\n\n\t            this.blockSize = (1600 - 2 * this.cfg.outputLength) / 32;\n\t        },\n\n\t        _doProcessBlock: function (M, offset) {\n\t            // Shortcuts\n\t            var state = this._state;\n\t            var nBlockSizeLanes = this.blockSize / 2;\n\n\t            // Absorb\n\t            for (var i = 0; i < nBlockSizeLanes; i++) {\n\t                // Shortcuts\n\t                var M2i  = M[offset + 2 * i];\n\t                var M2i1 = M[offset + 2 * i + 1];\n\n\t                // Swap endian\n\t                M2i = (\n\t                    (((M2i << 8)  | (M2i >>> 24)) & 0x00ff00ff) |\n\t                    (((M2i << 24) | (M2i >>> 8))  & 0xff00ff00)\n\t                );\n\t                M2i1 = (\n\t                    (((M2i1 << 8)  | (M2i1 >>> 24)) & 0x00ff00ff) |\n\t                    (((M2i1 << 24) | (M2i1 >>> 8))  & 0xff00ff00)\n\t                );\n\n\t                // Absorb message into state\n\t                var lane = state[i];\n\t                lane.high ^= M2i1;\n\t                lane.low  ^= M2i;\n\t            }\n\n\t            // Rounds\n\t            for (var round = 0; round < 24; round++) {\n\t                // Theta\n\t                for (var x = 0; x < 5; x++) {\n\t                    // Mix column lanes\n\t                    var tMsw = 0, tLsw = 0;\n\t                    for (var y = 0; y < 5; y++) {\n\t                        var lane = state[x + 5 * y];\n\t                        tMsw ^= lane.high;\n\t                        tLsw ^= lane.low;\n\t                    }\n\n\t                    // Temporary values\n\t                    var Tx = T[x];\n\t                    Tx.high = tMsw;\n\t                    Tx.low  = tLsw;\n\t                }\n\t                for (var x = 0; x < 5; x++) {\n\t                    // Shortcuts\n\t                    var Tx4 = T[(x + 4) % 5];\n\t                    var Tx1 = T[(x + 1) % 5];\n\t                    var Tx1Msw = Tx1.high;\n\t                    var Tx1Lsw = Tx1.low;\n\n\t                    // Mix surrounding columns\n\t                    var tMsw = Tx4.high ^ ((Tx1Msw << 1) | (Tx1Lsw >>> 31));\n\t                    var tLsw = Tx4.low  ^ ((Tx1Lsw << 1) | (Tx1Msw >>> 31));\n\t                    for (var y = 0; y < 5; y++) {\n\t                        var lane = state[x + 5 * y];\n\t                        lane.high ^= tMsw;\n\t                        lane.low  ^= tLsw;\n\t                    }\n\t                }\n\n\t                // Rho Pi\n\t                for (var laneIndex = 1; laneIndex < 25; laneIndex++) {\n\t                    var tMsw;\n\t                    var tLsw;\n\n\t                    // Shortcuts\n\t                    var lane = state[laneIndex];\n\t                    var laneMsw = lane.high;\n\t                    var laneLsw = lane.low;\n\t                    var rhoOffset = RHO_OFFSETS[laneIndex];\n\n\t                    // Rotate lanes\n\t                    if (rhoOffset < 32) {\n\t                        tMsw = (laneMsw << rhoOffset) | (laneLsw >>> (32 - rhoOffset));\n\t                        tLsw = (laneLsw << rhoOffset) | (laneMsw >>> (32 - rhoOffset));\n\t                    } else /* if (rhoOffset >= 32) */ {\n\t                        tMsw = (laneLsw << (rhoOffset - 32)) | (laneMsw >>> (64 - rhoOffset));\n\t                        tLsw = (laneMsw << (rhoOffset - 32)) | (laneLsw >>> (64 - rhoOffset));\n\t                    }\n\n\t                    // Transpose lanes\n\t                    var TPiLane = T[PI_INDEXES[laneIndex]];\n\t                    TPiLane.high = tMsw;\n\t                    TPiLane.low  = tLsw;\n\t                }\n\n\t                // Rho pi at x = y = 0\n\t                var T0 = T[0];\n\t                var state0 = state[0];\n\t                T0.high = state0.high;\n\t                T0.low  = state0.low;\n\n\t                // Chi\n\t                for (var x = 0; x < 5; x++) {\n\t                    for (var y = 0; y < 5; y++) {\n\t                        // Shortcuts\n\t                        var laneIndex = x + 5 * y;\n\t                        var lane = state[laneIndex];\n\t                        var TLane = T[laneIndex];\n\t                        var Tx1Lane = T[((x + 1) % 5) + 5 * y];\n\t                        var Tx2Lane = T[((x + 2) % 5) + 5 * y];\n\n\t                        // Mix rows\n\t                        lane.high = TLane.high ^ (~Tx1Lane.high & Tx2Lane.high);\n\t                        lane.low  = TLane.low  ^ (~Tx1Lane.low  & Tx2Lane.low);\n\t                    }\n\t                }\n\n\t                // Iota\n\t                var lane = state[0];\n\t                var roundConstant = ROUND_CONSTANTS[round];\n\t                lane.high ^= roundConstant.high;\n\t                lane.low  ^= roundConstant.low;\n\t            }\n\t        },\n\n\t        _doFinalize: function () {\n\t            // Shortcuts\n\t            var data = this._data;\n\t            var dataWords = data.words;\n\t            var nBitsTotal = this._nDataBytes * 8;\n\t            var nBitsLeft = data.sigBytes * 8;\n\t            var blockSizeBits = this.blockSize * 32;\n\n\t            // Add padding\n\t            dataWords[nBitsLeft >>> 5] |= 0x1 << (24 - nBitsLeft % 32);\n\t            dataWords[((Math.ceil((nBitsLeft + 1) / blockSizeBits) * blockSizeBits) >>> 5) - 1] |= 0x80;\n\t            data.sigBytes = dataWords.length * 4;\n\n\t            // Hash final blocks\n\t            this._process();\n\n\t            // Shortcuts\n\t            var state = this._state;\n\t            var outputLengthBytes = this.cfg.outputLength / 8;\n\t            var outputLengthLanes = outputLengthBytes / 8;\n\n\t            // Squeeze\n\t            var hashWords = [];\n\t            for (var i = 0; i < outputLengthLanes; i++) {\n\t                // Shortcuts\n\t                var lane = state[i];\n\t                var laneMsw = lane.high;\n\t                var laneLsw = lane.low;\n\n\t                // Swap endian\n\t                laneMsw = (\n\t                    (((laneMsw << 8)  | (laneMsw >>> 24)) & 0x00ff00ff) |\n\t                    (((laneMsw << 24) | (laneMsw >>> 8))  & 0xff00ff00)\n\t                );\n\t                laneLsw = (\n\t                    (((laneLsw << 8)  | (laneLsw >>> 24)) & 0x00ff00ff) |\n\t                    (((laneLsw << 24) | (laneLsw >>> 8))  & 0xff00ff00)\n\t                );\n\n\t                // Squeeze state to retrieve hash\n\t                hashWords.push(laneLsw);\n\t                hashWords.push(laneMsw);\n\t            }\n\n\t            // Return final computed hash\n\t            return new WordArray.init(hashWords, outputLengthBytes);\n\t        },\n\n\t        clone: function () {\n\t            var clone = Hasher.clone.call(this);\n\n\t            var state = clone._state = this._state.slice(0);\n\t            for (var i = 0; i < 25; i++) {\n\t                state[i] = state[i].clone();\n\t            }\n\n\t            return clone;\n\t        }\n\t    });\n\n\t    /**\n\t     * Shortcut function to the hasher's object interface.\n\t     *\n\t     * @param {WordArray|string} message The message to hash.\n\t     *\n\t     * @return {WordArray} The hash.\n\t     *\n\t     * @static\n\t     *\n\t     * @example\n\t     *\n\t     *     var hash = CryptoJS.SHA3('message');\n\t     *     var hash = CryptoJS.SHA3(wordArray);\n\t     */\n\t    C.SHA3 = Hasher._createHelper(SHA3);\n\n\t    /**\n\t     * Shortcut function to the HMAC's object interface.\n\t     *\n\t     * @param {WordArray|string} message The message to hash.\n\t     * @param {WordArray|string} key The secret key.\n\t     *\n\t     * @return {WordArray} The HMAC.\n\t     *\n\t     * @static\n\t     *\n\t     * @example\n\t     *\n\t     *     var hmac = CryptoJS.HmacSHA3(message, key);\n\t     */\n\t    C.HmacSHA3 = Hasher._createHmacHelper(SHA3);\n\t}(Math));\n\n\n\t(function () {\n\t    // Shortcuts\n\t    var C = CryptoJS;\n\t    var C_lib = C.lib;\n\t    var Hasher = C_lib.Hasher;\n\t    var C_x64 = C.x64;\n\t    var X64Word = C_x64.Word;\n\t    var X64WordArray = C_x64.WordArray;\n\t    var C_algo = C.algo;\n\n\t    function X64Word_create() {\n\t        return X64Word.create.apply(X64Word, arguments);\n\t    }\n\n\t    // Constants\n\t    var K = [\n\t        X64Word_create(0x428a2f98, 0xd728ae22), X64Word_create(0x71374491, 0x23ef65cd),\n\t        X64Word_create(0xb5c0fbcf, 0xec4d3b2f), X64Word_create(0xe9b5dba5, 0x8189dbbc),\n\t        X64Word_create(0x3956c25b, 0xf348b538), X64Word_create(0x59f111f1, 0xb605d019),\n\t        X64Word_create(0x923f82a4, 0xaf194f9b), X64Word_create(0xab1c5ed5, 0xda6d8118),\n\t        X64Word_create(0xd807aa98, 0xa3030242), X64Word_create(0x12835b01, 0x45706fbe),\n\t        X64Word_create(0x243185be, 0x4ee4b28c), X64Word_create(0x550c7dc3, 0xd5ffb4e2),\n\t        X64Word_create(0x72be5d74, 0xf27b896f), X64Word_create(0x80deb1fe, 0x3b1696b1),\n\t        X64Word_create(0x9bdc06a7, 0x25c71235), X64Word_create(0xc19bf174, 0xcf692694),\n\t        X64Word_create(0xe49b69c1, 0x9ef14ad2), X64Word_create(0xefbe4786, 0x384f25e3),\n\t        X64Word_create(0x0fc19dc6, 0x8b8cd5b5), X64Word_create(0x240ca1cc, 0x77ac9c65),\n\t        X64Word_create(0x2de92c6f, 0x592b0275), X64Word_create(0x4a7484aa, 0x6ea6e483),\n\t        X64Word_create(0x5cb0a9dc, 0xbd41fbd4), X64Word_create(0x76f988da, 0x831153b5),\n\t        X64Word_create(0x983e5152, 0xee66dfab), X64Word_create(0xa831c66d, 0x2db43210),\n\t        X64Word_create(0xb00327c8, 0x98fb213f), X64Word_create(0xbf597fc7, 0xbeef0ee4),\n\t        X64Word_create(0xc6e00bf3, 0x3da88fc2), X64Word_create(0xd5a79147, 0x930aa725),\n\t        X64Word_create(0x06ca6351, 0xe003826f), X64Word_create(0x14292967, 0x0a0e6e70),\n\t        X64Word_create(0x27b70a85, 0x46d22ffc), X64Word_create(0x2e1b2138, 0x5c26c926),\n\t        X64Word_create(0x4d2c6dfc, 0x5ac42aed), X64Word_create(0x53380d13, 0x9d95b3df),\n\t        X64Word_create(0x650a7354, 0x8baf63de), X64Word_create(0x766a0abb, 0x3c77b2a8),\n\t        X64Word_create(0x81c2c92e, 0x47edaee6), X64Word_create(0x92722c85, 0x1482353b),\n\t        X64Word_create(0xa2bfe8a1, 0x4cf10364), X64Word_create(0xa81a664b, 0xbc423001),\n\t        X64Word_create(0xc24b8b70, 0xd0f89791), X64Word_create(0xc76c51a3, 0x0654be30),\n\t        X64Word_create(0xd192e819, 0xd6ef5218), X64Word_create(0xd6990624, 0x5565a910),\n\t        X64Word_create(0xf40e3585, 0x5771202a), X64Word_create(0x106aa070, 0x32bbd1b8),\n\t        X64Word_create(0x19a4c116, 0xb8d2d0c8), X64Word_create(0x1e376c08, 0x5141ab53),\n\t        X64Word_create(0x2748774c, 0xdf8eeb99), X64Word_create(0x34b0bcb5, 0xe19b48a8),\n\t        X64Word_create(0x391c0cb3, 0xc5c95a63), X64Word_create(0x4ed8aa4a, 0xe3418acb),\n\t        X64Word_create(0x5b9cca4f, 0x7763e373), X64Word_create(0x682e6ff3, 0xd6b2b8a3),\n\t        X64Word_create(0x748f82ee, 0x5defb2fc), X64Word_create(0x78a5636f, 0x43172f60),\n\t        X64Word_create(0x84c87814, 0xa1f0ab72), X64Word_create(0x8cc70208, 0x1a6439ec),\n\t        X64Word_create(0x90befffa, 0x23631e28), X64Word_create(0xa4506ceb, 0xde82bde9),\n\t        X64Word_create(0xbef9a3f7, 0xb2c67915), X64Word_create(0xc67178f2, 0xe372532b),\n\t        X64Word_create(0xca273ece, 0xea26619c), X64Word_create(0xd186b8c7, 0x21c0c207),\n\t        X64Word_create(0xeada7dd6, 0xcde0eb1e), X64Word_create(0xf57d4f7f, 0xee6ed178),\n\t        X64Word_create(0x06f067aa, 0x72176fba), X64Word_create(0x0a637dc5, 0xa2c898a6),\n\t        X64Word_create(0x113f9804, 0xbef90dae), X64Word_create(0x1b710b35, 0x131c471b),\n\t        X64Word_create(0x28db77f5, 0x23047d84), X64Word_create(0x32caab7b, 0x40c72493),\n\t        X64Word_create(0x3c9ebe0a, 0x15c9bebc), X64Word_create(0x431d67c4, 0x9c100d4c),\n\t        X64Word_create(0x4cc5d4be, 0xcb3e42b6), X64Word_create(0x597f299c, 0xfc657e2a),\n\t        X64Word_create(0x5fcb6fab, 0x3ad6faec), X64Word_create(0x6c44198c, 0x4a475817)\n\t    ];\n\n\t    // Reusable objects\n\t    var W = [];\n\t    (function () {\n\t        for (var i = 0; i < 80; i++) {\n\t            W[i] = X64Word_create();\n\t        }\n\t    }());\n\n\t    /**\n\t     * SHA-512 hash algorithm.\n\t     */\n\t    var SHA512 = C_algo.SHA512 = Hasher.extend({\n\t        _doReset: function () {\n\t            this._hash = new X64WordArray.init([\n\t                new X64Word.init(0x6a09e667, 0xf3bcc908), new X64Word.init(0xbb67ae85, 0x84caa73b),\n\t                new X64Word.init(0x3c6ef372, 0xfe94f82b), new X64Word.init(0xa54ff53a, 0x5f1d36f1),\n\t                new X64Word.init(0x510e527f, 0xade682d1), new X64Word.init(0x9b05688c, 0x2b3e6c1f),\n\t                new X64Word.init(0x1f83d9ab, 0xfb41bd6b), new X64Word.init(0x5be0cd19, 0x137e2179)\n\t            ]);\n\t        },\n\n\t        _doProcessBlock: function (M, offset) {\n\t            // Shortcuts\n\t            var H = this._hash.words;\n\n\t            var H0 = H[0];\n\t            var H1 = H[1];\n\t            var H2 = H[2];\n\t            var H3 = H[3];\n\t            var H4 = H[4];\n\t            var H5 = H[5];\n\t            var H6 = H[6];\n\t            var H7 = H[7];\n\n\t            var H0h = H0.high;\n\t            var H0l = H0.low;\n\t            var H1h = H1.high;\n\t            var H1l = H1.low;\n\t            var H2h = H2.high;\n\t            var H2l = H2.low;\n\t            var H3h = H3.high;\n\t            var H3l = H3.low;\n\t            var H4h = H4.high;\n\t            var H4l = H4.low;\n\t            var H5h = H5.high;\n\t            var H5l = H5.low;\n\t            var H6h = H6.high;\n\t            var H6l = H6.low;\n\t            var H7h = H7.high;\n\t            var H7l = H7.low;\n\n\t            // Working variables\n\t            var ah = H0h;\n\t            var al = H0l;\n\t            var bh = H1h;\n\t            var bl = H1l;\n\t            var ch = H2h;\n\t            var cl = H2l;\n\t            var dh = H3h;\n\t            var dl = H3l;\n\t            var eh = H4h;\n\t            var el = H4l;\n\t            var fh = H5h;\n\t            var fl = H5l;\n\t            var gh = H6h;\n\t            var gl = H6l;\n\t            var hh = H7h;\n\t            var hl = H7l;\n\n\t            // Rounds\n\t            for (var i = 0; i < 80; i++) {\n\t                var Wil;\n\t                var Wih;\n\n\t                // Shortcut\n\t                var Wi = W[i];\n\n\t                // Extend message\n\t                if (i < 16) {\n\t                    Wih = Wi.high = M[offset + i * 2]     | 0;\n\t                    Wil = Wi.low  = M[offset + i * 2 + 1] | 0;\n\t                } else {\n\t                    // Gamma0\n\t                    var gamma0x  = W[i - 15];\n\t                    var gamma0xh = gamma0x.high;\n\t                    var gamma0xl = gamma0x.low;\n\t                    var gamma0h  = ((gamma0xh >>> 1) | (gamma0xl << 31)) ^ ((gamma0xh >>> 8) | (gamma0xl << 24)) ^ (gamma0xh >>> 7);\n\t                    var gamma0l  = ((gamma0xl >>> 1) | (gamma0xh << 31)) ^ ((gamma0xl >>> 8) | (gamma0xh << 24)) ^ ((gamma0xl >>> 7) | (gamma0xh << 25));\n\n\t                    // Gamma1\n\t                    var gamma1x  = W[i - 2];\n\t                    var gamma1xh = gamma1x.high;\n\t                    var gamma1xl = gamma1x.low;\n\t                    var gamma1h  = ((gamma1xh >>> 19) | (gamma1xl << 13)) ^ ((gamma1xh << 3) | (gamma1xl >>> 29)) ^ (gamma1xh >>> 6);\n\t                    var gamma1l  = ((gamma1xl >>> 19) | (gamma1xh << 13)) ^ ((gamma1xl << 3) | (gamma1xh >>> 29)) ^ ((gamma1xl >>> 6) | (gamma1xh << 26));\n\n\t                    // W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16]\n\t                    var Wi7  = W[i - 7];\n\t                    var Wi7h = Wi7.high;\n\t                    var Wi7l = Wi7.low;\n\n\t                    var Wi16  = W[i - 16];\n\t                    var Wi16h = Wi16.high;\n\t                    var Wi16l = Wi16.low;\n\n\t                    Wil = gamma0l + Wi7l;\n\t                    Wih = gamma0h + Wi7h + ((Wil >>> 0) < (gamma0l >>> 0) ? 1 : 0);\n\t                    Wil = Wil + gamma1l;\n\t                    Wih = Wih + gamma1h + ((Wil >>> 0) < (gamma1l >>> 0) ? 1 : 0);\n\t                    Wil = Wil + Wi16l;\n\t                    Wih = Wih + Wi16h + ((Wil >>> 0) < (Wi16l >>> 0) ? 1 : 0);\n\n\t                    Wi.high = Wih;\n\t                    Wi.low  = Wil;\n\t                }\n\n\t                var chh  = (eh & fh) ^ (~eh & gh);\n\t                var chl  = (el & fl) ^ (~el & gl);\n\t                var majh = (ah & bh) ^ (ah & ch) ^ (bh & ch);\n\t                var majl = (al & bl) ^ (al & cl) ^ (bl & cl);\n\n\t                var sigma0h = ((ah >>> 28) | (al << 4))  ^ ((ah << 30)  | (al >>> 2)) ^ ((ah << 25) | (al >>> 7));\n\t                var sigma0l = ((al >>> 28) | (ah << 4))  ^ ((al << 30)  | (ah >>> 2)) ^ ((al << 25) | (ah >>> 7));\n\t                var sigma1h = ((eh >>> 14) | (el << 18)) ^ ((eh >>> 18) | (el << 14)) ^ ((eh << 23) | (el >>> 9));\n\t                var sigma1l = ((el >>> 14) | (eh << 18)) ^ ((el >>> 18) | (eh << 14)) ^ ((el << 23) | (eh >>> 9));\n\n\t                // t1 = h + sigma1 + ch + K[i] + W[i]\n\t                var Ki  = K[i];\n\t                var Kih = Ki.high;\n\t                var Kil = Ki.low;\n\n\t                var t1l = hl + sigma1l;\n\t                var t1h = hh + sigma1h + ((t1l >>> 0) < (hl >>> 0) ? 1 : 0);\n\t                var t1l = t1l + chl;\n\t                var t1h = t1h + chh + ((t1l >>> 0) < (chl >>> 0) ? 1 : 0);\n\t                var t1l = t1l + Kil;\n\t                var t1h = t1h + Kih + ((t1l >>> 0) < (Kil >>> 0) ? 1 : 0);\n\t                var t1l = t1l + Wil;\n\t                var t1h = t1h + Wih + ((t1l >>> 0) < (Wil >>> 0) ? 1 : 0);\n\n\t                // t2 = sigma0 + maj\n\t                var t2l = sigma0l + majl;\n\t                var t2h = sigma0h + majh + ((t2l >>> 0) < (sigma0l >>> 0) ? 1 : 0);\n\n\t                // Update working variables\n\t                hh = gh;\n\t                hl = gl;\n\t                gh = fh;\n\t                gl = fl;\n\t                fh = eh;\n\t                fl = el;\n\t                el = (dl + t1l) | 0;\n\t                eh = (dh + t1h + ((el >>> 0) < (dl >>> 0) ? 1 : 0)) | 0;\n\t                dh = ch;\n\t                dl = cl;\n\t                ch = bh;\n\t                cl = bl;\n\t                bh = ah;\n\t                bl = al;\n\t                al = (t1l + t2l) | 0;\n\t                ah = (t1h + t2h + ((al >>> 0) < (t1l >>> 0) ? 1 : 0)) | 0;\n\t            }\n\n\t            // Intermediate hash value\n\t            H0l = H0.low  = (H0l + al);\n\t            H0.high = (H0h + ah + ((H0l >>> 0) < (al >>> 0) ? 1 : 0));\n\t            H1l = H1.low  = (H1l + bl);\n\t            H1.high = (H1h + bh + ((H1l >>> 0) < (bl >>> 0) ? 1 : 0));\n\t            H2l = H2.low  = (H2l + cl);\n\t            H2.high = (H2h + ch + ((H2l >>> 0) < (cl >>> 0) ? 1 : 0));\n\t            H3l = H3.low  = (H3l + dl);\n\t            H3.high = (H3h + dh + ((H3l >>> 0) < (dl >>> 0) ? 1 : 0));\n\t            H4l = H4.low  = (H4l + el);\n\t            H4.high = (H4h + eh + ((H4l >>> 0) < (el >>> 0) ? 1 : 0));\n\t            H5l = H5.low  = (H5l + fl);\n\t            H5.high = (H5h + fh + ((H5l >>> 0) < (fl >>> 0) ? 1 : 0));\n\t            H6l = H6.low  = (H6l + gl);\n\t            H6.high = (H6h + gh + ((H6l >>> 0) < (gl >>> 0) ? 1 : 0));\n\t            H7l = H7.low  = (H7l + hl);\n\t            H7.high = (H7h + hh + ((H7l >>> 0) < (hl >>> 0) ? 1 : 0));\n\t        },\n\n\t        _doFinalize: function () {\n\t            // Shortcuts\n\t            var data = this._data;\n\t            var dataWords = data.words;\n\n\t            var nBitsTotal = this._nDataBytes * 8;\n\t            var nBitsLeft = data.sigBytes * 8;\n\n\t            // Add padding\n\t            dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);\n\t            dataWords[(((nBitsLeft + 128) >>> 10) << 5) + 30] = Math.floor(nBitsTotal / 0x100000000);\n\t            dataWords[(((nBitsLeft + 128) >>> 10) << 5) + 31] = nBitsTotal;\n\t            data.sigBytes = dataWords.length * 4;\n\n\t            // Hash final blocks\n\t            this._process();\n\n\t            // Convert hash to 32-bit word array before returning\n\t            var hash = this._hash.toX32();\n\n\t            // Return final computed hash\n\t            return hash;\n\t        },\n\n\t        clone: function () {\n\t            var clone = Hasher.clone.call(this);\n\t            clone._hash = this._hash.clone();\n\n\t            return clone;\n\t        },\n\n\t        blockSize: 1024/32\n\t    });\n\n\t    /**\n\t     * Shortcut function to the hasher's object interface.\n\t     *\n\t     * @param {WordArray|string} message The message to hash.\n\t     *\n\t     * @return {WordArray} The hash.\n\t     *\n\t     * @static\n\t     *\n\t     * @example\n\t     *\n\t     *     var hash = CryptoJS.SHA512('message');\n\t     *     var hash = CryptoJS.SHA512(wordArray);\n\t     */\n\t    C.SHA512 = Hasher._createHelper(SHA512);\n\n\t    /**\n\t     * Shortcut function to the HMAC's object interface.\n\t     *\n\t     * @param {WordArray|string} message The message to hash.\n\t     * @param {WordArray|string} key The secret key.\n\t     *\n\t     * @return {WordArray} The HMAC.\n\t     *\n\t     * @static\n\t     *\n\t     * @example\n\t     *\n\t     *     var hmac = CryptoJS.HmacSHA512(message, key);\n\t     */\n\t    C.HmacSHA512 = Hasher._createHmacHelper(SHA512);\n\t}());\n\n\n\t(function () {\n\t    // Shortcuts\n\t    var C = CryptoJS;\n\t    var C_x64 = C.x64;\n\t    var X64Word = C_x64.Word;\n\t    var X64WordArray = C_x64.WordArray;\n\t    var C_algo = C.algo;\n\t    var SHA512 = C_algo.SHA512;\n\n\t    /**\n\t     * SHA-384 hash algorithm.\n\t     */\n\t    var SHA384 = C_algo.SHA384 = SHA512.extend({\n\t        _doReset: function () {\n\t            this._hash = new X64WordArray.init([\n\t                new X64Word.init(0xcbbb9d5d, 0xc1059ed8), new X64Word.init(0x629a292a, 0x367cd507),\n\t                new X64Word.init(0x9159015a, 0x3070dd17), new X64Word.init(0x152fecd8, 0xf70e5939),\n\t                new X64Word.init(0x67332667, 0xffc00b31), new X64Word.init(0x8eb44a87, 0x68581511),\n\t                new X64Word.init(0xdb0c2e0d, 0x64f98fa7), new X64Word.init(0x47b5481d, 0xbefa4fa4)\n\t            ]);\n\t        },\n\n\t        _doFinalize: function () {\n\t            var hash = SHA512._doFinalize.call(this);\n\n\t            hash.sigBytes -= 16;\n\n\t            return hash;\n\t        }\n\t    });\n\n\t    /**\n\t     * Shortcut function to the hasher's object interface.\n\t     *\n\t     * @param {WordArray|string} message The message to hash.\n\t     *\n\t     * @return {WordArray} The hash.\n\t     *\n\t     * @static\n\t     *\n\t     * @example\n\t     *\n\t     *     var hash = CryptoJS.SHA384('message');\n\t     *     var hash = CryptoJS.SHA384(wordArray);\n\t     */\n\t    C.SHA384 = SHA512._createHelper(SHA384);\n\n\t    /**\n\t     * Shortcut function to the HMAC's object interface.\n\t     *\n\t     * @param {WordArray|string} message The message to hash.\n\t     * @param {WordArray|string} key The secret key.\n\t     *\n\t     * @return {WordArray} The HMAC.\n\t     *\n\t     * @static\n\t     *\n\t     * @example\n\t     *\n\t     *     var hmac = CryptoJS.HmacSHA384(message, key);\n\t     */\n\t    C.HmacSHA384 = SHA512._createHmacHelper(SHA384);\n\t}());\n\n\n\t/**\n\t * Cipher core components.\n\t */\n\tCryptoJS.lib.Cipher || (function (undefined) {\n\t    // Shortcuts\n\t    var C = CryptoJS;\n\t    var C_lib = C.lib;\n\t    var Base = C_lib.Base;\n\t    var WordArray = C_lib.WordArray;\n\t    var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm;\n\t    var C_enc = C.enc;\n\t    var Utf8 = C_enc.Utf8;\n\t    var Base64 = C_enc.Base64;\n\t    var C_algo = C.algo;\n\t    var EvpKDF = C_algo.EvpKDF;\n\n\t    /**\n\t     * Abstract base cipher template.\n\t     *\n\t     * @property {number} keySize This cipher's key size. Default: 4 (128 bits)\n\t     * @property {number} ivSize This cipher's IV size. Default: 4 (128 bits)\n\t     * @property {number} _ENC_XFORM_MODE A constant representing encryption mode.\n\t     * @property {number} _DEC_XFORM_MODE A constant representing decryption mode.\n\t     */\n\t    var Cipher = C_lib.Cipher = BufferedBlockAlgorithm.extend({\n\t        /**\n\t         * Configuration options.\n\t         *\n\t         * @property {WordArray} iv The IV to use for this operation.\n\t         */\n\t        cfg: Base.extend(),\n\n\t        /**\n\t         * Creates this cipher in encryption mode.\n\t         *\n\t         * @param {WordArray} key The key.\n\t         * @param {Object} cfg (Optional) The configuration options to use for this operation.\n\t         *\n\t         * @return {Cipher} A cipher instance.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var cipher = CryptoJS.algo.AES.createEncryptor(keyWordArray, { iv: ivWordArray });\n\t         */\n\t        createEncryptor: function (key, cfg) {\n\t            return this.create(this._ENC_XFORM_MODE, key, cfg);\n\t        },\n\n\t        /**\n\t         * Creates this cipher in decryption mode.\n\t         *\n\t         * @param {WordArray} key The key.\n\t         * @param {Object} cfg (Optional) The configuration options to use for this operation.\n\t         *\n\t         * @return {Cipher} A cipher instance.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var cipher = CryptoJS.algo.AES.createDecryptor(keyWordArray, { iv: ivWordArray });\n\t         */\n\t        createDecryptor: function (key, cfg) {\n\t            return this.create(this._DEC_XFORM_MODE, key, cfg);\n\t        },\n\n\t        /**\n\t         * Initializes a newly created cipher.\n\t         *\n\t         * @param {number} xformMode Either the encryption or decryption transormation mode constant.\n\t         * @param {WordArray} key The key.\n\t         * @param {Object} cfg (Optional) The configuration options to use for this operation.\n\t         *\n\t         * @example\n\t         *\n\t         *     var cipher = CryptoJS.algo.AES.create(CryptoJS.algo.AES._ENC_XFORM_MODE, keyWordArray, { iv: ivWordArray });\n\t         */\n\t        init: function (xformMode, key, cfg) {\n\t            // Apply config defaults\n\t            this.cfg = this.cfg.extend(cfg);\n\n\t            // Store transform mode and key\n\t            this._xformMode = xformMode;\n\t            this._key = key;\n\n\t            // Set initial values\n\t            this.reset();\n\t        },\n\n\t        /**\n\t         * Resets this cipher to its initial state.\n\t         *\n\t         * @example\n\t         *\n\t         *     cipher.reset();\n\t         */\n\t        reset: function () {\n\t            // Reset data buffer\n\t            BufferedBlockAlgorithm.reset.call(this);\n\n\t            // Perform concrete-cipher logic\n\t            this._doReset();\n\t        },\n\n\t        /**\n\t         * Adds data to be encrypted or decrypted.\n\t         *\n\t         * @param {WordArray|string} dataUpdate The data to encrypt or decrypt.\n\t         *\n\t         * @return {WordArray} The data after processing.\n\t         *\n\t         * @example\n\t         *\n\t         *     var encrypted = cipher.process('data');\n\t         *     var encrypted = cipher.process(wordArray);\n\t         */\n\t        process: function (dataUpdate) {\n\t            // Append\n\t            this._append(dataUpdate);\n\n\t            // Process available blocks\n\t            return this._process();\n\t        },\n\n\t        /**\n\t         * Finalizes the encryption or decryption process.\n\t         * Note that the finalize operation is effectively a destructive, read-once operation.\n\t         *\n\t         * @param {WordArray|string} dataUpdate The final data to encrypt or decrypt.\n\t         *\n\t         * @return {WordArray} The data after final processing.\n\t         *\n\t         * @example\n\t         *\n\t         *     var encrypted = cipher.finalize();\n\t         *     var encrypted = cipher.finalize('data');\n\t         *     var encrypted = cipher.finalize(wordArray);\n\t         */\n\t        finalize: function (dataUpdate) {\n\t            // Final data update\n\t            if (dataUpdate) {\n\t                this._append(dataUpdate);\n\t            }\n\n\t            // Perform concrete-cipher logic\n\t            var finalProcessedData = this._doFinalize();\n\n\t            return finalProcessedData;\n\t        },\n\n\t        keySize: 128/32,\n\n\t        ivSize: 128/32,\n\n\t        _ENC_XFORM_MODE: 1,\n\n\t        _DEC_XFORM_MODE: 2,\n\n\t        /**\n\t         * Creates shortcut functions to a cipher's object interface.\n\t         *\n\t         * @param {Cipher} cipher The cipher to create a helper for.\n\t         *\n\t         * @return {Object} An object with encrypt and decrypt shortcut functions.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var AES = CryptoJS.lib.Cipher._createHelper(CryptoJS.algo.AES);\n\t         */\n\t        _createHelper: (function () {\n\t            function selectCipherStrategy(key) {\n\t                if (typeof key == 'string') {\n\t                    return PasswordBasedCipher;\n\t                } else {\n\t                    return SerializableCipher;\n\t                }\n\t            }\n\n\t            return function (cipher) {\n\t                return {\n\t                    encrypt: function (message, key, cfg) {\n\t                        return selectCipherStrategy(key).encrypt(cipher, message, key, cfg);\n\t                    },\n\n\t                    decrypt: function (ciphertext, key, cfg) {\n\t                        return selectCipherStrategy(key).decrypt(cipher, ciphertext, key, cfg);\n\t                    }\n\t                };\n\t            };\n\t        }())\n\t    });\n\n\t    /**\n\t     * Abstract base stream cipher template.\n\t     *\n\t     * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 1 (32 bits)\n\t     */\n\t    var StreamCipher = C_lib.StreamCipher = Cipher.extend({\n\t        _doFinalize: function () {\n\t            // Process partial blocks\n\t            var finalProcessedBlocks = this._process(!!'flush');\n\n\t            return finalProcessedBlocks;\n\t        },\n\n\t        blockSize: 1\n\t    });\n\n\t    /**\n\t     * Mode namespace.\n\t     */\n\t    var C_mode = C.mode = {};\n\n\t    /**\n\t     * Abstract base block cipher mode template.\n\t     */\n\t    var BlockCipherMode = C_lib.BlockCipherMode = Base.extend({\n\t        /**\n\t         * Creates this mode for encryption.\n\t         *\n\t         * @param {Cipher} cipher A block cipher instance.\n\t         * @param {Array} iv The IV words.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var mode = CryptoJS.mode.CBC.createEncryptor(cipher, iv.words);\n\t         */\n\t        createEncryptor: function (cipher, iv) {\n\t            return this.Encryptor.create(cipher, iv);\n\t        },\n\n\t        /**\n\t         * Creates this mode for decryption.\n\t         *\n\t         * @param {Cipher} cipher A block cipher instance.\n\t         * @param {Array} iv The IV words.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var mode = CryptoJS.mode.CBC.createDecryptor(cipher, iv.words);\n\t         */\n\t        createDecryptor: function (cipher, iv) {\n\t            return this.Decryptor.create(cipher, iv);\n\t        },\n\n\t        /**\n\t         * Initializes a newly created mode.\n\t         *\n\t         * @param {Cipher} cipher A block cipher instance.\n\t         * @param {Array} iv The IV words.\n\t         *\n\t         * @example\n\t         *\n\t         *     var mode = CryptoJS.mode.CBC.Encryptor.create(cipher, iv.words);\n\t         */\n\t        init: function (cipher, iv) {\n\t            this._cipher = cipher;\n\t            this._iv = iv;\n\t        }\n\t    });\n\n\t    /**\n\t     * Cipher Block Chaining mode.\n\t     */\n\t    var CBC = C_mode.CBC = (function () {\n\t        /**\n\t         * Abstract base CBC mode.\n\t         */\n\t        var CBC = BlockCipherMode.extend();\n\n\t        /**\n\t         * CBC encryptor.\n\t         */\n\t        CBC.Encryptor = CBC.extend({\n\t            /**\n\t             * Processes the data block at offset.\n\t             *\n\t             * @param {Array} words The data words to operate on.\n\t             * @param {number} offset The offset where the block starts.\n\t             *\n\t             * @example\n\t             *\n\t             *     mode.processBlock(data.words, offset);\n\t             */\n\t            processBlock: function (words, offset) {\n\t                // Shortcuts\n\t                var cipher = this._cipher;\n\t                var blockSize = cipher.blockSize;\n\n\t                // XOR and encrypt\n\t                xorBlock.call(this, words, offset, blockSize);\n\t                cipher.encryptBlock(words, offset);\n\n\t                // Remember this block to use with next block\n\t                this._prevBlock = words.slice(offset, offset + blockSize);\n\t            }\n\t        });\n\n\t        /**\n\t         * CBC decryptor.\n\t         */\n\t        CBC.Decryptor = CBC.extend({\n\t            /**\n\t             * Processes the data block at offset.\n\t             *\n\t             * @param {Array} words The data words to operate on.\n\t             * @param {number} offset The offset where the block starts.\n\t             *\n\t             * @example\n\t             *\n\t             *     mode.processBlock(data.words, offset);\n\t             */\n\t            processBlock: function (words, offset) {\n\t                // Shortcuts\n\t                var cipher = this._cipher;\n\t                var blockSize = cipher.blockSize;\n\n\t                // Remember this block to use with next block\n\t                var thisBlock = words.slice(offset, offset + blockSize);\n\n\t                // Decrypt and XOR\n\t                cipher.decryptBlock(words, offset);\n\t                xorBlock.call(this, words, offset, blockSize);\n\n\t                // This block becomes the previous block\n\t                this._prevBlock = thisBlock;\n\t            }\n\t        });\n\n\t        function xorBlock(words, offset, blockSize) {\n\t            var block;\n\n\t            // Shortcut\n\t            var iv = this._iv;\n\n\t            // Choose mixing block\n\t            if (iv) {\n\t                block = iv;\n\n\t                // Remove IV for subsequent blocks\n\t                this._iv = undefined;\n\t            } else {\n\t                block = this._prevBlock;\n\t            }\n\n\t            // XOR blocks\n\t            for (var i = 0; i < blockSize; i++) {\n\t                words[offset + i] ^= block[i];\n\t            }\n\t        }\n\n\t        return CBC;\n\t    }());\n\n\t    /**\n\t     * Padding namespace.\n\t     */\n\t    var C_pad = C.pad = {};\n\n\t    /**\n\t     * PKCS #5/7 padding strategy.\n\t     */\n\t    var Pkcs7 = C_pad.Pkcs7 = {\n\t        /**\n\t         * Pads data using the algorithm defined in PKCS #5/7.\n\t         *\n\t         * @param {WordArray} data The data to pad.\n\t         * @param {number} blockSize The multiple that the data should be padded to.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     CryptoJS.pad.Pkcs7.pad(wordArray, 4);\n\t         */\n\t        pad: function (data, blockSize) {\n\t            // Shortcut\n\t            var blockSizeBytes = blockSize * 4;\n\n\t            // Count padding bytes\n\t            var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes;\n\n\t            // Create padding word\n\t            var paddingWord = (nPaddingBytes << 24) | (nPaddingBytes << 16) | (nPaddingBytes << 8) | nPaddingBytes;\n\n\t            // Create padding\n\t            var paddingWords = [];\n\t            for (var i = 0; i < nPaddingBytes; i += 4) {\n\t                paddingWords.push(paddingWord);\n\t            }\n\t            var padding = WordArray.create(paddingWords, nPaddingBytes);\n\n\t            // Add padding\n\t            data.concat(padding);\n\t        },\n\n\t        /**\n\t         * Unpads data that had been padded using the algorithm defined in PKCS #5/7.\n\t         *\n\t         * @param {WordArray} data The data to unpad.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     CryptoJS.pad.Pkcs7.unpad(wordArray);\n\t         */\n\t        unpad: function (data) {\n\t            // Get number of padding bytes from last byte\n\t            var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff;\n\n\t            // Remove padding\n\t            data.sigBytes -= nPaddingBytes;\n\t        }\n\t    };\n\n\t    /**\n\t     * Abstract base block cipher template.\n\t     *\n\t     * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 4 (128 bits)\n\t     */\n\t    var BlockCipher = C_lib.BlockCipher = Cipher.extend({\n\t        /**\n\t         * Configuration options.\n\t         *\n\t         * @property {Mode} mode The block mode to use. Default: CBC\n\t         * @property {Padding} padding The padding strategy to use. Default: Pkcs7\n\t         */\n\t        cfg: Cipher.cfg.extend({\n\t            mode: CBC,\n\t            padding: Pkcs7\n\t        }),\n\n\t        reset: function () {\n\t            var modeCreator;\n\n\t            // Reset cipher\n\t            Cipher.reset.call(this);\n\n\t            // Shortcuts\n\t            var cfg = this.cfg;\n\t            var iv = cfg.iv;\n\t            var mode = cfg.mode;\n\n\t            // Reset block mode\n\t            if (this._xformMode == this._ENC_XFORM_MODE) {\n\t                modeCreator = mode.createEncryptor;\n\t            } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ {\n\t                modeCreator = mode.createDecryptor;\n\t                // Keep at least one block in the buffer for unpadding\n\t                this._minBufferSize = 1;\n\t            }\n\n\t            if (this._mode && this._mode.__creator == modeCreator) {\n\t                this._mode.init(this, iv && iv.words);\n\t            } else {\n\t                this._mode = modeCreator.call(mode, this, iv && iv.words);\n\t                this._mode.__creator = modeCreator;\n\t            }\n\t        },\n\n\t        _doProcessBlock: function (words, offset) {\n\t            this._mode.processBlock(words, offset);\n\t        },\n\n\t        _doFinalize: function () {\n\t            var finalProcessedBlocks;\n\n\t            // Shortcut\n\t            var padding = this.cfg.padding;\n\n\t            // Finalize\n\t            if (this._xformMode == this._ENC_XFORM_MODE) {\n\t                // Pad data\n\t                padding.pad(this._data, this.blockSize);\n\n\t                // Process final blocks\n\t                finalProcessedBlocks = this._process(!!'flush');\n\t            } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ {\n\t                // Process final blocks\n\t                finalProcessedBlocks = this._process(!!'flush');\n\n\t                // Unpad data\n\t                padding.unpad(finalProcessedBlocks);\n\t            }\n\n\t            return finalProcessedBlocks;\n\t        },\n\n\t        blockSize: 128/32\n\t    });\n\n\t    /**\n\t     * A collection of cipher parameters.\n\t     *\n\t     * @property {WordArray} ciphertext The raw ciphertext.\n\t     * @property {WordArray} key The key to this ciphertext.\n\t     * @property {WordArray} iv The IV used in the ciphering operation.\n\t     * @property {WordArray} salt The salt used with a key derivation function.\n\t     * @property {Cipher} algorithm The cipher algorithm.\n\t     * @property {Mode} mode The block mode used in the ciphering operation.\n\t     * @property {Padding} padding The padding scheme used in the ciphering operation.\n\t     * @property {number} blockSize The block size of the cipher.\n\t     * @property {Format} formatter The default formatting strategy to convert this cipher params object to a string.\n\t     */\n\t    var CipherParams = C_lib.CipherParams = Base.extend({\n\t        /**\n\t         * Initializes a newly created cipher params object.\n\t         *\n\t         * @param {Object} cipherParams An object with any of the possible cipher parameters.\n\t         *\n\t         * @example\n\t         *\n\t         *     var cipherParams = CryptoJS.lib.CipherParams.create({\n\t         *         ciphertext: ciphertextWordArray,\n\t         *         key: keyWordArray,\n\t         *         iv: ivWordArray,\n\t         *         salt: saltWordArray,\n\t         *         algorithm: CryptoJS.algo.AES,\n\t         *         mode: CryptoJS.mode.CBC,\n\t         *         padding: CryptoJS.pad.PKCS7,\n\t         *         blockSize: 4,\n\t         *         formatter: CryptoJS.format.OpenSSL\n\t         *     });\n\t         */\n\t        init: function (cipherParams) {\n\t            this.mixIn(cipherParams);\n\t        },\n\n\t        /**\n\t         * Converts this cipher params object to a string.\n\t         *\n\t         * @param {Format} formatter (Optional) The formatting strategy to use.\n\t         *\n\t         * @return {string} The stringified cipher params.\n\t         *\n\t         * @throws Error If neither the formatter nor the default formatter is set.\n\t         *\n\t         * @example\n\t         *\n\t         *     var string = cipherParams + '';\n\t         *     var string = cipherParams.toString();\n\t         *     var string = cipherParams.toString(CryptoJS.format.OpenSSL);\n\t         */\n\t        toString: function (formatter) {\n\t            return (formatter || this.formatter).stringify(this);\n\t        }\n\t    });\n\n\t    /**\n\t     * Format namespace.\n\t     */\n\t    var C_format = C.format = {};\n\n\t    /**\n\t     * OpenSSL formatting strategy.\n\t     */\n\t    var OpenSSLFormatter = C_format.OpenSSL = {\n\t        /**\n\t         * Converts a cipher params object to an OpenSSL-compatible string.\n\t         *\n\t         * @param {CipherParams} cipherParams The cipher params object.\n\t         *\n\t         * @return {string} The OpenSSL-compatible string.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var openSSLString = CryptoJS.format.OpenSSL.stringify(cipherParams);\n\t         */\n\t        stringify: function (cipherParams) {\n\t            var wordArray;\n\n\t            // Shortcuts\n\t            var ciphertext = cipherParams.ciphertext;\n\t            var salt = cipherParams.salt;\n\n\t            // Format\n\t            if (salt) {\n\t                wordArray = WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext);\n\t            } else {\n\t                wordArray = ciphertext;\n\t            }\n\n\t            return wordArray.toString(Base64);\n\t        },\n\n\t        /**\n\t         * Converts an OpenSSL-compatible string to a cipher params object.\n\t         *\n\t         * @param {string} openSSLStr The OpenSSL-compatible string.\n\t         *\n\t         * @return {CipherParams} The cipher params object.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var cipherParams = CryptoJS.format.OpenSSL.parse(openSSLString);\n\t         */\n\t        parse: function (openSSLStr) {\n\t            var salt;\n\n\t            // Parse base64\n\t            var ciphertext = Base64.parse(openSSLStr);\n\n\t            // Shortcut\n\t            var ciphertextWords = ciphertext.words;\n\n\t            // Test for salt\n\t            if (ciphertextWords[0] == 0x53616c74 && ciphertextWords[1] == 0x65645f5f) {\n\t                // Extract salt\n\t                salt = WordArray.create(ciphertextWords.slice(2, 4));\n\n\t                // Remove salt from ciphertext\n\t                ciphertextWords.splice(0, 4);\n\t                ciphertext.sigBytes -= 16;\n\t            }\n\n\t            return CipherParams.create({ ciphertext: ciphertext, salt: salt });\n\t        }\n\t    };\n\n\t    /**\n\t     * A cipher wrapper that returns ciphertext as a serializable cipher params object.\n\t     */\n\t    var SerializableCipher = C_lib.SerializableCipher = Base.extend({\n\t        /**\n\t         * Configuration options.\n\t         *\n\t         * @property {Formatter} format The formatting strategy to convert cipher param objects to and from a string. Default: OpenSSL\n\t         */\n\t        cfg: Base.extend({\n\t            format: OpenSSLFormatter\n\t        }),\n\n\t        /**\n\t         * Encrypts a message.\n\t         *\n\t         * @param {Cipher} cipher The cipher algorithm to use.\n\t         * @param {WordArray|string} message The message to encrypt.\n\t         * @param {WordArray} key The key.\n\t         * @param {Object} cfg (Optional) The configuration options to use for this operation.\n\t         *\n\t         * @return {CipherParams} A cipher params object.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key);\n\t         *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv });\n\t         *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv, format: CryptoJS.format.OpenSSL });\n\t         */\n\t        encrypt: function (cipher, message, key, cfg) {\n\t            // Apply config defaults\n\t            cfg = this.cfg.extend(cfg);\n\n\t            // Encrypt\n\t            var encryptor = cipher.createEncryptor(key, cfg);\n\t            var ciphertext = encryptor.finalize(message);\n\n\t            // Shortcut\n\t            var cipherCfg = encryptor.cfg;\n\n\t            // Create and return serializable cipher params\n\t            return CipherParams.create({\n\t                ciphertext: ciphertext,\n\t                key: key,\n\t                iv: cipherCfg.iv,\n\t                algorithm: cipher,\n\t                mode: cipherCfg.mode,\n\t                padding: cipherCfg.padding,\n\t                blockSize: cipher.blockSize,\n\t                formatter: cfg.format\n\t            });\n\t        },\n\n\t        /**\n\t         * Decrypts serialized ciphertext.\n\t         *\n\t         * @param {Cipher} cipher The cipher algorithm to use.\n\t         * @param {CipherParams|string} ciphertext The ciphertext to decrypt.\n\t         * @param {WordArray} key The key.\n\t         * @param {Object} cfg (Optional) The configuration options to use for this operation.\n\t         *\n\t         * @return {WordArray} The plaintext.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, key, { iv: iv, format: CryptoJS.format.OpenSSL });\n\t         *     var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, key, { iv: iv, format: CryptoJS.format.OpenSSL });\n\t         */\n\t        decrypt: function (cipher, ciphertext, key, cfg) {\n\t            // Apply config defaults\n\t            cfg = this.cfg.extend(cfg);\n\n\t            // Convert string to CipherParams\n\t            ciphertext = this._parse(ciphertext, cfg.format);\n\n\t            // Decrypt\n\t            var plaintext = cipher.createDecryptor(key, cfg).finalize(ciphertext.ciphertext);\n\n\t            return plaintext;\n\t        },\n\n\t        /**\n\t         * Converts serialized ciphertext to CipherParams,\n\t         * else assumed CipherParams already and returns ciphertext unchanged.\n\t         *\n\t         * @param {CipherParams|string} ciphertext The ciphertext.\n\t         * @param {Formatter} format The formatting strategy to use to parse serialized ciphertext.\n\t         *\n\t         * @return {CipherParams} The unserialized ciphertext.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var ciphertextParams = CryptoJS.lib.SerializableCipher._parse(ciphertextStringOrParams, format);\n\t         */\n\t        _parse: function (ciphertext, format) {\n\t            if (typeof ciphertext == 'string') {\n\t                return format.parse(ciphertext, this);\n\t            } else {\n\t                return ciphertext;\n\t            }\n\t        }\n\t    });\n\n\t    /**\n\t     * Key derivation function namespace.\n\t     */\n\t    var C_kdf = C.kdf = {};\n\n\t    /**\n\t     * OpenSSL key derivation function.\n\t     */\n\t    var OpenSSLKdf = C_kdf.OpenSSL = {\n\t        /**\n\t         * Derives a key and IV from a password.\n\t         *\n\t         * @param {string} password The password to derive from.\n\t         * @param {number} keySize The size in words of the key to generate.\n\t         * @param {number} ivSize The size in words of the IV to generate.\n\t         * @param {WordArray|string} salt (Optional) A 64-bit salt to use. If omitted, a salt will be generated randomly.\n\t         *\n\t         * @return {CipherParams} A cipher params object with the key, IV, and salt.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32);\n\t         *     var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32, 'saltsalt');\n\t         */\n\t        execute: function (password, keySize, ivSize, salt) {\n\t            // Generate random salt\n\t            if (!salt) {\n\t                salt = WordArray.random(64/8);\n\t            }\n\n\t            // Derive key and IV\n\t            var key = EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt);\n\n\t            // Separate key and IV\n\t            var iv = WordArray.create(key.words.slice(keySize), ivSize * 4);\n\t            key.sigBytes = keySize * 4;\n\n\t            // Return params\n\t            return CipherParams.create({ key: key, iv: iv, salt: salt });\n\t        }\n\t    };\n\n\t    /**\n\t     * A serializable cipher wrapper that derives the key from a password,\n\t     * and returns ciphertext as a serializable cipher params object.\n\t     */\n\t    var PasswordBasedCipher = C_lib.PasswordBasedCipher = SerializableCipher.extend({\n\t        /**\n\t         * Configuration options.\n\t         *\n\t         * @property {KDF} kdf The key derivation function to use to generate a key and IV from a password. Default: OpenSSL\n\t         */\n\t        cfg: SerializableCipher.cfg.extend({\n\t            kdf: OpenSSLKdf\n\t        }),\n\n\t        /**\n\t         * Encrypts a message using a password.\n\t         *\n\t         * @param {Cipher} cipher The cipher algorithm to use.\n\t         * @param {WordArray|string} message The message to encrypt.\n\t         * @param {string} password The password.\n\t         * @param {Object} cfg (Optional) The configuration options to use for this operation.\n\t         *\n\t         * @return {CipherParams} A cipher params object.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password');\n\t         *     var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password', { format: CryptoJS.format.OpenSSL });\n\t         */\n\t        encrypt: function (cipher, message, password, cfg) {\n\t            // Apply config defaults\n\t            cfg = this.cfg.extend(cfg);\n\n\t            // Derive key and other params\n\t            var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize);\n\n\t            // Add IV to config\n\t            cfg.iv = derivedParams.iv;\n\n\t            // Encrypt\n\t            var ciphertext = SerializableCipher.encrypt.call(this, cipher, message, derivedParams.key, cfg);\n\n\t            // Mix in derived params\n\t            ciphertext.mixIn(derivedParams);\n\n\t            return ciphertext;\n\t        },\n\n\t        /**\n\t         * Decrypts serialized ciphertext using a password.\n\t         *\n\t         * @param {Cipher} cipher The cipher algorithm to use.\n\t         * @param {CipherParams|string} ciphertext The ciphertext to decrypt.\n\t         * @param {string} password The password.\n\t         * @param {Object} cfg (Optional) The configuration options to use for this operation.\n\t         *\n\t         * @return {WordArray} The plaintext.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, 'password', { format: CryptoJS.format.OpenSSL });\n\t         *     var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, 'password', { format: CryptoJS.format.OpenSSL });\n\t         */\n\t        decrypt: function (cipher, ciphertext, password, cfg) {\n\t            // Apply config defaults\n\t            cfg = this.cfg.extend(cfg);\n\n\t            // Convert string to CipherParams\n\t            ciphertext = this._parse(ciphertext, cfg.format);\n\n\t            // Derive key and other params\n\t            var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, ciphertext.salt);\n\n\t            // Add IV to config\n\t            cfg.iv = derivedParams.iv;\n\n\t            // Decrypt\n\t            var plaintext = SerializableCipher.decrypt.call(this, cipher, ciphertext, derivedParams.key, cfg);\n\n\t            return plaintext;\n\t        }\n\t    });\n\t}());\n\n\n\t/**\n\t * Cipher Feedback block mode.\n\t */\n\tCryptoJS.mode.CFB = (function () {\n\t    var CFB = CryptoJS.lib.BlockCipherMode.extend();\n\n\t    CFB.Encryptor = CFB.extend({\n\t        processBlock: function (words, offset) {\n\t            // Shortcuts\n\t            var cipher = this._cipher;\n\t            var blockSize = cipher.blockSize;\n\n\t            generateKeystreamAndEncrypt.call(this, words, offset, blockSize, cipher);\n\n\t            // Remember this block to use with next block\n\t            this._prevBlock = words.slice(offset, offset + blockSize);\n\t        }\n\t    });\n\n\t    CFB.Decryptor = CFB.extend({\n\t        processBlock: function (words, offset) {\n\t            // Shortcuts\n\t            var cipher = this._cipher;\n\t            var blockSize = cipher.blockSize;\n\n\t            // Remember this block to use with next block\n\t            var thisBlock = words.slice(offset, offset + blockSize);\n\n\t            generateKeystreamAndEncrypt.call(this, words, offset, blockSize, cipher);\n\n\t            // This block becomes the previous block\n\t            this._prevBlock = thisBlock;\n\t        }\n\t    });\n\n\t    function generateKeystreamAndEncrypt(words, offset, blockSize, cipher) {\n\t        var keystream;\n\n\t        // Shortcut\n\t        var iv = this._iv;\n\n\t        // Generate keystream\n\t        if (iv) {\n\t            keystream = iv.slice(0);\n\n\t            // Remove IV for subsequent blocks\n\t            this._iv = undefined;\n\t        } else {\n\t            keystream = this._prevBlock;\n\t        }\n\t        cipher.encryptBlock(keystream, 0);\n\n\t        // Encrypt\n\t        for (var i = 0; i < blockSize; i++) {\n\t            words[offset + i] ^= keystream[i];\n\t        }\n\t    }\n\n\t    return CFB;\n\t}());\n\n\n\t/**\n\t * Electronic Codebook block mode.\n\t */\n\tCryptoJS.mode.ECB = (function () {\n\t    var ECB = CryptoJS.lib.BlockCipherMode.extend();\n\n\t    ECB.Encryptor = ECB.extend({\n\t        processBlock: function (words, offset) {\n\t            this._cipher.encryptBlock(words, offset);\n\t        }\n\t    });\n\n\t    ECB.Decryptor = ECB.extend({\n\t        processBlock: function (words, offset) {\n\t            this._cipher.decryptBlock(words, offset);\n\t        }\n\t    });\n\n\t    return ECB;\n\t}());\n\n\n\t/**\n\t * ANSI X.923 padding strategy.\n\t */\n\tCryptoJS.pad.AnsiX923 = {\n\t    pad: function (data, blockSize) {\n\t        // Shortcuts\n\t        var dataSigBytes = data.sigBytes;\n\t        var blockSizeBytes = blockSize * 4;\n\n\t        // Count padding bytes\n\t        var nPaddingBytes = blockSizeBytes - dataSigBytes % blockSizeBytes;\n\n\t        // Compute last byte position\n\t        var lastBytePos = dataSigBytes + nPaddingBytes - 1;\n\n\t        // Pad\n\t        data.clamp();\n\t        data.words[lastBytePos >>> 2] |= nPaddingBytes << (24 - (lastBytePos % 4) * 8);\n\t        data.sigBytes += nPaddingBytes;\n\t    },\n\n\t    unpad: function (data) {\n\t        // Get number of padding bytes from last byte\n\t        var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff;\n\n\t        // Remove padding\n\t        data.sigBytes -= nPaddingBytes;\n\t    }\n\t};\n\n\n\t/**\n\t * ISO 10126 padding strategy.\n\t */\n\tCryptoJS.pad.Iso10126 = {\n\t    pad: function (data, blockSize) {\n\t        // Shortcut\n\t        var blockSizeBytes = blockSize * 4;\n\n\t        // Count padding bytes\n\t        var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes;\n\n\t        // Pad\n\t        data.concat(CryptoJS.lib.WordArray.random(nPaddingBytes - 1)).\n\t             concat(CryptoJS.lib.WordArray.create([nPaddingBytes << 24], 1));\n\t    },\n\n\t    unpad: function (data) {\n\t        // Get number of padding bytes from last byte\n\t        var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff;\n\n\t        // Remove padding\n\t        data.sigBytes -= nPaddingBytes;\n\t    }\n\t};\n\n\n\t/**\n\t * ISO/IEC 9797-1 Padding Method 2.\n\t */\n\tCryptoJS.pad.Iso97971 = {\n\t    pad: function (data, blockSize) {\n\t        // Add 0x80 byte\n\t        data.concat(CryptoJS.lib.WordArray.create([0x80000000], 1));\n\n\t        // Zero pad the rest\n\t        CryptoJS.pad.ZeroPadding.pad(data, blockSize);\n\t    },\n\n\t    unpad: function (data) {\n\t        // Remove zero padding\n\t        CryptoJS.pad.ZeroPadding.unpad(data);\n\n\t        // Remove one more byte -- the 0x80 byte\n\t        data.sigBytes--;\n\t    }\n\t};\n\n\n\t/**\n\t * Output Feedback block mode.\n\t */\n\tCryptoJS.mode.OFB = (function () {\n\t    var OFB = CryptoJS.lib.BlockCipherMode.extend();\n\n\t    var Encryptor = OFB.Encryptor = OFB.extend({\n\t        processBlock: function (words, offset) {\n\t            // Shortcuts\n\t            var cipher = this._cipher\n\t            var blockSize = cipher.blockSize;\n\t            var iv = this._iv;\n\t            var keystream = this._keystream;\n\n\t            // Generate keystream\n\t            if (iv) {\n\t                keystream = this._keystream = iv.slice(0);\n\n\t                // Remove IV for subsequent blocks\n\t                this._iv = undefined;\n\t            }\n\t            cipher.encryptBlock(keystream, 0);\n\n\t            // Encrypt\n\t            for (var i = 0; i < blockSize; i++) {\n\t                words[offset + i] ^= keystream[i];\n\t            }\n\t        }\n\t    });\n\n\t    OFB.Decryptor = Encryptor;\n\n\t    return OFB;\n\t}());\n\n\n\t/**\n\t * A noop padding strategy.\n\t */\n\tCryptoJS.pad.NoPadding = {\n\t    pad: function () {\n\t    },\n\n\t    unpad: function () {\n\t    }\n\t};\n\n\n\t(function (undefined) {\n\t    // Shortcuts\n\t    var C = CryptoJS;\n\t    var C_lib = C.lib;\n\t    var CipherParams = C_lib.CipherParams;\n\t    var C_enc = C.enc;\n\t    var Hex = C_enc.Hex;\n\t    var C_format = C.format;\n\n\t    var HexFormatter = C_format.Hex = {\n\t        /**\n\t         * Converts the ciphertext of a cipher params object to a hexadecimally encoded string.\n\t         *\n\t         * @param {CipherParams} cipherParams The cipher params object.\n\t         *\n\t         * @return {string} The hexadecimally encoded string.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var hexString = CryptoJS.format.Hex.stringify(cipherParams);\n\t         */\n\t        stringify: function (cipherParams) {\n\t            return cipherParams.ciphertext.toString(Hex);\n\t        },\n\n\t        /**\n\t         * Converts a hexadecimally encoded ciphertext string to a cipher params object.\n\t         *\n\t         * @param {string} input The hexadecimally encoded string.\n\t         *\n\t         * @return {CipherParams} The cipher params object.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var cipherParams = CryptoJS.format.Hex.parse(hexString);\n\t         */\n\t        parse: function (input) {\n\t            var ciphertext = Hex.parse(input);\n\t            return CipherParams.create({ ciphertext: ciphertext });\n\t        }\n\t    };\n\t}());\n\n\n\t(function () {\n\t    // Shortcuts\n\t    var C = CryptoJS;\n\t    var C_lib = C.lib;\n\t    var BlockCipher = C_lib.BlockCipher;\n\t    var C_algo = C.algo;\n\n\t    // Lookup tables\n\t    var SBOX = [];\n\t    var INV_SBOX = [];\n\t    var SUB_MIX_0 = [];\n\t    var SUB_MIX_1 = [];\n\t    var SUB_MIX_2 = [];\n\t    var SUB_MIX_3 = [];\n\t    var INV_SUB_MIX_0 = [];\n\t    var INV_SUB_MIX_1 = [];\n\t    var INV_SUB_MIX_2 = [];\n\t    var INV_SUB_MIX_3 = [];\n\n\t    // Compute lookup tables\n\t    (function () {\n\t        // Compute double table\n\t        var d = [];\n\t        for (var i = 0; i < 256; i++) {\n\t            if (i < 128) {\n\t                d[i] = i << 1;\n\t            } else {\n\t                d[i] = (i << 1) ^ 0x11b;\n\t            }\n\t        }\n\n\t        // Walk GF(2^8)\n\t        var x = 0;\n\t        var xi = 0;\n\t        for (var i = 0; i < 256; i++) {\n\t            // Compute sbox\n\t            var sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4);\n\t            sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63;\n\t            SBOX[x] = sx;\n\t            INV_SBOX[sx] = x;\n\n\t            // Compute multiplication\n\t            var x2 = d[x];\n\t            var x4 = d[x2];\n\t            var x8 = d[x4];\n\n\t            // Compute sub bytes, mix columns tables\n\t            var t = (d[sx] * 0x101) ^ (sx * 0x1010100);\n\t            SUB_MIX_0[x] = (t << 24) | (t >>> 8);\n\t            SUB_MIX_1[x] = (t << 16) | (t >>> 16);\n\t            SUB_MIX_2[x] = (t << 8)  | (t >>> 24);\n\t            SUB_MIX_3[x] = t;\n\n\t            // Compute inv sub bytes, inv mix columns tables\n\t            var t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100);\n\t            INV_SUB_MIX_0[sx] = (t << 24) | (t >>> 8);\n\t            INV_SUB_MIX_1[sx] = (t << 16) | (t >>> 16);\n\t            INV_SUB_MIX_2[sx] = (t << 8)  | (t >>> 24);\n\t            INV_SUB_MIX_3[sx] = t;\n\n\t            // Compute next counter\n\t            if (!x) {\n\t                x = xi = 1;\n\t            } else {\n\t                x = x2 ^ d[d[d[x8 ^ x2]]];\n\t                xi ^= d[d[xi]];\n\t            }\n\t        }\n\t    }());\n\n\t    // Precomputed Rcon lookup\n\t    var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];\n\n\t    /**\n\t     * AES block cipher algorithm.\n\t     */\n\t    var AES = C_algo.AES = BlockCipher.extend({\n\t        _doReset: function () {\n\t            var t;\n\n\t            // Skip reset of nRounds has been set before and key did not change\n\t            if (this._nRounds && this._keyPriorReset === this._key) {\n\t                return;\n\t            }\n\n\t            // Shortcuts\n\t            var key = this._keyPriorReset = this._key;\n\t            var keyWords = key.words;\n\t            var keySize = key.sigBytes / 4;\n\n\t            // Compute number of rounds\n\t            var nRounds = this._nRounds = keySize + 6;\n\n\t            // Compute number of key schedule rows\n\t            var ksRows = (nRounds + 1) * 4;\n\n\t            // Compute key schedule\n\t            var keySchedule = this._keySchedule = [];\n\t            for (var ksRow = 0; ksRow < ksRows; ksRow++) {\n\t                if (ksRow < keySize) {\n\t                    keySchedule[ksRow] = keyWords[ksRow];\n\t                } else {\n\t                    t = keySchedule[ksRow - 1];\n\n\t                    if (!(ksRow % keySize)) {\n\t                        // Rot word\n\t                        t = (t << 8) | (t >>> 24);\n\n\t                        // Sub word\n\t                        t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff];\n\n\t                        // Mix Rcon\n\t                        t ^= RCON[(ksRow / keySize) | 0] << 24;\n\t                    } else if (keySize > 6 && ksRow % keySize == 4) {\n\t                        // Sub word\n\t                        t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff];\n\t                    }\n\n\t                    keySchedule[ksRow] = keySchedule[ksRow - keySize] ^ t;\n\t                }\n\t            }\n\n\t            // Compute inv key schedule\n\t            var invKeySchedule = this._invKeySchedule = [];\n\t            for (var invKsRow = 0; invKsRow < ksRows; invKsRow++) {\n\t                var ksRow = ksRows - invKsRow;\n\n\t                if (invKsRow % 4) {\n\t                    var t = keySchedule[ksRow];\n\t                } else {\n\t                    var t = keySchedule[ksRow - 4];\n\t                }\n\n\t                if (invKsRow < 4 || ksRow <= 4) {\n\t                    invKeySchedule[invKsRow] = t;\n\t                } else {\n\t                    invKeySchedule[invKsRow] = INV_SUB_MIX_0[SBOX[t >>> 24]] ^ INV_SUB_MIX_1[SBOX[(t >>> 16) & 0xff]] ^\n\t                                               INV_SUB_MIX_2[SBOX[(t >>> 8) & 0xff]] ^ INV_SUB_MIX_3[SBOX[t & 0xff]];\n\t                }\n\t            }\n\t        },\n\n\t        encryptBlock: function (M, offset) {\n\t            this._doCryptBlock(M, offset, this._keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX);\n\t        },\n\n\t        decryptBlock: function (M, offset) {\n\t            // Swap 2nd and 4th rows\n\t            var t = M[offset + 1];\n\t            M[offset + 1] = M[offset + 3];\n\t            M[offset + 3] = t;\n\n\t            this._doCryptBlock(M, offset, this._invKeySchedule, INV_SUB_MIX_0, INV_SUB_MIX_1, INV_SUB_MIX_2, INV_SUB_MIX_3, INV_SBOX);\n\n\t            // Inv swap 2nd and 4th rows\n\t            var t = M[offset + 1];\n\t            M[offset + 1] = M[offset + 3];\n\t            M[offset + 3] = t;\n\t        },\n\n\t        _doCryptBlock: function (M, offset, keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX) {\n\t            // Shortcut\n\t            var nRounds = this._nRounds;\n\n\t            // Get input, add round key\n\t            var s0 = M[offset]     ^ keySchedule[0];\n\t            var s1 = M[offset + 1] ^ keySchedule[1];\n\t            var s2 = M[offset + 2] ^ keySchedule[2];\n\t            var s3 = M[offset + 3] ^ keySchedule[3];\n\n\t            // Key schedule row counter\n\t            var ksRow = 4;\n\n\t            // Rounds\n\t            for (var round = 1; round < nRounds; round++) {\n\t                // Shift rows, sub bytes, mix columns, add round key\n\t                var t0 = SUB_MIX_0[s0 >>> 24] ^ SUB_MIX_1[(s1 >>> 16) & 0xff] ^ SUB_MIX_2[(s2 >>> 8) & 0xff] ^ SUB_MIX_3[s3 & 0xff] ^ keySchedule[ksRow++];\n\t                var t1 = SUB_MIX_0[s1 >>> 24] ^ SUB_MIX_1[(s2 >>> 16) & 0xff] ^ SUB_MIX_2[(s3 >>> 8) & 0xff] ^ SUB_MIX_3[s0 & 0xff] ^ keySchedule[ksRow++];\n\t                var t2 = SUB_MIX_0[s2 >>> 24] ^ SUB_MIX_1[(s3 >>> 16) & 0xff] ^ SUB_MIX_2[(s0 >>> 8) & 0xff] ^ SUB_MIX_3[s1 & 0xff] ^ keySchedule[ksRow++];\n\t                var t3 = SUB_MIX_0[s3 >>> 24] ^ SUB_MIX_1[(s0 >>> 16) & 0xff] ^ SUB_MIX_2[(s1 >>> 8) & 0xff] ^ SUB_MIX_3[s2 & 0xff] ^ keySchedule[ksRow++];\n\n\t                // Update state\n\t                s0 = t0;\n\t                s1 = t1;\n\t                s2 = t2;\n\t                s3 = t3;\n\t            }\n\n\t            // Shift rows, sub bytes, add round key\n\t            var t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) | (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++];\n\t            var t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) | (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++];\n\t            var t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) | (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++];\n\t            var t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) | (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++];\n\n\t            // Set output\n\t            M[offset]     = t0;\n\t            M[offset + 1] = t1;\n\t            M[offset + 2] = t2;\n\t            M[offset + 3] = t3;\n\t        },\n\n\t        keySize: 256/32\n\t    });\n\n\t    /**\n\t     * Shortcut functions to the cipher's object interface.\n\t     *\n\t     * @example\n\t     *\n\t     *     var ciphertext = CryptoJS.AES.encrypt(message, key, cfg);\n\t     *     var plaintext  = CryptoJS.AES.decrypt(ciphertext, key, cfg);\n\t     */\n\t    C.AES = BlockCipher._createHelper(AES);\n\t}());\n\n\n\t(function () {\n\t    // Shortcuts\n\t    var C = CryptoJS;\n\t    var C_lib = C.lib;\n\t    var WordArray = C_lib.WordArray;\n\t    var BlockCipher = C_lib.BlockCipher;\n\t    var C_algo = C.algo;\n\n\t    // Permuted Choice 1 constants\n\t    var PC1 = [\n\t        57, 49, 41, 33, 25, 17, 9,  1,\n\t        58, 50, 42, 34, 26, 18, 10, 2,\n\t        59, 51, 43, 35, 27, 19, 11, 3,\n\t        60, 52, 44, 36, 63, 55, 47, 39,\n\t        31, 23, 15, 7,  62, 54, 46, 38,\n\t        30, 22, 14, 6,  61, 53, 45, 37,\n\t        29, 21, 13, 5,  28, 20, 12, 4\n\t    ];\n\n\t    // Permuted Choice 2 constants\n\t    var PC2 = [\n\t        14, 17, 11, 24, 1,  5,\n\t        3,  28, 15, 6,  21, 10,\n\t        23, 19, 12, 4,  26, 8,\n\t        16, 7,  27, 20, 13, 2,\n\t        41, 52, 31, 37, 47, 55,\n\t        30, 40, 51, 45, 33, 48,\n\t        44, 49, 39, 56, 34, 53,\n\t        46, 42, 50, 36, 29, 32\n\t    ];\n\n\t    // Cumulative bit shift constants\n\t    var BIT_SHIFTS = [1,  2,  4,  6,  8,  10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28];\n\n\t    // SBOXes and round permutation constants\n\t    var SBOX_P = [\n\t        {\n\t            0x0: 0x808200,\n\t            0x10000000: 0x8000,\n\t            0x20000000: 0x808002,\n\t            0x30000000: 0x2,\n\t            0x40000000: 0x200,\n\t            0x50000000: 0x808202,\n\t            0x60000000: 0x800202,\n\t            0x70000000: 0x800000,\n\t            0x80000000: 0x202,\n\t            0x90000000: 0x800200,\n\t            0xa0000000: 0x8200,\n\t            0xb0000000: 0x808000,\n\t            0xc0000000: 0x8002,\n\t            0xd0000000: 0x800002,\n\t            0xe0000000: 0x0,\n\t            0xf0000000: 0x8202,\n\t            0x8000000: 0x0,\n\t            0x18000000: 0x808202,\n\t            0x28000000: 0x8202,\n\t            0x38000000: 0x8000,\n\t            0x48000000: 0x808200,\n\t            0x58000000: 0x200,\n\t            0x68000000: 0x808002,\n\t            0x78000000: 0x2,\n\t            0x88000000: 0x800200,\n\t            0x98000000: 0x8200,\n\t            0xa8000000: 0x808000,\n\t            0xb8000000: 0x800202,\n\t            0xc8000000: 0x800002,\n\t            0xd8000000: 0x8002,\n\t            0xe8000000: 0x202,\n\t            0xf8000000: 0x800000,\n\t            0x1: 0x8000,\n\t            0x10000001: 0x2,\n\t            0x20000001: 0x808200,\n\t            0x30000001: 0x800000,\n\t            0x40000001: 0x808002,\n\t            0x50000001: 0x8200,\n\t            0x60000001: 0x200,\n\t            0x70000001: 0x800202,\n\t            0x80000001: 0x808202,\n\t            0x90000001: 0x808000,\n\t            0xa0000001: 0x800002,\n\t            0xb0000001: 0x8202,\n\t            0xc0000001: 0x202,\n\t            0xd0000001: 0x800200,\n\t            0xe0000001: 0x8002,\n\t            0xf0000001: 0x0,\n\t            0x8000001: 0x808202,\n\t            0x18000001: 0x808000,\n\t            0x28000001: 0x800000,\n\t            0x38000001: 0x200,\n\t            0x48000001: 0x8000,\n\t            0x58000001: 0x800002,\n\t            0x68000001: 0x2,\n\t            0x78000001: 0x8202,\n\t            0x88000001: 0x8002,\n\t            0x98000001: 0x800202,\n\t            0xa8000001: 0x202,\n\t            0xb8000001: 0x808200,\n\t            0xc8000001: 0x800200,\n\t            0xd8000001: 0x0,\n\t            0xe8000001: 0x8200,\n\t            0xf8000001: 0x808002\n\t        },\n\t        {\n\t            0x0: 0x40084010,\n\t            0x1000000: 0x4000,\n\t            0x2000000: 0x80000,\n\t            0x3000000: 0x40080010,\n\t            0x4000000: 0x40000010,\n\t            0x5000000: 0x40084000,\n\t            0x6000000: 0x40004000,\n\t            0x7000000: 0x10,\n\t            0x8000000: 0x84000,\n\t            0x9000000: 0x40004010,\n\t            0xa000000: 0x40000000,\n\t            0xb000000: 0x84010,\n\t            0xc000000: 0x80010,\n\t            0xd000000: 0x0,\n\t            0xe000000: 0x4010,\n\t            0xf000000: 0x40080000,\n\t            0x800000: 0x40004000,\n\t            0x1800000: 0x84010,\n\t            0x2800000: 0x10,\n\t            0x3800000: 0x40004010,\n\t            0x4800000: 0x40084010,\n\t            0x5800000: 0x40000000,\n\t            0x6800000: 0x80000,\n\t            0x7800000: 0x40080010,\n\t            0x8800000: 0x80010,\n\t            0x9800000: 0x0,\n\t            0xa800000: 0x4000,\n\t            0xb800000: 0x40080000,\n\t            0xc800000: 0x40000010,\n\t            0xd800000: 0x84000,\n\t            0xe800000: 0x40084000,\n\t            0xf800000: 0x4010,\n\t            0x10000000: 0x0,\n\t            0x11000000: 0x40080010,\n\t            0x12000000: 0x40004010,\n\t            0x13000000: 0x40084000,\n\t            0x14000000: 0x40080000,\n\t            0x15000000: 0x10,\n\t            0x16000000: 0x84010,\n\t            0x17000000: 0x4000,\n\t            0x18000000: 0x4010,\n\t            0x19000000: 0x80000,\n\t            0x1a000000: 0x80010,\n\t            0x1b000000: 0x40000010,\n\t            0x1c000000: 0x84000,\n\t            0x1d000000: 0x40004000,\n\t            0x1e000000: 0x40000000,\n\t            0x1f000000: 0x40084010,\n\t            0x10800000: 0x84010,\n\t            0x11800000: 0x80000,\n\t            0x12800000: 0x40080000,\n\t            0x13800000: 0x4000,\n\t            0x14800000: 0x40004000,\n\t            0x15800000: 0x40084010,\n\t            0x16800000: 0x10,\n\t            0x17800000: 0x40000000,\n\t            0x18800000: 0x40084000,\n\t            0x19800000: 0x40000010,\n\t            0x1a800000: 0x40004010,\n\t            0x1b800000: 0x80010,\n\t            0x1c800000: 0x0,\n\t            0x1d800000: 0x4010,\n\t            0x1e800000: 0x40080010,\n\t            0x1f800000: 0x84000\n\t        },\n\t        {\n\t            0x0: 0x104,\n\t            0x100000: 0x0,\n\t            0x200000: 0x4000100,\n\t            0x300000: 0x10104,\n\t            0x400000: 0x10004,\n\t            0x500000: 0x4000004,\n\t            0x600000: 0x4010104,\n\t            0x700000: 0x4010000,\n\t            0x800000: 0x4000000,\n\t            0x900000: 0x4010100,\n\t            0xa00000: 0x10100,\n\t            0xb00000: 0x4010004,\n\t            0xc00000: 0x4000104,\n\t            0xd00000: 0x10000,\n\t            0xe00000: 0x4,\n\t            0xf00000: 0x100,\n\t            0x80000: 0x4010100,\n\t            0x180000: 0x4010004,\n\t            0x280000: 0x0,\n\t            0x380000: 0x4000100,\n\t            0x480000: 0x4000004,\n\t            0x580000: 0x10000,\n\t            0x680000: 0x10004,\n\t            0x780000: 0x104,\n\t            0x880000: 0x4,\n\t            0x980000: 0x100,\n\t            0xa80000: 0x4010000,\n\t            0xb80000: 0x10104,\n\t            0xc80000: 0x10100,\n\t            0xd80000: 0x4000104,\n\t            0xe80000: 0x4010104,\n\t            0xf80000: 0x4000000,\n\t            0x1000000: 0x4010100,\n\t            0x1100000: 0x10004,\n\t            0x1200000: 0x10000,\n\t            0x1300000: 0x4000100,\n\t            0x1400000: 0x100,\n\t            0x1500000: 0x4010104,\n\t            0x1600000: 0x4000004,\n\t            0x1700000: 0x0,\n\t            0x1800000: 0x4000104,\n\t            0x1900000: 0x4000000,\n\t            0x1a00000: 0x4,\n\t            0x1b00000: 0x10100,\n\t            0x1c00000: 0x4010000,\n\t            0x1d00000: 0x104,\n\t            0x1e00000: 0x10104,\n\t            0x1f00000: 0x4010004,\n\t            0x1080000: 0x4000000,\n\t            0x1180000: 0x104,\n\t            0x1280000: 0x4010100,\n\t            0x1380000: 0x0,\n\t            0x1480000: 0x10004,\n\t            0x1580000: 0x4000100,\n\t            0x1680000: 0x100,\n\t            0x1780000: 0x4010004,\n\t            0x1880000: 0x10000,\n\t            0x1980000: 0x4010104,\n\t            0x1a80000: 0x10104,\n\t            0x1b80000: 0x4000004,\n\t            0x1c80000: 0x4000104,\n\t            0x1d80000: 0x4010000,\n\t            0x1e80000: 0x4,\n\t            0x1f80000: 0x10100\n\t        },\n\t        {\n\t            0x0: 0x80401000,\n\t            0x10000: 0x80001040,\n\t            0x20000: 0x401040,\n\t            0x30000: 0x80400000,\n\t            0x40000: 0x0,\n\t            0x50000: 0x401000,\n\t            0x60000: 0x80000040,\n\t            0x70000: 0x400040,\n\t            0x80000: 0x80000000,\n\t            0x90000: 0x400000,\n\t            0xa0000: 0x40,\n\t            0xb0000: 0x80001000,\n\t            0xc0000: 0x80400040,\n\t            0xd0000: 0x1040,\n\t            0xe0000: 0x1000,\n\t            0xf0000: 0x80401040,\n\t            0x8000: 0x80001040,\n\t            0x18000: 0x40,\n\t            0x28000: 0x80400040,\n\t            0x38000: 0x80001000,\n\t            0x48000: 0x401000,\n\t            0x58000: 0x80401040,\n\t            0x68000: 0x0,\n\t            0x78000: 0x80400000,\n\t            0x88000: 0x1000,\n\t            0x98000: 0x80401000,\n\t            0xa8000: 0x400000,\n\t            0xb8000: 0x1040,\n\t            0xc8000: 0x80000000,\n\t            0xd8000: 0x400040,\n\t            0xe8000: 0x401040,\n\t            0xf8000: 0x80000040,\n\t            0x100000: 0x400040,\n\t            0x110000: 0x401000,\n\t            0x120000: 0x80000040,\n\t            0x130000: 0x0,\n\t            0x140000: 0x1040,\n\t            0x150000: 0x80400040,\n\t            0x160000: 0x80401000,\n\t            0x170000: 0x80001040,\n\t            0x180000: 0x80401040,\n\t            0x190000: 0x80000000,\n\t            0x1a0000: 0x80400000,\n\t            0x1b0000: 0x401040,\n\t            0x1c0000: 0x80001000,\n\t            0x1d0000: 0x400000,\n\t            0x1e0000: 0x40,\n\t            0x1f0000: 0x1000,\n\t            0x108000: 0x80400000,\n\t            0x118000: 0x80401040,\n\t            0x128000: 0x0,\n\t            0x138000: 0x401000,\n\t            0x148000: 0x400040,\n\t            0x158000: 0x80000000,\n\t            0x168000: 0x80001040,\n\t            0x178000: 0x40,\n\t            0x188000: 0x80000040,\n\t            0x198000: 0x1000,\n\t            0x1a8000: 0x80001000,\n\t            0x1b8000: 0x80400040,\n\t            0x1c8000: 0x1040,\n\t            0x1d8000: 0x80401000,\n\t            0x1e8000: 0x400000,\n\t            0x1f8000: 0x401040\n\t        },\n\t        {\n\t            0x0: 0x80,\n\t            0x1000: 0x1040000,\n\t            0x2000: 0x40000,\n\t            0x3000: 0x20000000,\n\t            0x4000: 0x20040080,\n\t            0x5000: 0x1000080,\n\t            0x6000: 0x21000080,\n\t            0x7000: 0x40080,\n\t            0x8000: 0x1000000,\n\t            0x9000: 0x20040000,\n\t            0xa000: 0x20000080,\n\t            0xb000: 0x21040080,\n\t            0xc000: 0x21040000,\n\t            0xd000: 0x0,\n\t            0xe000: 0x1040080,\n\t            0xf000: 0x21000000,\n\t            0x800: 0x1040080,\n\t            0x1800: 0x21000080,\n\t            0x2800: 0x80,\n\t            0x3800: 0x1040000,\n\t            0x4800: 0x40000,\n\t            0x5800: 0x20040080,\n\t            0x6800: 0x21040000,\n\t            0x7800: 0x20000000,\n\t            0x8800: 0x20040000,\n\t            0x9800: 0x0,\n\t            0xa800: 0x21040080,\n\t            0xb800: 0x1000080,\n\t            0xc800: 0x20000080,\n\t            0xd800: 0x21000000,\n\t            0xe800: 0x1000000,\n\t            0xf800: 0x40080,\n\t            0x10000: 0x40000,\n\t            0x11000: 0x80,\n\t            0x12000: 0x20000000,\n\t            0x13000: 0x21000080,\n\t            0x14000: 0x1000080,\n\t            0x15000: 0x21040000,\n\t            0x16000: 0x20040080,\n\t            0x17000: 0x1000000,\n\t            0x18000: 0x21040080,\n\t            0x19000: 0x21000000,\n\t            0x1a000: 0x1040000,\n\t            0x1b000: 0x20040000,\n\t            0x1c000: 0x40080,\n\t            0x1d000: 0x20000080,\n\t            0x1e000: 0x0,\n\t            0x1f000: 0x1040080,\n\t            0x10800: 0x21000080,\n\t            0x11800: 0x1000000,\n\t            0x12800: 0x1040000,\n\t            0x13800: 0x20040080,\n\t            0x14800: 0x20000000,\n\t            0x15800: 0x1040080,\n\t            0x16800: 0x80,\n\t            0x17800: 0x21040000,\n\t            0x18800: 0x40080,\n\t            0x19800: 0x21040080,\n\t            0x1a800: 0x0,\n\t            0x1b800: 0x21000000,\n\t            0x1c800: 0x1000080,\n\t            0x1d800: 0x40000,\n\t            0x1e800: 0x20040000,\n\t            0x1f800: 0x20000080\n\t        },\n\t        {\n\t            0x0: 0x10000008,\n\t            0x100: 0x2000,\n\t            0x200: 0x10200000,\n\t            0x300: 0x10202008,\n\t            0x400: 0x10002000,\n\t            0x500: 0x200000,\n\t            0x600: 0x200008,\n\t            0x700: 0x10000000,\n\t            0x800: 0x0,\n\t            0x900: 0x10002008,\n\t            0xa00: 0x202000,\n\t            0xb00: 0x8,\n\t            0xc00: 0x10200008,\n\t            0xd00: 0x202008,\n\t            0xe00: 0x2008,\n\t            0xf00: 0x10202000,\n\t            0x80: 0x10200000,\n\t            0x180: 0x10202008,\n\t            0x280: 0x8,\n\t            0x380: 0x200000,\n\t            0x480: 0x202008,\n\t            0x580: 0x10000008,\n\t            0x680: 0x10002000,\n\t            0x780: 0x2008,\n\t            0x880: 0x200008,\n\t            0x980: 0x2000,\n\t            0xa80: 0x10002008,\n\t            0xb80: 0x10200008,\n\t            0xc80: 0x0,\n\t            0xd80: 0x10202000,\n\t            0xe80: 0x202000,\n\t            0xf80: 0x10000000,\n\t            0x1000: 0x10002000,\n\t            0x1100: 0x10200008,\n\t            0x1200: 0x10202008,\n\t            0x1300: 0x2008,\n\t            0x1400: 0x200000,\n\t            0x1500: 0x10000000,\n\t            0x1600: 0x10000008,\n\t            0x1700: 0x202000,\n\t            0x1800: 0x202008,\n\t            0x1900: 0x0,\n\t            0x1a00: 0x8,\n\t            0x1b00: 0x10200000,\n\t            0x1c00: 0x2000,\n\t            0x1d00: 0x10002008,\n\t            0x1e00: 0x10202000,\n\t            0x1f00: 0x200008,\n\t            0x1080: 0x8,\n\t            0x1180: 0x202000,\n\t            0x1280: 0x200000,\n\t            0x1380: 0x10000008,\n\t            0x1480: 0x10002000,\n\t            0x1580: 0x2008,\n\t            0x1680: 0x10202008,\n\t            0x1780: 0x10200000,\n\t            0x1880: 0x10202000,\n\t            0x1980: 0x10200008,\n\t            0x1a80: 0x2000,\n\t            0x1b80: 0x202008,\n\t            0x1c80: 0x200008,\n\t            0x1d80: 0x0,\n\t            0x1e80: 0x10000000,\n\t            0x1f80: 0x10002008\n\t        },\n\t        {\n\t            0x0: 0x100000,\n\t            0x10: 0x2000401,\n\t            0x20: 0x400,\n\t            0x30: 0x100401,\n\t            0x40: 0x2100401,\n\t            0x50: 0x0,\n\t            0x60: 0x1,\n\t            0x70: 0x2100001,\n\t            0x80: 0x2000400,\n\t            0x90: 0x100001,\n\t            0xa0: 0x2000001,\n\t            0xb0: 0x2100400,\n\t            0xc0: 0x2100000,\n\t            0xd0: 0x401,\n\t            0xe0: 0x100400,\n\t            0xf0: 0x2000000,\n\t            0x8: 0x2100001,\n\t            0x18: 0x0,\n\t            0x28: 0x2000401,\n\t            0x38: 0x2100400,\n\t            0x48: 0x100000,\n\t            0x58: 0x2000001,\n\t            0x68: 0x2000000,\n\t            0x78: 0x401,\n\t            0x88: 0x100401,\n\t            0x98: 0x2000400,\n\t            0xa8: 0x2100000,\n\t            0xb8: 0x100001,\n\t            0xc8: 0x400,\n\t            0xd8: 0x2100401,\n\t            0xe8: 0x1,\n\t            0xf8: 0x100400,\n\t            0x100: 0x2000000,\n\t            0x110: 0x100000,\n\t            0x120: 0x2000401,\n\t            0x130: 0x2100001,\n\t            0x140: 0x100001,\n\t            0x150: 0x2000400,\n\t            0x160: 0x2100400,\n\t            0x170: 0x100401,\n\t            0x180: 0x401,\n\t            0x190: 0x2100401,\n\t            0x1a0: 0x100400,\n\t            0x1b0: 0x1,\n\t            0x1c0: 0x0,\n\t            0x1d0: 0x2100000,\n\t            0x1e0: 0x2000001,\n\t            0x1f0: 0x400,\n\t            0x108: 0x100400,\n\t            0x118: 0x2000401,\n\t            0x128: 0x2100001,\n\t            0x138: 0x1,\n\t            0x148: 0x2000000,\n\t            0x158: 0x100000,\n\t            0x168: 0x401,\n\t            0x178: 0x2100400,\n\t            0x188: 0x2000001,\n\t            0x198: 0x2100000,\n\t            0x1a8: 0x0,\n\t            0x1b8: 0x2100401,\n\t            0x1c8: 0x100401,\n\t            0x1d8: 0x400,\n\t            0x1e8: 0x2000400,\n\t            0x1f8: 0x100001\n\t        },\n\t        {\n\t            0x0: 0x8000820,\n\t            0x1: 0x20000,\n\t            0x2: 0x8000000,\n\t            0x3: 0x20,\n\t            0x4: 0x20020,\n\t            0x5: 0x8020820,\n\t            0x6: 0x8020800,\n\t            0x7: 0x800,\n\t            0x8: 0x8020000,\n\t            0x9: 0x8000800,\n\t            0xa: 0x20800,\n\t            0xb: 0x8020020,\n\t            0xc: 0x820,\n\t            0xd: 0x0,\n\t            0xe: 0x8000020,\n\t            0xf: 0x20820,\n\t            0x80000000: 0x800,\n\t            0x80000001: 0x8020820,\n\t            0x80000002: 0x8000820,\n\t            0x80000003: 0x8000000,\n\t            0x80000004: 0x8020000,\n\t            0x80000005: 0x20800,\n\t            0x80000006: 0x20820,\n\t            0x80000007: 0x20,\n\t            0x80000008: 0x8000020,\n\t            0x80000009: 0x820,\n\t            0x8000000a: 0x20020,\n\t            0x8000000b: 0x8020800,\n\t            0x8000000c: 0x0,\n\t            0x8000000d: 0x8020020,\n\t            0x8000000e: 0x8000800,\n\t            0x8000000f: 0x20000,\n\t            0x10: 0x20820,\n\t            0x11: 0x8020800,\n\t            0x12: 0x20,\n\t            0x13: 0x800,\n\t            0x14: 0x8000800,\n\t            0x15: 0x8000020,\n\t            0x16: 0x8020020,\n\t            0x17: 0x20000,\n\t            0x18: 0x0,\n\t            0x19: 0x20020,\n\t            0x1a: 0x8020000,\n\t            0x1b: 0x8000820,\n\t            0x1c: 0x8020820,\n\t            0x1d: 0x20800,\n\t            0x1e: 0x820,\n\t            0x1f: 0x8000000,\n\t            0x80000010: 0x20000,\n\t            0x80000011: 0x800,\n\t            0x80000012: 0x8020020,\n\t            0x80000013: 0x20820,\n\t            0x80000014: 0x20,\n\t            0x80000015: 0x8020000,\n\t            0x80000016: 0x8000000,\n\t            0x80000017: 0x8000820,\n\t            0x80000018: 0x8020820,\n\t            0x80000019: 0x8000020,\n\t            0x8000001a: 0x8000800,\n\t            0x8000001b: 0x0,\n\t            0x8000001c: 0x20800,\n\t            0x8000001d: 0x820,\n\t            0x8000001e: 0x20020,\n\t            0x8000001f: 0x8020800\n\t        }\n\t    ];\n\n\t    // Masks that select the SBOX input\n\t    var SBOX_MASK = [\n\t        0xf8000001, 0x1f800000, 0x01f80000, 0x001f8000,\n\t        0x0001f800, 0x00001f80, 0x000001f8, 0x8000001f\n\t    ];\n\n\t    /**\n\t     * DES block cipher algorithm.\n\t     */\n\t    var DES = C_algo.DES = BlockCipher.extend({\n\t        _doReset: function () {\n\t            // Shortcuts\n\t            var key = this._key;\n\t            var keyWords = key.words;\n\n\t            // Select 56 bits according to PC1\n\t            var keyBits = [];\n\t            for (var i = 0; i < 56; i++) {\n\t                var keyBitPos = PC1[i] - 1;\n\t                keyBits[i] = (keyWords[keyBitPos >>> 5] >>> (31 - keyBitPos % 32)) & 1;\n\t            }\n\n\t            // Assemble 16 subkeys\n\t            var subKeys = this._subKeys = [];\n\t            for (var nSubKey = 0; nSubKey < 16; nSubKey++) {\n\t                // Create subkey\n\t                var subKey = subKeys[nSubKey] = [];\n\n\t                // Shortcut\n\t                var bitShift = BIT_SHIFTS[nSubKey];\n\n\t                // Select 48 bits according to PC2\n\t                for (var i = 0; i < 24; i++) {\n\t                    // Select from the left 28 key bits\n\t                    subKey[(i / 6) | 0] |= keyBits[((PC2[i] - 1) + bitShift) % 28] << (31 - i % 6);\n\n\t                    // Select from the right 28 key bits\n\t                    subKey[4 + ((i / 6) | 0)] |= keyBits[28 + (((PC2[i + 24] - 1) + bitShift) % 28)] << (31 - i % 6);\n\t                }\n\n\t                // Since each subkey is applied to an expanded 32-bit input,\n\t                // the subkey can be broken into 8 values scaled to 32-bits,\n\t                // which allows the key to be used without expansion\n\t                subKey[0] = (subKey[0] << 1) | (subKey[0] >>> 31);\n\t                for (var i = 1; i < 7; i++) {\n\t                    subKey[i] = subKey[i] >>> ((i - 1) * 4 + 3);\n\t                }\n\t                subKey[7] = (subKey[7] << 5) | (subKey[7] >>> 27);\n\t            }\n\n\t            // Compute inverse subkeys\n\t            var invSubKeys = this._invSubKeys = [];\n\t            for (var i = 0; i < 16; i++) {\n\t                invSubKeys[i] = subKeys[15 - i];\n\t            }\n\t        },\n\n\t        encryptBlock: function (M, offset) {\n\t            this._doCryptBlock(M, offset, this._subKeys);\n\t        },\n\n\t        decryptBlock: function (M, offset) {\n\t            this._doCryptBlock(M, offset, this._invSubKeys);\n\t        },\n\n\t        _doCryptBlock: function (M, offset, subKeys) {\n\t            // Get input\n\t            this._lBlock = M[offset];\n\t            this._rBlock = M[offset + 1];\n\n\t            // Initial permutation\n\t            exchangeLR.call(this, 4,  0x0f0f0f0f);\n\t            exchangeLR.call(this, 16, 0x0000ffff);\n\t            exchangeRL.call(this, 2,  0x33333333);\n\t            exchangeRL.call(this, 8,  0x00ff00ff);\n\t            exchangeLR.call(this, 1,  0x55555555);\n\n\t            // Rounds\n\t            for (var round = 0; round < 16; round++) {\n\t                // Shortcuts\n\t                var subKey = subKeys[round];\n\t                var lBlock = this._lBlock;\n\t                var rBlock = this._rBlock;\n\n\t                // Feistel function\n\t                var f = 0;\n\t                for (var i = 0; i < 8; i++) {\n\t                    f |= SBOX_P[i][((rBlock ^ subKey[i]) & SBOX_MASK[i]) >>> 0];\n\t                }\n\t                this._lBlock = rBlock;\n\t                this._rBlock = lBlock ^ f;\n\t            }\n\n\t            // Undo swap from last round\n\t            var t = this._lBlock;\n\t            this._lBlock = this._rBlock;\n\t            this._rBlock = t;\n\n\t            // Final permutation\n\t            exchangeLR.call(this, 1,  0x55555555);\n\t            exchangeRL.call(this, 8,  0x00ff00ff);\n\t            exchangeRL.call(this, 2,  0x33333333);\n\t            exchangeLR.call(this, 16, 0x0000ffff);\n\t            exchangeLR.call(this, 4,  0x0f0f0f0f);\n\n\t            // Set output\n\t            M[offset] = this._lBlock;\n\t            M[offset + 1] = this._rBlock;\n\t        },\n\n\t        keySize: 64/32,\n\n\t        ivSize: 64/32,\n\n\t        blockSize: 64/32\n\t    });\n\n\t    // Swap bits across the left and right words\n\t    function exchangeLR(offset, mask) {\n\t        var t = ((this._lBlock >>> offset) ^ this._rBlock) & mask;\n\t        this._rBlock ^= t;\n\t        this._lBlock ^= t << offset;\n\t    }\n\n\t    function exchangeRL(offset, mask) {\n\t        var t = ((this._rBlock >>> offset) ^ this._lBlock) & mask;\n\t        this._lBlock ^= t;\n\t        this._rBlock ^= t << offset;\n\t    }\n\n\t    /**\n\t     * Shortcut functions to the cipher's object interface.\n\t     *\n\t     * @example\n\t     *\n\t     *     var ciphertext = CryptoJS.DES.encrypt(message, key, cfg);\n\t     *     var plaintext  = CryptoJS.DES.decrypt(ciphertext, key, cfg);\n\t     */\n\t    C.DES = BlockCipher._createHelper(DES);\n\n\t    /**\n\t     * Triple-DES block cipher algorithm.\n\t     */\n\t    var TripleDES = C_algo.TripleDES = BlockCipher.extend({\n\t        _doReset: function () {\n\t            // Shortcuts\n\t            var key = this._key;\n\t            var keyWords = key.words;\n\t            // Make sure the key length is valid (64, 128 or >= 192 bit)\n\t            if (keyWords.length !== 2 && keyWords.length !== 4 && keyWords.length < 6) {\n\t                throw new Error('Invalid key length - 3DES requires the key length to be 64, 128, 192 or >192.');\n\t            }\n\n\t            // Extend the key according to the keying options defined in 3DES standard\n\t            var key1 = keyWords.slice(0, 2);\n\t            var key2 = keyWords.length < 4 ? keyWords.slice(0, 2) : keyWords.slice(2, 4);\n\t            var key3 = keyWords.length < 6 ? keyWords.slice(0, 2) : keyWords.slice(4, 6);\n\n\t            // Create DES instances\n\t            this._des1 = DES.createEncryptor(WordArray.create(key1));\n\t            this._des2 = DES.createEncryptor(WordArray.create(key2));\n\t            this._des3 = DES.createEncryptor(WordArray.create(key3));\n\t        },\n\n\t        encryptBlock: function (M, offset) {\n\t            this._des1.encryptBlock(M, offset);\n\t            this._des2.decryptBlock(M, offset);\n\t            this._des3.encryptBlock(M, offset);\n\t        },\n\n\t        decryptBlock: function (M, offset) {\n\t            this._des3.decryptBlock(M, offset);\n\t            this._des2.encryptBlock(M, offset);\n\t            this._des1.decryptBlock(M, offset);\n\t        },\n\n\t        keySize: 192/32,\n\n\t        ivSize: 64/32,\n\n\t        blockSize: 64/32\n\t    });\n\n\t    /**\n\t     * Shortcut functions to the cipher's object interface.\n\t     *\n\t     * @example\n\t     *\n\t     *     var ciphertext = CryptoJS.TripleDES.encrypt(message, key, cfg);\n\t     *     var plaintext  = CryptoJS.TripleDES.decrypt(ciphertext, key, cfg);\n\t     */\n\t    C.TripleDES = BlockCipher._createHelper(TripleDES);\n\t}());\n\n\n\t(function () {\n\t    // Shortcuts\n\t    var C = CryptoJS;\n\t    var C_lib = C.lib;\n\t    var StreamCipher = C_lib.StreamCipher;\n\t    var C_algo = C.algo;\n\n\t    /**\n\t     * RC4 stream cipher algorithm.\n\t     */\n\t    var RC4 = C_algo.RC4 = StreamCipher.extend({\n\t        _doReset: function () {\n\t            // Shortcuts\n\t            var key = this._key;\n\t            var keyWords = key.words;\n\t            var keySigBytes = key.sigBytes;\n\n\t            // Init sbox\n\t            var S = this._S = [];\n\t            for (var i = 0; i < 256; i++) {\n\t                S[i] = i;\n\t            }\n\n\t            // Key setup\n\t            for (var i = 0, j = 0; i < 256; i++) {\n\t                var keyByteIndex = i % keySigBytes;\n\t                var keyByte = (keyWords[keyByteIndex >>> 2] >>> (24 - (keyByteIndex % 4) * 8)) & 0xff;\n\n\t                j = (j + S[i] + keyByte) % 256;\n\n\t                // Swap\n\t                var t = S[i];\n\t                S[i] = S[j];\n\t                S[j] = t;\n\t            }\n\n\t            // Counters\n\t            this._i = this._j = 0;\n\t        },\n\n\t        _doProcessBlock: function (M, offset) {\n\t            M[offset] ^= generateKeystreamWord.call(this);\n\t        },\n\n\t        keySize: 256/32,\n\n\t        ivSize: 0\n\t    });\n\n\t    function generateKeystreamWord() {\n\t        // Shortcuts\n\t        var S = this._S;\n\t        var i = this._i;\n\t        var j = this._j;\n\n\t        // Generate keystream word\n\t        var keystreamWord = 0;\n\t        for (var n = 0; n < 4; n++) {\n\t            i = (i + 1) % 256;\n\t            j = (j + S[i]) % 256;\n\n\t            // Swap\n\t            var t = S[i];\n\t            S[i] = S[j];\n\t            S[j] = t;\n\n\t            keystreamWord |= S[(S[i] + S[j]) % 256] << (24 - n * 8);\n\t        }\n\n\t        // Update counters\n\t        this._i = i;\n\t        this._j = j;\n\n\t        return keystreamWord;\n\t    }\n\n\t    /**\n\t     * Shortcut functions to the cipher's object interface.\n\t     *\n\t     * @example\n\t     *\n\t     *     var ciphertext = CryptoJS.RC4.encrypt(message, key, cfg);\n\t     *     var plaintext  = CryptoJS.RC4.decrypt(ciphertext, key, cfg);\n\t     */\n\t    C.RC4 = StreamCipher._createHelper(RC4);\n\n\t    /**\n\t     * Modified RC4 stream cipher algorithm.\n\t     */\n\t    var RC4Drop = C_algo.RC4Drop = RC4.extend({\n\t        /**\n\t         * Configuration options.\n\t         *\n\t         * @property {number} drop The number of keystream words to drop. Default 192\n\t         */\n\t        cfg: RC4.cfg.extend({\n\t            drop: 192\n\t        }),\n\n\t        _doReset: function () {\n\t            RC4._doReset.call(this);\n\n\t            // Drop\n\t            for (var i = this.cfg.drop; i > 0; i--) {\n\t                generateKeystreamWord.call(this);\n\t            }\n\t        }\n\t    });\n\n\t    /**\n\t     * Shortcut functions to the cipher's object interface.\n\t     *\n\t     * @example\n\t     *\n\t     *     var ciphertext = CryptoJS.RC4Drop.encrypt(message, key, cfg);\n\t     *     var plaintext  = CryptoJS.RC4Drop.decrypt(ciphertext, key, cfg);\n\t     */\n\t    C.RC4Drop = StreamCipher._createHelper(RC4Drop);\n\t}());\n\n\n\t/** @preserve\n\t * Counter block mode compatible with  Dr Brian Gladman fileenc.c\n\t * derived from CryptoJS.mode.CTR\n\t * Jan Hruby jhruby.web@gmail.com\n\t */\n\tCryptoJS.mode.CTRGladman = (function () {\n\t    var CTRGladman = CryptoJS.lib.BlockCipherMode.extend();\n\n\t\tfunction incWord(word)\n\t\t{\n\t\t\tif (((word >> 24) & 0xff) === 0xff) { //overflow\n\t\t\tvar b1 = (word >> 16)&0xff;\n\t\t\tvar b2 = (word >> 8)&0xff;\n\t\t\tvar b3 = word & 0xff;\n\n\t\t\tif (b1 === 0xff) // overflow b1\n\t\t\t{\n\t\t\tb1 = 0;\n\t\t\tif (b2 === 0xff)\n\t\t\t{\n\t\t\t\tb2 = 0;\n\t\t\t\tif (b3 === 0xff)\n\t\t\t\t{\n\t\t\t\t\tb3 = 0;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t++b3;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t++b2;\n\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t++b1;\n\t\t\t}\n\n\t\t\tword = 0;\n\t\t\tword += (b1 << 16);\n\t\t\tword += (b2 << 8);\n\t\t\tword += b3;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\tword += (0x01 << 24);\n\t\t\t}\n\t\t\treturn word;\n\t\t}\n\n\t\tfunction incCounter(counter)\n\t\t{\n\t\t\tif ((counter[0] = incWord(counter[0])) === 0)\n\t\t\t{\n\t\t\t\t// encr_data in fileenc.c from  Dr Brian Gladman's counts only with DWORD j < 8\n\t\t\t\tcounter[1] = incWord(counter[1]);\n\t\t\t}\n\t\t\treturn counter;\n\t\t}\n\n\t    var Encryptor = CTRGladman.Encryptor = CTRGladman.extend({\n\t        processBlock: function (words, offset) {\n\t            // Shortcuts\n\t            var cipher = this._cipher\n\t            var blockSize = cipher.blockSize;\n\t            var iv = this._iv;\n\t            var counter = this._counter;\n\n\t            // Generate keystream\n\t            if (iv) {\n\t                counter = this._counter = iv.slice(0);\n\n\t                // Remove IV for subsequent blocks\n\t                this._iv = undefined;\n\t            }\n\n\t\t\t\tincCounter(counter);\n\n\t\t\t\tvar keystream = counter.slice(0);\n\t            cipher.encryptBlock(keystream, 0);\n\n\t            // Encrypt\n\t            for (var i = 0; i < blockSize; i++) {\n\t                words[offset + i] ^= keystream[i];\n\t            }\n\t        }\n\t    });\n\n\t    CTRGladman.Decryptor = Encryptor;\n\n\t    return CTRGladman;\n\t}());\n\n\n\n\n\t(function () {\n\t    // Shortcuts\n\t    var C = CryptoJS;\n\t    var C_lib = C.lib;\n\t    var StreamCipher = C_lib.StreamCipher;\n\t    var C_algo = C.algo;\n\n\t    // Reusable objects\n\t    var S  = [];\n\t    var C_ = [];\n\t    var G  = [];\n\n\t    /**\n\t     * Rabbit stream cipher algorithm\n\t     */\n\t    var Rabbit = C_algo.Rabbit = StreamCipher.extend({\n\t        _doReset: function () {\n\t            // Shortcuts\n\t            var K = this._key.words;\n\t            var iv = this.cfg.iv;\n\n\t            // Swap endian\n\t            for (var i = 0; i < 4; i++) {\n\t                K[i] = (((K[i] << 8)  | (K[i] >>> 24)) & 0x00ff00ff) |\n\t                       (((K[i] << 24) | (K[i] >>> 8))  & 0xff00ff00);\n\t            }\n\n\t            // Generate initial state values\n\t            var X = this._X = [\n\t                K[0], (K[3] << 16) | (K[2] >>> 16),\n\t                K[1], (K[0] << 16) | (K[3] >>> 16),\n\t                K[2], (K[1] << 16) | (K[0] >>> 16),\n\t                K[3], (K[2] << 16) | (K[1] >>> 16)\n\t            ];\n\n\t            // Generate initial counter values\n\t            var C = this._C = [\n\t                (K[2] << 16) | (K[2] >>> 16), (K[0] & 0xffff0000) | (K[1] & 0x0000ffff),\n\t                (K[3] << 16) | (K[3] >>> 16), (K[1] & 0xffff0000) | (K[2] & 0x0000ffff),\n\t                (K[0] << 16) | (K[0] >>> 16), (K[2] & 0xffff0000) | (K[3] & 0x0000ffff),\n\t                (K[1] << 16) | (K[1] >>> 16), (K[3] & 0xffff0000) | (K[0] & 0x0000ffff)\n\t            ];\n\n\t            // Carry bit\n\t            this._b = 0;\n\n\t            // Iterate the system four times\n\t            for (var i = 0; i < 4; i++) {\n\t                nextState.call(this);\n\t            }\n\n\t            // Modify the counters\n\t            for (var i = 0; i < 8; i++) {\n\t                C[i] ^= X[(i + 4) & 7];\n\t            }\n\n\t            // IV setup\n\t            if (iv) {\n\t                // Shortcuts\n\t                var IV = iv.words;\n\t                var IV_0 = IV[0];\n\t                var IV_1 = IV[1];\n\n\t                // Generate four subvectors\n\t                var i0 = (((IV_0 << 8) | (IV_0 >>> 24)) & 0x00ff00ff) | (((IV_0 << 24) | (IV_0 >>> 8)) & 0xff00ff00);\n\t                var i2 = (((IV_1 << 8) | (IV_1 >>> 24)) & 0x00ff00ff) | (((IV_1 << 24) | (IV_1 >>> 8)) & 0xff00ff00);\n\t                var i1 = (i0 >>> 16) | (i2 & 0xffff0000);\n\t                var i3 = (i2 << 16)  | (i0 & 0x0000ffff);\n\n\t                // Modify counter values\n\t                C[0] ^= i0;\n\t                C[1] ^= i1;\n\t                C[2] ^= i2;\n\t                C[3] ^= i3;\n\t                C[4] ^= i0;\n\t                C[5] ^= i1;\n\t                C[6] ^= i2;\n\t                C[7] ^= i3;\n\n\t                // Iterate the system four times\n\t                for (var i = 0; i < 4; i++) {\n\t                    nextState.call(this);\n\t                }\n\t            }\n\t        },\n\n\t        _doProcessBlock: function (M, offset) {\n\t            // Shortcut\n\t            var X = this._X;\n\n\t            // Iterate the system\n\t            nextState.call(this);\n\n\t            // Generate four keystream words\n\t            S[0] = X[0] ^ (X[5] >>> 16) ^ (X[3] << 16);\n\t            S[1] = X[2] ^ (X[7] >>> 16) ^ (X[5] << 16);\n\t            S[2] = X[4] ^ (X[1] >>> 16) ^ (X[7] << 16);\n\t            S[3] = X[6] ^ (X[3] >>> 16) ^ (X[1] << 16);\n\n\t            for (var i = 0; i < 4; i++) {\n\t                // Swap endian\n\t                S[i] = (((S[i] << 8)  | (S[i] >>> 24)) & 0x00ff00ff) |\n\t                       (((S[i] << 24) | (S[i] >>> 8))  & 0xff00ff00);\n\n\t                // Encrypt\n\t                M[offset + i] ^= S[i];\n\t            }\n\t        },\n\n\t        blockSize: 128/32,\n\n\t        ivSize: 64/32\n\t    });\n\n\t    function nextState() {\n\t        // Shortcuts\n\t        var X = this._X;\n\t        var C = this._C;\n\n\t        // Save old counter values\n\t        for (var i = 0; i < 8; i++) {\n\t            C_[i] = C[i];\n\t        }\n\n\t        // Calculate new counter values\n\t        C[0] = (C[0] + 0x4d34d34d + this._b) | 0;\n\t        C[1] = (C[1] + 0xd34d34d3 + ((C[0] >>> 0) < (C_[0] >>> 0) ? 1 : 0)) | 0;\n\t        C[2] = (C[2] + 0x34d34d34 + ((C[1] >>> 0) < (C_[1] >>> 0) ? 1 : 0)) | 0;\n\t        C[3] = (C[3] + 0x4d34d34d + ((C[2] >>> 0) < (C_[2] >>> 0) ? 1 : 0)) | 0;\n\t        C[4] = (C[4] + 0xd34d34d3 + ((C[3] >>> 0) < (C_[3] >>> 0) ? 1 : 0)) | 0;\n\t        C[5] = (C[5] + 0x34d34d34 + ((C[4] >>> 0) < (C_[4] >>> 0) ? 1 : 0)) | 0;\n\t        C[6] = (C[6] + 0x4d34d34d + ((C[5] >>> 0) < (C_[5] >>> 0) ? 1 : 0)) | 0;\n\t        C[7] = (C[7] + 0xd34d34d3 + ((C[6] >>> 0) < (C_[6] >>> 0) ? 1 : 0)) | 0;\n\t        this._b = (C[7] >>> 0) < (C_[7] >>> 0) ? 1 : 0;\n\n\t        // Calculate the g-values\n\t        for (var i = 0; i < 8; i++) {\n\t            var gx = X[i] + C[i];\n\n\t            // Construct high and low argument for squaring\n\t            var ga = gx & 0xffff;\n\t            var gb = gx >>> 16;\n\n\t            // Calculate high and low result of squaring\n\t            var gh = ((((ga * ga) >>> 17) + ga * gb) >>> 15) + gb * gb;\n\t            var gl = (((gx & 0xffff0000) * gx) | 0) + (((gx & 0x0000ffff) * gx) | 0);\n\n\t            // High XOR low\n\t            G[i] = gh ^ gl;\n\t        }\n\n\t        // Calculate new state values\n\t        X[0] = (G[0] + ((G[7] << 16) | (G[7] >>> 16)) + ((G[6] << 16) | (G[6] >>> 16))) | 0;\n\t        X[1] = (G[1] + ((G[0] << 8)  | (G[0] >>> 24)) + G[7]) | 0;\n\t        X[2] = (G[2] + ((G[1] << 16) | (G[1] >>> 16)) + ((G[0] << 16) | (G[0] >>> 16))) | 0;\n\t        X[3] = (G[3] + ((G[2] << 8)  | (G[2] >>> 24)) + G[1]) | 0;\n\t        X[4] = (G[4] + ((G[3] << 16) | (G[3] >>> 16)) + ((G[2] << 16) | (G[2] >>> 16))) | 0;\n\t        X[5] = (G[5] + ((G[4] << 8)  | (G[4] >>> 24)) + G[3]) | 0;\n\t        X[6] = (G[6] + ((G[5] << 16) | (G[5] >>> 16)) + ((G[4] << 16) | (G[4] >>> 16))) | 0;\n\t        X[7] = (G[7] + ((G[6] << 8)  | (G[6] >>> 24)) + G[5]) | 0;\n\t    }\n\n\t    /**\n\t     * Shortcut functions to the cipher's object interface.\n\t     *\n\t     * @example\n\t     *\n\t     *     var ciphertext = CryptoJS.Rabbit.encrypt(message, key, cfg);\n\t     *     var plaintext  = CryptoJS.Rabbit.decrypt(ciphertext, key, cfg);\n\t     */\n\t    C.Rabbit = StreamCipher._createHelper(Rabbit);\n\t}());\n\n\n\t/**\n\t * Counter block mode.\n\t */\n\tCryptoJS.mode.CTR = (function () {\n\t    var CTR = CryptoJS.lib.BlockCipherMode.extend();\n\n\t    var Encryptor = CTR.Encryptor = CTR.extend({\n\t        processBlock: function (words, offset) {\n\t            // Shortcuts\n\t            var cipher = this._cipher\n\t            var blockSize = cipher.blockSize;\n\t            var iv = this._iv;\n\t            var counter = this._counter;\n\n\t            // Generate keystream\n\t            if (iv) {\n\t                counter = this._counter = iv.slice(0);\n\n\t                // Remove IV for subsequent blocks\n\t                this._iv = undefined;\n\t            }\n\t            var keystream = counter.slice(0);\n\t            cipher.encryptBlock(keystream, 0);\n\n\t            // Increment counter\n\t            counter[blockSize - 1] = (counter[blockSize - 1] + 1) | 0\n\n\t            // Encrypt\n\t            for (var i = 0; i < blockSize; i++) {\n\t                words[offset + i] ^= keystream[i];\n\t            }\n\t        }\n\t    });\n\n\t    CTR.Decryptor = Encryptor;\n\n\t    return CTR;\n\t}());\n\n\n\t(function () {\n\t    // Shortcuts\n\t    var C = CryptoJS;\n\t    var C_lib = C.lib;\n\t    var StreamCipher = C_lib.StreamCipher;\n\t    var C_algo = C.algo;\n\n\t    // Reusable objects\n\t    var S  = [];\n\t    var C_ = [];\n\t    var G  = [];\n\n\t    /**\n\t     * Rabbit stream cipher algorithm.\n\t     *\n\t     * This is a legacy version that neglected to convert the key to little-endian.\n\t     * This error doesn't affect the cipher's security,\n\t     * but it does affect its compatibility with other implementations.\n\t     */\n\t    var RabbitLegacy = C_algo.RabbitLegacy = StreamCipher.extend({\n\t        _doReset: function () {\n\t            // Shortcuts\n\t            var K = this._key.words;\n\t            var iv = this.cfg.iv;\n\n\t            // Generate initial state values\n\t            var X = this._X = [\n\t                K[0], (K[3] << 16) | (K[2] >>> 16),\n\t                K[1], (K[0] << 16) | (K[3] >>> 16),\n\t                K[2], (K[1] << 16) | (K[0] >>> 16),\n\t                K[3], (K[2] << 16) | (K[1] >>> 16)\n\t            ];\n\n\t            // Generate initial counter values\n\t            var C = this._C = [\n\t                (K[2] << 16) | (K[2] >>> 16), (K[0] & 0xffff0000) | (K[1] & 0x0000ffff),\n\t                (K[3] << 16) | (K[3] >>> 16), (K[1] & 0xffff0000) | (K[2] & 0x0000ffff),\n\t                (K[0] << 16) | (K[0] >>> 16), (K[2] & 0xffff0000) | (K[3] & 0x0000ffff),\n\t                (K[1] << 16) | (K[1] >>> 16), (K[3] & 0xffff0000) | (K[0] & 0x0000ffff)\n\t            ];\n\n\t            // Carry bit\n\t            this._b = 0;\n\n\t            // Iterate the system four times\n\t            for (var i = 0; i < 4; i++) {\n\t                nextState.call(this);\n\t            }\n\n\t            // Modify the counters\n\t            for (var i = 0; i < 8; i++) {\n\t                C[i] ^= X[(i + 4) & 7];\n\t            }\n\n\t            // IV setup\n\t            if (iv) {\n\t                // Shortcuts\n\t                var IV = iv.words;\n\t                var IV_0 = IV[0];\n\t                var IV_1 = IV[1];\n\n\t                // Generate four subvectors\n\t                var i0 = (((IV_0 << 8) | (IV_0 >>> 24)) & 0x00ff00ff) | (((IV_0 << 24) | (IV_0 >>> 8)) & 0xff00ff00);\n\t                var i2 = (((IV_1 << 8) | (IV_1 >>> 24)) & 0x00ff00ff) | (((IV_1 << 24) | (IV_1 >>> 8)) & 0xff00ff00);\n\t                var i1 = (i0 >>> 16) | (i2 & 0xffff0000);\n\t                var i3 = (i2 << 16)  | (i0 & 0x0000ffff);\n\n\t                // Modify counter values\n\t                C[0] ^= i0;\n\t                C[1] ^= i1;\n\t                C[2] ^= i2;\n\t                C[3] ^= i3;\n\t                C[4] ^= i0;\n\t                C[5] ^= i1;\n\t                C[6] ^= i2;\n\t                C[7] ^= i3;\n\n\t                // Iterate the system four times\n\t                for (var i = 0; i < 4; i++) {\n\t                    nextState.call(this);\n\t                }\n\t            }\n\t        },\n\n\t        _doProcessBlock: function (M, offset) {\n\t            // Shortcut\n\t            var X = this._X;\n\n\t            // Iterate the system\n\t            nextState.call(this);\n\n\t            // Generate four keystream words\n\t            S[0] = X[0] ^ (X[5] >>> 16) ^ (X[3] << 16);\n\t            S[1] = X[2] ^ (X[7] >>> 16) ^ (X[5] << 16);\n\t            S[2] = X[4] ^ (X[1] >>> 16) ^ (X[7] << 16);\n\t            S[3] = X[6] ^ (X[3] >>> 16) ^ (X[1] << 16);\n\n\t            for (var i = 0; i < 4; i++) {\n\t                // Swap endian\n\t                S[i] = (((S[i] << 8)  | (S[i] >>> 24)) & 0x00ff00ff) |\n\t                       (((S[i] << 24) | (S[i] >>> 8))  & 0xff00ff00);\n\n\t                // Encrypt\n\t                M[offset + i] ^= S[i];\n\t            }\n\t        },\n\n\t        blockSize: 128/32,\n\n\t        ivSize: 64/32\n\t    });\n\n\t    function nextState() {\n\t        // Shortcuts\n\t        var X = this._X;\n\t        var C = this._C;\n\n\t        // Save old counter values\n\t        for (var i = 0; i < 8; i++) {\n\t            C_[i] = C[i];\n\t        }\n\n\t        // Calculate new counter values\n\t        C[0] = (C[0] + 0x4d34d34d + this._b) | 0;\n\t        C[1] = (C[1] + 0xd34d34d3 + ((C[0] >>> 0) < (C_[0] >>> 0) ? 1 : 0)) | 0;\n\t        C[2] = (C[2] + 0x34d34d34 + ((C[1] >>> 0) < (C_[1] >>> 0) ? 1 : 0)) | 0;\n\t        C[3] = (C[3] + 0x4d34d34d + ((C[2] >>> 0) < (C_[2] >>> 0) ? 1 : 0)) | 0;\n\t        C[4] = (C[4] + 0xd34d34d3 + ((C[3] >>> 0) < (C_[3] >>> 0) ? 1 : 0)) | 0;\n\t        C[5] = (C[5] + 0x34d34d34 + ((C[4] >>> 0) < (C_[4] >>> 0) ? 1 : 0)) | 0;\n\t        C[6] = (C[6] + 0x4d34d34d + ((C[5] >>> 0) < (C_[5] >>> 0) ? 1 : 0)) | 0;\n\t        C[7] = (C[7] + 0xd34d34d3 + ((C[6] >>> 0) < (C_[6] >>> 0) ? 1 : 0)) | 0;\n\t        this._b = (C[7] >>> 0) < (C_[7] >>> 0) ? 1 : 0;\n\n\t        // Calculate the g-values\n\t        for (var i = 0; i < 8; i++) {\n\t            var gx = X[i] + C[i];\n\n\t            // Construct high and low argument for squaring\n\t            var ga = gx & 0xffff;\n\t            var gb = gx >>> 16;\n\n\t            // Calculate high and low result of squaring\n\t            var gh = ((((ga * ga) >>> 17) + ga * gb) >>> 15) + gb * gb;\n\t            var gl = (((gx & 0xffff0000) * gx) | 0) + (((gx & 0x0000ffff) * gx) | 0);\n\n\t            // High XOR low\n\t            G[i] = gh ^ gl;\n\t        }\n\n\t        // Calculate new state values\n\t        X[0] = (G[0] + ((G[7] << 16) | (G[7] >>> 16)) + ((G[6] << 16) | (G[6] >>> 16))) | 0;\n\t        X[1] = (G[1] + ((G[0] << 8)  | (G[0] >>> 24)) + G[7]) | 0;\n\t        X[2] = (G[2] + ((G[1] << 16) | (G[1] >>> 16)) + ((G[0] << 16) | (G[0] >>> 16))) | 0;\n\t        X[3] = (G[3] + ((G[2] << 8)  | (G[2] >>> 24)) + G[1]) | 0;\n\t        X[4] = (G[4] + ((G[3] << 16) | (G[3] >>> 16)) + ((G[2] << 16) | (G[2] >>> 16))) | 0;\n\t        X[5] = (G[5] + ((G[4] << 8)  | (G[4] >>> 24)) + G[3]) | 0;\n\t        X[6] = (G[6] + ((G[5] << 16) | (G[5] >>> 16)) + ((G[4] << 16) | (G[4] >>> 16))) | 0;\n\t        X[7] = (G[7] + ((G[6] << 8)  | (G[6] >>> 24)) + G[5]) | 0;\n\t    }\n\n\t    /**\n\t     * Shortcut functions to the cipher's object interface.\n\t     *\n\t     * @example\n\t     *\n\t     *     var ciphertext = CryptoJS.RabbitLegacy.encrypt(message, key, cfg);\n\t     *     var plaintext  = CryptoJS.RabbitLegacy.decrypt(ciphertext, key, cfg);\n\t     */\n\t    C.RabbitLegacy = StreamCipher._createHelper(RabbitLegacy);\n\t}());\n\n\n\t/**\n\t * Zero padding strategy.\n\t */\n\tCryptoJS.pad.ZeroPadding = {\n\t    pad: function (data, blockSize) {\n\t        // Shortcut\n\t        var blockSizeBytes = blockSize * 4;\n\n\t        // Pad\n\t        data.clamp();\n\t        data.sigBytes += blockSizeBytes - ((data.sigBytes % blockSizeBytes) || blockSizeBytes);\n\t    },\n\n\t    unpad: function (data) {\n\t        // Shortcut\n\t        var dataWords = data.words;\n\n\t        // Unpad\n\t        var i = data.sigBytes - 1;\n\t        for (var i = data.sigBytes - 1; i >= 0; i--) {\n\t            if (((dataWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff)) {\n\t                data.sigBytes = i + 1;\n\t                break;\n\t            }\n\t        }\n\t    }\n\t};\n\n\n\treturn CryptoJS;\n\n}));"
  },
  {
    "path": "helper.php",
    "content": "<?php\n/**\n * Created by PhpStorm.\n * User: ellermister\n * Date: 2023/11/13\n * Time: 1:20\n */\n\nfunction getRandStr($len)\n{\n    $strs = \"QWERTYUIOPASDFGHJKLZXCVBNM1234567890qwertyuiopasdfghjklzxcvbnm\";\n    $value = '';\n    while (strlen($value) < $len) {\n        $value .= substr(str_shuffle($strs), mt_rand(0, strlen($strs) - 11), $len);\n    }\n    return substr($value, 0, $len);\n}\n\n\nfunction makeMessageJs(string $msg)\n{\n    $javascript = \"(function(){alert(`{{msg}}`)})();\";\n    $javascript = str_replace('{{msg}}', $msg, $javascript);\n    return $javascript;\n}\n\nfunction makeRedirectJs($url, $time = 500)\n{\n    $javascript = 'setTimeout(function(){location.href=\"{{url}}\"},{{time}});';\n    $javascript = str_replace('{{url}}', $url, $javascript);\n    $javascript = str_replace('{{time}}', $time, $javascript);\n    return $javascript;\n}\n\nfunction makeReturnJs($code, $time = 500)\n{\n    $javascript = \"(function(){return window.atob('{{code}}');})();\";\n    $javascript = str_replace('{{code}}', base64_encode($code), $javascript);\n    return $javascript;\n}\n\nfunction base64_encode_url($input) {\n    return strtr(base64_encode($input), '+/=', '._-');\n}\n\nfunction base64_decode_url($input) {\n    return base64_decode(strtr($input, '._-', '+/='));\n}\n\n\n\n\n/**\n * 判断IP是否大陆\n * https://raw.githubusercontent.com/ym/chnroutes2/master/chnroutes.txt 下载与根目录\n *\n * @param $ip\n * @return bool\n */\nfunction ip_is_china($ip)\n{\n    $path = ROOT_PATH . '/chnroutes.txt';\n    if (is_file($path)) {\n        $ipInt = ip2long($ip);\n        $fh = fopen($path, 'r') or exit(\"Unable to open file chnroutes.txt !\");;\n        while (!feof($fh)) {\n            $ipSegment = fgets($fh);\n            if (substr($ipSegment, 0, 1) == '#') {\n                unset($ipSegment);\n                continue;\n            }\n            list($ipBegin, $type) = explode('/', $ipSegment);\n            $ipBegin = ip2long($ipBegin);\n            $mask = 0xFFFFFFFF << (32 - intval($type));\n            if (intval($ipInt & $mask) == intval($ipBegin & $mask)) {\n                unset($raw);\n                fclose($fh);\n                return true;\n            }\n            unset($raw);\n        }\n        fclose($fh);\n    }\n    return false;\n}\n\n\nfunction route($uri, Closure $_route)\n{\n    if (empty($_SERVER['PATH_INFO'])) {\n        $pathInfo = $_SERVER['REQUEST_URI'] ?? '/';\n    } else {\n        $pathInfo = $_SERVER['PATH_INFO'];\n    }\n\n    if (substr($pathInfo, 0, strlen(SUB_PATH)) == SUB_PATH) {\n        $pathInfo = '/' . ltrim(substr($pathInfo, strlen(SUB_PATH)), '/');\n    }\n\n    $pathInfo = preg_replace('/\\?.*?$/is', '', $pathInfo);\n    if (preg_match('#^' . $uri . '$#', $pathInfo, $matches)) {\n        $_route($matches);\n        exit(0);\n    }\n}\n\n\nfunction json($msg, $code = 200, $data = [])\n{\n    $format = [\n        'msg'  => $msg,\n        'code' => $code,\n        'data' => $data\n    ];\n    return json_encode($format, JSON_UNESCAPED_UNICODE);\n}\n\nfunction view($name, $vars = [])\n{\n    $path = ROOT_PATH . DIRECTORY_SEPARATOR . VIEW_PATH . DIRECTORY_SEPARATOR . $name . '.php';\n    extract($vars);\n    @include $path;\n}\n\nfunction abort($status = 404)\n{\n    $path = ROOT_PATH . DIRECTORY_SEPARATOR . $status . '.html';\n    if (is_file($path)) {\n        @include path;\n    } else {\n        echo $status;\n    }\n    die();\n}\n\n\nfunction get_lang()\n{\n    $locale = 'en';\n    $http_accept_language = $_SERVER['HTTP_ACCEPT_LANGUAGE'];\n    preg_match_all(\"/([[:alpha:]]{1,8})(-([[:alpha:]|-]{1,8}))?\" .\n        \"(\\s*;\\s*q\\s*=\\s*(1\\.0{0,3}|0\\.\\d{0,3}))?\\s*(,|$)/i\",\n        $http_accept_language, $hits, PREG_SET_ORDER);\n    if (isset($hits[0])) {\n        $locale = $hits[0][1];\n    }\n    return $locale;\n}\n\nfunction __($name, $_vars = [])\n{\n    return \\Libs\\Languages::trans($name, $_vars);\n}\n\nfunction env(string $name, $default)\n{\n    $value = getenv($name);\n    if($value === false){\n        return $default;\n    }\n    return $value;\n}"
  },
  {
    "path": "index.php",
    "content": "<?php\ndefine('ROOT_PATH', __DIR__);\ndefine('PASS', true);// 访问许可\nspl_autoload_register(function ($class) {\n    require_once __DIR__ . '/' . lcfirst(str_replace('\\\\', '/', $class) . '.php');\n});\n\ninclude(\"helper.php\");\n\ndefine('CACHE_TYPE', env('CACHE_TYPE', 'file'));// 支持REDIS OR FILE\ndefine('CACHE_REDIS_KEY', env('CACHE_REDIS_KEY', ''));// REDIS AUTH KEY\ndefine('CACHE_REDIS_HOST', env('CACHE_REDIS_HOST', '127.0.0.1'));\ndefine('CACHE_REDIS_PORT', intval(env('CACHE_REDIS_PORT', 6379)));\ndefine('CACHE_REDIS_PREFIX', env('CACHE_REDIS_PREFIX', 'shorturl'));\ndefine('CACHE_DIR', env('CACHE_DIR', 'cache'));// FILE模式下缓存目录\ndefine('CACHE_EXPIRE', intval(env('CACHE_EXPIRE', 3600 * 24 * 7)));// 缓存时间，单位秒\ndefine('IS_HTTPS', boolval(env('IS_HTTPS', false)));//是否HTTPS\ndefine('VIEW_PATH', 'view');//视图模板目录\n\ndefine('SUB_PATH', '/');// 子目录： `/` OR `/shorturl/` 必须以 `/` 结尾\ndefine('ENABLE_CLIENT_ENCRYPT', true);\ndefine('ENCRYPT_PASSPHRASE', env('ENCRYPT_PASSPHRASE', 'applicationPassword'));\n\n\\Libs\\Languages::setConfig(include(\"lang.php\"));\n\\Libs\\Languages::setLocale(get_lang());\n\n//--- 入口逻辑  ---//\n\ntry {\n    ob_start();\n    route('/', function () {\n        view('welcome', ['time' => date('Ymd')]);\n    });\n\n    route(\"/s/([A-z0-9]+)\", function ($matches) {\n        $shortURL = new \\Libs\\ShortURL();\n        $data = $shortURL->hashToUrl($matches[1]);\n        // 直接重定向\n        $encrypt_type = ['normal'];\n        $extent = [];\n        if (!empty($data['url'])) {\n            $url = $data['url'];\n            $encrypt_type = $data['encrypt_type'];\n            $extent = $data['extent'] ?? [];\n        }\n        empty($url) && $url = '/404';\n\n        $redirectRequest = new \\Libs\\Redirects\\RedirectRequest(\n            $url,\n            $encrypt_type,\n            $matches[1],\n            $extent,\n        );\n        $redirectRequest->handle();\n    });\n\n    route('/api/link', function ($matches) {\n        $url = $_REQUEST['url'] ?? '';\n        $encrypt_type = $_REQUEST['encrypt_type'] ?? '[\"normal\"]';\n        $extent = $_REQUEST['extent'] ?? '[]';\n        if (null == ($encrypt_type = json_decode($encrypt_type, true))) {\n            $response = json(__('Wrong encode_type parameter'), 500);\n        } else if (empty($url)) {\n            $response = json(__('The url cannot be empty'), 500);\n        } else if (mb_strlen($url) > 2047) {\n            $response = json(__('Too long url'), 500);\n        } else if (mb_strlen($extent) > 10000) {\n            $response = json(__('Too much content'), 500);\n        } else {\n            $extent = json_decode($extent, true);\n            $su = new \\Libs\\ShortURL();\n\n            $response = $su->urlToShort($url, $encrypt_type, $extent ?? []);\n            $response = json(__('Link created successfully'), 200, $response);\n        }\n        echo $response;\n    });\n    route('/api/clean', function () {\n        $count = \\Libs\\Cache\\CacheManager::clearCache(null);\n        echo json(sprintf('clean %s files', $count), 200);\n    });\n\n    route('/404', function () {\n        abort(404);\n    });\n} catch (\\RedisException $exception) {\n    ob_clean();\n    echo sprintf('Redis cannot connect:[%s]%s', $exception->getCode(), $exception->getMessage());\n} catch (\\Exception $exception) {\n    ob_clean();\n    echo sprintf('Site Error:[%s]%s', $exception->getCode(), $exception->getMessage());\n}\n\n"
  },
  {
    "path": "lang.php",
    "content": "<?php\n\n/**\n * Created by PhpStorm.\n * User: ellermister\n * Date: 2023/11/14\n * Time: 01:25\n */\n\nreturn [\n    'en' => [],\n    'zh' => [\n        'GENERATE'             => '生成',\n        'GITHUB'               => 'Github 地址',\n        'ABOUT'                => '关于',\n        'GENERATE SHORT URL'   => '生成短网址',\n        'Quickly generate URL' => '快速生成URL',\n        'Enter URL link'       => '输出URL链接',\n        'Generate'             => '生成',\n        'Firewall'             => '拦截器',\n        'Endpoint'             => '跳转方式',\n\n        'Normal'             => '原始',\n        'No referer'         => '无Referer',\n        'Encrypt redirect'   => '加密跳转',\n        'Fake page'          => '伪装页面',\n        'Redirect once'      => '阅后即焚',\n        'Password access'    => '密码访问',\n        'Whisper text'       => '附加图文',\n        'PC access only'     => '仅限PC访问',\n        'Mobile access only' => '仅限手机访问',\n        'Ban China Browser'  => '屏蔽中国大陆浏览器',\n\n        'Jump directly to the website'                                        => '直接跳转到目标网站',\n        'No Referer parameter'                                                => '无 Referer 参数，目标网站无法获取来源站地址',\n        'Encrypted access, anti-crawler'                                      => '加密跳转参数信息，反大部分爬虫抓取探测',\n        'Use random news, forums, product website information to fool robots' => '使用随机信息、论坛、商品来骗过机器人爬虫',\n        'Jump only once'                                                      => '一次性跳转(阅后即焚)',\n        'Password required'                                                   => '将为你生成密码，访问时需要密码验证',\n        'Append rich text information'                                        => '附加富文本信息，您可以在此留言并分享给您的其他社交媒体用户',\n        'Only PC users can access this page'                                  => '仅限PC用户访问该地址',\n        'Only Mobile users can access this page'                              => '仅限手机用户访问该地址',\n        'Mainland China access only'                                          => '仅限中国大陆访问',\n        'Non-mainland China access only'                                      => '仅限非中国大陆访问',\n        'Please use a non-China browser'                                      => '请使用安全浏览器访问: 如 Chrome, Edge, Firefox',\n        'Please copy this link to open in other browsers'                     => '请复制这个链接到其他浏览器打开',\n\n        'Access only to users in mainland China'          => '仅限中国大陆用户访问',\n        'Only access users who are not in mainland China' => '仅限非中国大陆用户访问',\n\n        'This site generates a total of :url_record_history links，Currently active :url_active_history' => '当前站点历史生成链接:url_record_history个，当前有效:url_active_history个',\n\n        'Password verification failed'                     => '密码验证失败',\n        'Wrong encode_type parameter'                      => '错误的 encode_type 参数',\n        'The url cannot be empty'                          => 'URL不能为空',\n        'Too long url'                                     => 'URL太长',\n        'Too much content'                                 => '内容过多',\n        'Link created successfully'                        => '链接创建成功',\n        'The link can only be accessed via mobile devices' => '该链接只能通过手机移动设备访问',\n        'The link can only be accessed via PC devices'     => '该链接只能通过电脑设备访问',\n        'The link has expired'                             => '链接已经过期',\n    ],\n    'ja' => [\n        'GENERATE'             => '生成',\n        'GITHUB'               => 'Github',\n        'ABOUT'                => 'ついて',\n        'GENERATE SHORT URL'   => '短いURLを生成する',\n        'Quickly generate URL' => 'URLをすばやく生成する',\n        'Enter URL link'       => 'URLリンクを入力します',\n        'Generate'             => '生成',\n        'Firewall'             => 'ファイアウォール',\n        'Endpoint'             => '終点',\n\n        'Normal'                                          => 'デフォルト',\n        'No referer'                                      => '「Referer」パラメータなし',\n        'Encrypt redirect'                                => '暗号化されたアクセス',\n        'Fake Page'                                       => '偽のウェブページ',\n        'Redirect once'                                   => '1回限りの訪問',\n        'Password access'                                 => 'パスワードの検証',\n        'Whisper text'                                    => '追加テキスト',\n        'PC access only'                                  => 'PCアクセスのみ',\n        'Mobile access only'                              => 'モバイルアクセスのみ',\n        'Mainland China access only'                      => '中国本土のユーザーのみがアクセス可能',\n        'Non-mainland China access only'                  => '中国本土以外のユーザーに限定',\n        'Ban China Browser'                               => '中国のブラウザを禁止する',\n        'Please use a non-China browser'                  => '中国以外のブラウザを使用してください',\n        'Please copy this link to open in other browsers' => '他のブラウザで開くには、このリンクをコピーしてください',\n\n        'Jump directly to the website'                                        => 'ターゲットのWebサイトに直接ジャンプします',\n        'No Referer parameter'                                                => '「Referer」パラメータがないと、ターゲットWebサイトは送信元ステーションのアドレスを取得できません',\n        'Encrypted access, anti-crawler'                                      => '暗号化されたジャンプパラメータ情報、ほとんどのクローラーの検出防止',\n        'Use random news, forums, product website information to fool robots' => 'ロボットを欺くためにランダムなニュース、フォーラム、製品のウェブサイト情報を生成する',\n        'Jump only once'                                                      => 'リンクには一度しかアクセスできず、非常に安全です',\n        'Password required'                                                   => 'リンクのパスワードを生成し、アクセス時に確認します',\n        'Append rich text information'                                        => 'テキストメッセージを残すことができます',\n        'Only PC users can access this page'                                  => 'このアドレスにアクセスできるのはPCユーザーのみです',\n        'Only Mobile users can access this page'                              => 'このアドレスにアクセスできるのは携帯電話ユーザーのみです',\n\n        'Access only to users in mainland China'          => '中国本土のユーザーのみがアクセス可能', //このウェブサイトは中国本土でのみアクセスできます\n        'Only access users who are not in mainland China' => '中国本土以外のユーザーに限定',\n\n        'This site generates a total of :url_record_history links，Currently active :url_active_history' => '現在のサイト履歴生成リンク:url_record_historyつのリンク、現在有効:url_active_historyつのリンク',\n\n        'Password verification failed'                     => 'パスワードの確認に失敗しました',\n        'Wrong encode_type parameter'                      => '間違ったencode_typeパラメータ',\n        'The url cannot be empty'                          => 'URLを空にすることはできません',\n        'Too long url'                                     => 'URLが長すぎます',\n        'Too much content'                                 => 'コンテンツが多すぎます',\n        'Link created successfully'                        => 'リンクが正常に作成されました',\n        'The link can only be accessed via mobile devices' => 'リンクにはモバイルデバイス経由でのみアクセスできます',\n        'The link can only be accessed via PC devices'     => 'リンクにはモバイルデバイスからのみアクセスできます',\n        'The link has expired'                             => 'リンクの有効期限が切れています',\n    ]\n];\n"
  },
  {
    "path": "libs/AAEncode.php",
    "content": "<?php\n/**\n * Created by PhpStorm.\n * User: ellermister\n * Date: 2023/11/13\n * Time: 1:50\n */\n\nnamespace Libs;\n\n\nclass AAEncode\n{\n    function charCodeAt($str, $index)\n    {\n        $char = mb_substr($str, $index, 1, 'UTF-8');\n        if (mb_check_encoding($char, 'UTF-8')) {\n            $ret = mb_convert_encoding($char, 'UTF-32BE', 'UTF-8');\n            return hexdec(bin2hex($ret));\n        } else {\n            return null;\n        }\n    }\n\n    function uchr($codes)\n    {\n        if (is_scalar($codes)) $codes = func_get_args();\n        $str = '';\n        foreach ($codes as $code) {\n            $buf = html_entity_decode('&#' . $code . ';', ENT_NOQUOTES, 'UTF-8');\n            $buf == '&#' . $code . ';' && ($buf = mb_convert_encoding('&#' . intval($code) . ';', 'UTF-8', 'HTML-ENTITIES'));\n            $str .= $buf;\n        }\n        return $str;\n    }\n\n    function aaEncode($javascript)\n    {\n        $b = [\n            \"(c^_^o)\",\n            \"(ﾟΘﾟ)\",\n            \"((o^_^o) - (ﾟΘﾟ))\",\n            \"(o^_^o)\",\n            \"(ﾟｰﾟ)\",\n            \"((ﾟｰﾟ) + (ﾟΘﾟ))\",\n            \"((o^_^o) +(o^_^o))\",\n            \"((ﾟｰﾟ) + (o^_^o))\",\n            \"((ﾟｰﾟ) + (ﾟｰﾟ))\",\n            \"((ﾟｰﾟ) + (ﾟｰﾟ) + (ﾟΘﾟ))\",\n            \"(ﾟДﾟ) .ﾟωﾟﾉ\",\n            \"(ﾟДﾟ) .ﾟΘﾟﾉ\",\n            \"(ﾟДﾟ) ['c']\",\n            \"(ﾟДﾟ) .ﾟｰﾟﾉ\",\n            \"(ﾟДﾟ) .ﾟДﾟﾉ\",\n            \"(ﾟДﾟ) [ﾟΘﾟ]\"\n        ];\n        $r = \"ﾟωﾟﾉ= /｀ｍ´）ﾉ ~┻━┻   //*´∇｀*/ ['_']; o=(ﾟｰﾟ)  =_=3; c=(ﾟΘﾟ) =(ﾟｰﾟ)-(ﾟｰﾟ); \";\n        if (preg_match('/ひだまりスケッチ×(365|３５６)\\s*来週も見てくださいね[!！]/', $javascript)) {\n            $r .= \"X=_=3; \";\n            $r .= \"\\r\\n\\r\\n    X / _ / X < \\\"来週も見てくださいね!\\\";\\r\\n\\r\\n\";\n        }\n        $r .= \"(ﾟДﾟ) =(ﾟΘﾟ)= (o^_^o)/ (o^_^o);\" .\n            \"(ﾟДﾟ)={ﾟΘﾟ: '_' ,ﾟωﾟﾉ : ((ﾟωﾟﾉ==3) +'_') [ﾟΘﾟ] \" .\n            \",ﾟｰﾟﾉ :(ﾟωﾟﾉ+ '_')[o^_^o -(ﾟΘﾟ)] \" .\n            \",ﾟДﾟﾉ:((ﾟｰﾟ==3) +'_')[ﾟｰﾟ] }; (ﾟДﾟ) [ﾟΘﾟ] =((ﾟωﾟﾉ==3) +'_') [c^_^o];\" .\n            \"(ﾟДﾟ) ['c'] = ((ﾟДﾟ)+'_') [ (ﾟｰﾟ)+(ﾟｰﾟ)-(ﾟΘﾟ) ];\" .\n            \"(ﾟДﾟ) ['o'] = ((ﾟДﾟ)+'_') [ﾟΘﾟ];\" .\n            \"(ﾟoﾟ)=(ﾟДﾟ) ['c']+(ﾟДﾟ) ['o']+(ﾟωﾟﾉ +'_')[ﾟΘﾟ]+ ((ﾟωﾟﾉ==3) +'_') [ﾟｰﾟ] + \" .\n            \"((ﾟДﾟ) +'_') [(ﾟｰﾟ)+(ﾟｰﾟ)]+ ((ﾟｰﾟ==3) +'_') [ﾟΘﾟ]+\" .\n            \"((ﾟｰﾟ==3) +'_') [(ﾟｰﾟ) - (ﾟΘﾟ)]+(ﾟДﾟ) ['c']+\" .\n            \"((ﾟДﾟ)+'_') [(ﾟｰﾟ)+(ﾟｰﾟ)]+ (ﾟДﾟ) ['o']+\" .\n            \"((ﾟｰﾟ==3) +'_') [ﾟΘﾟ];(ﾟДﾟ) ['_'] =(o^_^o) [ﾟoﾟ] [ﾟoﾟ];\" .\n            \"(ﾟεﾟ)=((ﾟｰﾟ==3) +'_') [ﾟΘﾟ]+ (ﾟДﾟ) .ﾟДﾟﾉ+\" .\n            \"((ﾟДﾟ)+'_') [(ﾟｰﾟ) + (ﾟｰﾟ)]+((ﾟｰﾟ==3) +'_') [o^_^o -ﾟΘﾟ]+\" .\n            \"((ﾟｰﾟ==3) +'_') [ﾟΘﾟ]+ (ﾟωﾟﾉ +'_') [ﾟΘﾟ]; \" .\n            \"(ﾟｰﾟ)+=(ﾟΘﾟ); (ﾟДﾟ)[ﾟεﾟ]='\\\\\\\\'; \" .\n            \"(ﾟДﾟ).ﾟΘﾟﾉ=(ﾟДﾟ+ ﾟｰﾟ)[o^_^o -(ﾟΘﾟ)];\" .\n            \"(oﾟｰﾟo)=(ﾟωﾟﾉ +'_')[c^_^o];\" .\n            \"(ﾟДﾟ) [ﾟoﾟ]='\\\\\\\"';\" .\n            \"(ﾟДﾟ) ['_'] ( (ﾟДﾟ) ['_'] (ﾟεﾟ+\";\n        $r .= \"(ﾟДﾟ)[ﾟoﾟ]+ \";\n\n        for ($i = 0; $i < mb_strlen($javascript); $i++) {\n            $n = $this->charCodeAt($javascript, $i);\n            $t = \"(ﾟДﾟ)[ﾟεﾟ]+\";\n            if ($n <= 127) {\n                $t .= preg_replace_callback('/[0-7]/', function ($c) use ($b) {\n                    return $b[$c[0]] . \"+ \";\n                }, ((string)decoct($n)));\n            } else {\n                if (preg_match('/[0-9a-f]{4}$/', '000' . ((string)dechex($n)), $result)) {\n                    $m = $result[0];\n                } else {\n                    $m = '';\n                }\n                $t .= \"(oﾟｰﾟo)+ \" . preg_replace_callback('/[0-9a-f]/i', function ($c) use ($b) {\n                        return $b[hexdec($c[0])] . \"+ \";\n                    }, $m);\n            }\n            $r .= $t;\n        }\n\n        $r .= \"(ﾟДﾟ)[ﾟoﾟ]) (ﾟΘﾟ)) ('_');\";\n        return $r;\n\n    }\n}"
  },
  {
    "path": "libs/Cache/Cache.php",
    "content": "<?php\nnamespace Libs\\Cache;\n/**\n * Created by PhpStorm.\n * User: ellermister\n * Date: 2023/11/12\n * Time: 23:58\n */\n\nabstract class Cache\n{\n    abstract public function putCache(string $name, $value, int $timeout);\n    abstract public function getCache(string $name);\n    abstract public function hasCache(string $name):bool;\n    abstract public function clearCache(string $name);\n}"
  },
  {
    "path": "libs/Cache/CacheManager.php",
    "content": "<?php\n/**\n * Created by PhpStorm.\n * User: ellermister\n * Date: 2023/11/13\n * Time: 0:29\n */\n\nnamespace Libs\\Cache;\n\n/**\n * Class CacheManager\n * @package Libs\n *\n * @method static void putCache(string $name, $value, int $timeout)\n * @method static mixed getCache(string $name)\n * @method  static bool hasCache(string $name)\n * @method  static int clearCache(string $name = null)\n */\nclass CacheManager\n{\n    protected $provider;\n\n    private static $instance;\n\n    public function __construct()\n    {\n        $engine = strtolower(CACHE_TYPE);;\n        if (!in_array(CACHE_TYPE, ['file', 'redis'])) {\n            throw new \\RuntimeException(sprintf('不支持的缓存方法: %s', $engine));\n        }\n\n        if ($engine == 'file') {\n            $this->provider = new FileCache();\n        }\n        if ($engine == 'redis') {\n            $this->provider = new RedisCache();\n        }\n    }\n\n    public function __call($name, $arguments)\n    {\n        return call_user_func_array([$this->provider, $name], $arguments);\n    }\n\n    public static function __callStatic($name, $arguments)\n    {\n        if(!self::$instance){\n            self::$instance = new static();\n        }\n        return call_user_func_array([self::$instance->provider, $name], $arguments);\n    }\n}"
  },
  {
    "path": "libs/Cache/FileCache.php",
    "content": "<?php\n/**\n * Created by PhpStorm.\n * User: ellermister\n * Date: 2023/11/13\n * Time: 0:11\n */\n\nnamespace Libs\\Cache;\n\n\nuse Libs\\ShortURL;\n\n/**\n * Class FileCache\n * 文件缓存不支持指定过期时间，采用全局固定的过期时间\n * @package Libs\n */\nclass FileCache extends Cache\n{\n    protected $cacheDIR;\n\n    public function __construct()\n    {\n        $this->cacheDIR = ROOT_PATH . DIRECTORY_SEPARATOR . CACHE_DIR;\n        if (!is_dir($this->cacheDIR)) {\n            if (!mkdir($this->cacheDIR, 0644)) {\n                throw new \\RuntimeException(\"缓存目录不存在\");\n            }\n        }\n        $this->cacheDIR = rtrim($this->cacheDIR, '/');\n    }\n\n    public function putCache(string $name, $value, int $timeout)\n    {\n        file_put_contents($this->cacheDIR . DIRECTORY_SEPARATOR . $name . '.data', serialize($value));\n    }\n\n    public function getCache(string $name)\n    {\n        $raw = @file_get_contents($this->cacheDIR . DIRECTORY_SEPARATOR . $name . '.data');\n        return unserialize($raw);\n    }\n\n    public function hasCache(string $name): bool\n    {\n        return is_file($this->cacheDIR . DIRECTORY_SEPARATOR . $name . '.data');\n    }\n\n    public function clearCache(string $name = null)\n    {\n        if ($name === null) {\n            $list = scandir($this->cacheDIR);\n            $currentTime = time();\n            foreach ($list as $file) {\n                if ($file == '.' or $file == '..' or !preg_match('/^(url|request)_/i', $file))\n                    continue;\n                $path = $this->cacheDIR . DIRECTORY_SEPARATOR . $file;\n\n                if ($currentTime - filemtime($path) > CACHE_EXPIRE) {\n                    if (preg_match('/^((url|request)_[A-z0-9]+)\\.[A-z]+$/', $file, $matches)) {\n                        $cache = $this->getCache($matches[1]);\n                        $url = $cache['url'];\n                        $su = new ShortURL();\n                        @unlink($path) && $count++ && $su->cleanUrlRecord($url);\n                        unset($url);\n                    }\n                }\n            }\n        } else {\n            $path = $this->cacheDIR . DIRECTORY_SEPARATOR . $name . '.data';\n            if (is_file($path)) {\n                @unlink($path);\n            }\n        }\n\n    }\n\n\n}"
  },
  {
    "path": "libs/Cache/RedisCache.php",
    "content": "<?php\n\nnamespace Libs\\Cache;\n\nuse RuntimeException;\n\n/**\n * Created by PhpStorm.\n * User: ellermister\n * Date: 2023/11/12\n * Time: 23:57\n */\nclass RedisCache extends Cache\n{\n\n    /**\n     * @var \\Redis\n     */\n    protected $redis;\n\n    public function __construct()\n    {\n        $this->redis = $this->getConnect();\n    }\n\n    /**\n     * @return \\Redis\n     */\n    private function getConnect(): \\Redis\n    {\n        $redis = new \\Redis();\n        $redis->connect(CACHE_REDIS_HOST, CACHE_REDIS_PORT);\n        CACHE_REDIS_KEY && $redis->auth(CACHE_REDIS_KEY);\n        if ($redis->isConnected()) {\n            return $redis;\n        }\n        throw new RuntimeException(\"Redis 连接失败!\",);\n    }\n\n\n    public function putCache(string $name, $value, int $timeout)\n    {\n        $value = serialize($value);\n        $this->redis->set(CACHE_REDIS_PREFIX . $name, $value, $timeout);\n    }\n\n    public function getCache(string $name)\n    {\n        $value = $this->redis->get(CACHE_REDIS_PREFIX . $name);\n        return unserialize($value);\n    }\n\n    public function hasCache(string $name): bool\n    {\n        return $this->redis->exists(CACHE_REDIS_PREFIX . $name);\n    }\n\n    public function clearCache(string $name = null): int\n    {\n        $count = 0;\n        if ($name === null) {\n            $iterator = null;\n            while ($list = $this->redis->scan($iterator, CACHE_REDIS_PREFIX . '*', 200)) {\n                $chunk_keys = array_chunk($list, 50);\n                foreach ($chunk_keys as $keys) {\n                    $this->redis->del(...$keys);\n                    $count += count($keys);\n                }\n            }\n        } else {\n            $count = $this->redis->del(CACHE_REDIS_PREFIX . $name);\n        }\n\n        return $count;\n    }\n\n\n}"
  },
  {
    "path": "libs/EncryptTool.php",
    "content": "<?php\n/**\n * Created by PhpStorm.\n * User: ellermister\n * Date: 2023/11/13\n * Time: 20:00\n */\n\nnamespace Libs;\n\n\nclass EncryptTool\n{\n\n    /**\n     * Compatibility method for handling UTF-8 characters and common encryption/decryption in JavaScript.\n     *\n     * Note: The key does not support UTF-8 characters.\n     *\n     * @param string $key\n     * @param string $plaintext\n     * @return string\n     */\n    public static function encrypt($key, $plaintext): string\n    {\n        $cypherText = [];\n        // Convert to hexadecimal to correctly handle UTF-8\n        $plaintext = implode('', array_map(function ($c) {\n            if (ord($c) < 128) {\n                return dechex(ord($c));\n            } else {\n                return bin2hex($c);\n//            return strtolower(rawurlencode($c));\n            }\n        }, preg_split('//u', $plaintext, -1, PREG_SPLIT_NO_EMPTY)));\n\n        // Convert each hexadecimal to decimal\n        $plaintext = array_map('hexdec', str_split($plaintext, 2));\n\n        // Perform XOR operation\n        for ($i = 0; $i < count($plaintext); $i++) {\n            $cypherText[] = $plaintext[$i] ^ ord($key[($i % strlen($key))]);\n        }\n\n        // Convert to hexadecimal, pad 2\n        $cypherText = array_map(function ($x) {\n            return sprintf(\"%02X\", $x);\n//            return dechex($x);\n        }, $cypherText);\n        return implode('', $cypherText);\n    }\n\n    /**\n     * Decrypts the given ciphertext using the specified key.\n     *\n     * @param string $key\n     * @param string $cypherText\n     * @return string|bool The decrypted plaintext or false on failure.\n     */\n    static function decrypt($key, $cypherText)\n    {\n        try {\n            // Convert hexadecimal string to an array of integers\n            $cypherText = array_map('hexdec', str_split($cypherText, 2));\n\n            $plaintext = [];\n\n            for ($i = 0; $i < count($cypherText); $i++) {\n                // Perform XOR operation and convert to hexadecimal string\n                $plaintext[] = dechex($cypherText[$i] ^ ord($key[($i % strlen($key))]));\n            }\n\n            // Convert hexadecimal string to URL-encoded string\n            $decodedPlaintext = '%' . implode('%', $plaintext);\n            // Decode URL-encoded string to the original plaintext\n            return rawurldecode($decodedPlaintext);\n        } catch (\\Exception $e) {\n            return false;\n        }\n    }\n\n\n\n    const ENCRYPT_METHOD = 'AES-128-CBC';\n\n\n    public static function createEncryptDataForURLSafe(array $data): string\n    {\n        $iv = openssl_random_pseudo_bytes(16);\n        $passphrase = substr(md5(ENCRYPT_PASSPHRASE), 0, 16);\n        $raw = serialize($data);\n        $encrypted = openssl_encrypt($raw, self::ENCRYPT_METHOD, $passphrase, 0, $iv);\n\n        return base64_encode_url(sprintf('%s,%s', $iv, $encrypted));\n    }\n\n    public static function parseEncryptDataForURLSafe($data)\n    {\n        $passphrase = substr(md5(ENCRYPT_PASSPHRASE), 0, 16);\n        $data = base64_decode_url($data);\n\n        $iv = substr($data, 0, 16);\n\n        $plain = openssl_decrypt(substr($data, 16), self::ENCRYPT_METHOD, $passphrase, 0, $iv);\n        return unserialize($plain);\n    }\n\n    public static function initGuestPass()\n    {\n        session_start();\n        return $_SESSION['guest_pass'] = getRandStr(32);\n    }\n\n    public static function getGuestPass()\n    {\n        session_start();\n        return $_SESSION['guest_pass'] ?? null;\n    }\n\n}\n"
  },
  {
    "path": "libs/Languages.php",
    "content": "<?php\n/**\n * Created by PhpStorm.\n * User: ellermister\n * Date: 2023/11/14\n * Time: 11:19\n */\n\nnamespace Libs;\n\n\nclass Languages\n{\n\n    protected static $data = [];\n    protected static $lang = '';\n\n    public static function setConfig(array $data = [])\n    {\n        self::$data = $data;\n    }\n\n\n    public static function setLocale(string $lang)\n    {\n        self::$lang = $lang;\n    }\n\n    public static function trans(string $name, array $_vars = [])\n    {\n        $locale = self::$lang;\n        if (!isset(self::$data[$locale])) {\n            $locale = 'en';\n        }\n        if (!isset(self::$data[$locale][$name])) {\n            $locale = 'en';\n        }\n        $text = self::$data[$locale][$name] ?? $name;\n        foreach ($_vars as $name => $value) {\n            $text = str_replace(\":$name\", $value, $text);\n        }\n        return $text;\n    }\n}"
  },
  {
    "path": "libs/Redirects/BanChinaBrowser.php",
    "content": "<?php\n/**\n * Created by PhpStorm.\n * User: ellermister\n * Date: 2023/11/17\n * Time: 23:40\n */\n\nnamespace Libs\\Redirects;\n\n\nclass BanChinaBrowser extends Handler\n{\n\n    const KEYWORD_IN_USERAGENT = [\n        'bidubrowser',\n        'metasr',\n        'tencenttraveler',\n        'MicroMessenger',\n        'MiuiBrowser',\n        'YodaoBot',\n        'IqiyiApp',\n        'Weibo',\n        'qq',\n        'QQBrowser',\n        'Quark',\n        'MetaSr',\n        'SNEBUY-APP',\n        'AlipayClient',\n        'AliApp',\n        '115Browser',\n        '2345Explorer',\n        'Mb2345Browser',\n        '2345chrome',\n        'QihooBrowser',\n        'QHBrowser',\n        '360Spider',\n        'HaosouSpider',\n        'BIDUBrowser',\n        'baidubrowser',\n        'baiduboxapp',\n        'BaiduD',\n        'DingTalk',\n        'douban.frodo',\n        'aweme',\n        'HuaweiBrowser',\n        'HUAWEI',\n        'HONOR',\n        'HBPC',\n        'LBBROWSER',\n        'LieBaoFast',\n        'MZBrowser',\n        'HeyTapBrowser',\n        'OPPO',\n        'Opera',\n        'VivoBrowser',\n    ];\n\n    function getHandlerName(): string\n    {\n        return \"ban_china_browser\";\n    }\n\n    function requireAuthorize(): bool\n    {\n        return true;\n    }\n\n    function isAuthorize(): bool\n    {\n        $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? '';\n        $userAgent = strtolower($userAgent);\n        foreach (self::KEYWORD_IN_USERAGENT as $value) {\n            if (strpos($userAgent, strtolower($value)) !== false) {\n                view('ban_china_browser', ['url' => $this->data['url']]);\n                return false;\n            }\n        }\n        return true;\n    }\n\n    function showPage(): bool\n    {\n        return false;\n    }\n\n}"
  },
  {
    "path": "libs/Redirects/ChinaOnlyHandler.php",
    "content": "<?php\n/**\n * Created by PhpStorm.\n * User: ellermister\n * Date: 2023/11/14\n * Time: 2:41\n */\n\nnamespace Libs\\Redirects;\n\n\nuse Libs\\EncryptTool;\n\nclass ChinaOnlyHandler extends Handler\n{\n    function getHandlerName(): string\n    {\n        return 'china_only';\n    }\n\n    function requireAuthorize(): bool\n    {\n        return true;\n    }\n\n    function isAuthorize(): bool\n    {\n        $clientIP = $this->request->getClientIP();\n        if (!ip_is_china($clientIP)) {\n            throw new MessageException(__('Access only to users in mainland China'));\n        }\n        return false;\n    }\n\n    function showPage(): bool\n    {\n       return false;\n    }\n\n}"
  },
  {
    "path": "libs/Redirects/DynamicHandler.php",
    "content": "<?php\n/**\n * Created by PhpStorm.\n * User: ellermister\n * Date: 2023/11/14\n * Time: 03:47\n */\n\nnamespace Libs\\Redirects;\n\n\n/**\n * Class DynamicHandler\n * 所谓动态方式就是 no referer\n * @package Libs\\Redirects\n */\nclass DynamicHandler extends Handler\n{\n    function getHandlerName(): string\n    {\n        return \"dynamic\";\n    }\n\n    function requireAuthorize(): bool\n    {\n        return false;\n    }\n\n    function isAuthorize(): bool\n    {\n        return true;\n    }\n\n    function showPage(): bool\n    {\n        view('dynamic', [\n            'url' => $this->data['url'],\n        ]);\n        return true;\n    }\n\n}"
  },
  {
    "path": "libs/Redirects/EncryptHandler.php",
    "content": "<?php\n/**\n * Created by PhpStorm.\n * User: ellermister\n * Date: 2023/11/13\n * Time: 22:25\n */\n\nnamespace Libs\\Redirects;\n\n\nuse Libs\\EncryptTool;\n\nclass EncryptHandler extends Handler\n{\n\n\n    function isAuthorize(): bool\n    {\n        return false;\n    }\n\n    function showPage(): bool\n    {\n        if (isset($_GET['a'])) {\n            $payload = file_get_contents(\"php://input\");\n            $data = EncryptTool::parseEncryptDataForURLSafe($payload);\n\n            if ((time() - intval($data['timestamp'])) > 30) {\n                echo \"1\" . makeMessageJs(__('The link has expired'));\n            } else {\n                echo \"0\" . EncryptTool::encrypt($data['pass'], makeRedirectJs($data['url']));\n            }\n\n            return true;\n        } else {\n            // 第一步，封装一个 token 给POST请求使用,\n            // 这个 token 只能使用一次，并且存在时间校验\n            $pass = getRandStr(16); // 客户端自己解密时需要的KEY\n\n            $cipher = EncryptTool::createEncryptDataForURLSafe([\n                'user_agent' => $_SERVER['HTTP_USER_AGENT'],\n                'timestamp'  => time(),\n                'url'        => $this->data['url'],\n                'pass'       => $pass,\n            ]);\n            $render['encrypt_data'] = sprintf('%s,%s', $pass, $cipher);\n\n            view('encrypt', $render);\n        }\n        return false;\n    }\n\n    function getHandlerName(): string\n    {\n        return \"encrypt\";\n    }\n\n    function requireAuthorize(): bool\n    {\n        return false;\n    }\n}"
  },
  {
    "path": "libs/Redirects/FakePageHandler.php",
    "content": "<?php\n/**\n * Created by PhpStorm.\n * User: ellermister\n * Date: 2023/11/14\n * Time: 4:18\n */\n\nnamespace Libs\\Redirects;\n\n\n/**\n * Class FakePageHandler\n * 更改性质，仅在认证失败时返回伪装页面\n *\n * @package Libs\\Redirects\n */\nclass FakePageHandler extends Handler\n{\n\n    function getHandlerName(): string\n    {\n        return \"fake_page\";\n    }\n\n    function requireAuthorize(): bool\n    {\n        return false;\n    }\n\n    function isAuthorize(): bool\n    {\n        return true;\n    }\n\n    function showPage(): bool\n    {\n        return false;\n    }\n\n\n    /**\n     * 异常页面，如伪装页面使用\n     */\n    public function exceptionPage(): bool\n    {\n        $url = 'https://item.jd.com/10000' . (str_pad(rand(0, 9999999), 7, '0')) . '.html';\n        header('Location: '.$url);\n        return true;\n    }\n}"
  },
  {
    "path": "libs/Redirects/Handler.php",
    "content": "<?php\n/**\n * Created by PhpStorm.\n * User: ellermister\n * Date: 2023/11/13\n * Time: 22:23\n */\n\nnamespace Libs\\Redirects;\n\n\n/**\n * 处理器内部不要使用 exit 之类中断执行，着重在 showPage 体内不能中断，因为外部还会有一些事件的落地\n *\n * Class Handler\n * @package Libs\\Redirects\n */\nabstract class Handler\n{\n\n    const EVENT_FIRST = 'EVENT_FIRST';\n    const EVENT_SHOW_PAGE = 'EVENT_SHOW_PAGE';\n    const EVENT_DONE = 'EVENT_DONE';\n    const EVENT_EXCEPTION_PAGE = 'EVENT_EXCEPTION_PAGE';\n\n    protected $data = [];\n\n    protected $request;\n\n    public function __construct(array $data, RedirectRequest $request)\n    {\n        $this->data = $data;\n        $this->request = $request;\n    }\n\n    abstract function getHandlerName(): string;\n\n    /**\n     * 用于外部判断验证是否需要授权\n     * @return bool\n     */\n    abstract function requireAuthorize(): bool;\n\n    /**\n     * 内部执行返回是否通过授权的结果\n     * @return bool\n     */\n    abstract function isAuthorize(): bool;\n\n    /**\n     * 展示最终的页面或者最终跳转的函数执行体\n     * @return bool\n     */\n    abstract function showPage(): bool;\n\n    /**\n     * 完成事件，不做抽象要求，可继承重写\n     * 仅对于showPage完成时生效\n     */\n    public function done()\n    {\n\n    }\n\n\n    /**\n     * 异常页面，如伪装页面使用\n     */\n    public function exceptionPage() :bool\n    {\n\n        return false;\n    }\n\n\n    /**\n     * @param string $event\n     * @param RedirectRequest $request\n     * @return bool isBlock isHandle\n     */\n    function notify(string $event, RedirectRequest $request): bool\n    {\n        if (!$request->hasTypes($this->getHandlerName())) {\n            return false;\n        }\n\n        switch ($event){\n            case self::EVENT_FIRST:\n                // 如果需要授权，并且没有获得授权则进行拦截\n                if ($this->requireAuthorize() && !$this->isAuthorize()) {\n                    return true;\n                }\n                break;\n            case self::EVENT_SHOW_PAGE:\n                return $this->showPage();\n                break;\n            case self::EVENT_DONE:\n                $this->done();\n                break;\n            case self::EVENT_EXCEPTION_PAGE:\n                error_log(sprintf('exception.handler>%s',get_class($this)));\n                return $this->exceptionPage();\n                break;\n        }\n\n        return false;\n    }\n\n}"
  },
  {
    "path": "libs/Redirects/MessageException.php",
    "content": "<?php\n/**\n * Created by PhpStorm.\n * User: ellermister\n * Date: 2023/11/14\n * Time: 3:15\n */\n\nnamespace Libs\\Redirects;\n\n\nclass MessageException extends \\RuntimeException\n{\n\n}"
  },
  {
    "path": "libs/Redirects/MobileOnlyHandler.php",
    "content": "<?php\n/**\n * Created by PhpStorm.\n * User: ellermister\n * Date: 2023/11/14\n * Time: 2:41\n */\n\nnamespace Libs\\Redirects;\n\n\nuse Libs\\EncryptTool;\n\nclass MobileOnlyHandler extends Handler\n{\n    function getHandlerName(): string\n    {\n        return 'mobile_only';\n    }\n\n    function requireAuthorize(): bool\n    {\n        return true;\n    }\n\n    function isAuthorize(): bool\n    {\n        if (isset($_GET['client'])) {\n            $client = $this->request->getClient();\n            if ($client) {\n                // https://uiiiuiii.com/screen/ 手机设备屏幕尺寸\n                if ($client->outerWidth() <= 1284 && $client->outerHeight() <= 2778 && $client->outerHeight() > $client->outerWidth()) {\n                    return true;\n                }\n                if (strtolower($client->platform()) == 'iphone' && stripos($client->appVersion(), 'windows') !== false) {\n                    return true;\n                }\n\n                throw new MessageException(__('The link can only be accessed via mobile devices'));\n            }\n        }\n        view('client');\n        return false;\n    }\n\n    function showPage(): bool\n    {\n        return false;\n    }\n\n}"
  },
  {
    "path": "libs/Redirects/NonChinaOnlyHandler.php",
    "content": "<?php\n/**\n * Created by PhpStorm.\n * User: ellermister\n * Date: 2023/11/14\n * Time: 2:41\n */\n\nnamespace Libs\\Redirects;\n\n\nuse Libs\\EncryptTool;\n\nclass NonChinaOnlyHandler extends Handler\n{\n    function getHandlerName(): string\n    {\n        return 'non_china_only';\n    }\n\n    function requireAuthorize(): bool\n    {\n        return true;\n    }\n\n    function isAuthorize(): bool\n    {\n        $clientIP = $this->request->getClientIP();\n        if (ip_is_china($clientIP)) {\n            throw new MessageException(__('Only access users who are not in mainland China'));\n        }\n        return false;\n    }\n\n    function showPage(): bool\n    {\n       return false;\n    }\n\n}"
  },
  {
    "path": "libs/Redirects/NormalHandler.php",
    "content": "<?php\n/**\n * Created by PhpStorm.\n * User: ellermister\n * Date: 2023/11/14\n * Time: 3:38\n */\n\nnamespace Libs\\Redirects;\n\n\nclass NormalHandler extends Handler\n{\n    function getHandlerName(): string\n    {\n       return \"normal\";\n    }\n\n    function requireAuthorize(): bool\n    {\n       return false;\n    }\n\n    function isAuthorize(): bool\n    {\n        return true;\n    }\n\n    function showPage(): bool\n    {\n        header('Location: '.$this->data['url']);\n        return true;\n    }\n\n}"
  },
  {
    "path": "libs/Redirects/OnceHandler.php",
    "content": "<?php\n/**\n * Created by PhpStorm.\n * User: ellermister\n * Date: 2023/11/14\n * Time: 3:59\n */\n\nnamespace Libs\\Redirects;\n\n\nuse Libs\\ShortURL;\n\nclass OnceHandler extends Handler\n{\n    function getHandlerName(): string\n    {\n        return \"once\";\n    }\n\n    function requireAuthorize(): bool\n    {\n       return false;\n    }\n\n    function isAuthorize(): bool\n    {\n        return true;\n    }\n\n    function showPage(): bool\n    {\n       return false;\n    }\n\n    public function done()\n    {\n        $su = new ShortURL();\n        $su->removeHash($this->data['hash']);\n    }\n\n\n}"
  },
  {
    "path": "libs/Redirects/PCOnlyHandler.php",
    "content": "<?php\n/**\n * Created by PhpStorm.\n * User: ellermister\n * Date: 2023/11/14\n * Time: 2:41\n */\n\nnamespace Libs\\Redirects;\n\n\nuse Libs\\EncryptTool;\n\nclass PCOnlyHandler extends Handler\n{\n    function getHandlerName(): string\n    {\n        return 'pc_only';\n    }\n\n    function requireAuthorize(): bool\n    {\n        return true;\n    }\n\n    function isAuthorize(): bool\n    {\n        if(isset($_GET['client'])){\n            $client = $this->request->getClient();\n            if($client){\n                if($client->outerWidth() >= 1920 && $client->outerHeight() >= 1024){\n                    return  true;\n                }\n                if(strtolower($client->platform()) == 'win32' && stripos($client->appVersion(), 'windows') !==false){\n                    return  true;\n                }\n\n                throw new MessageException(__('The link can only be accessed via mobile devices'));\n            }\n        }\n        view('client');\n        return false;\n    }\n\n    function showPage(): bool\n    {\n       return false;\n    }\n\n}"
  },
  {
    "path": "libs/Redirects/PasswordHandler.php",
    "content": "<?php\n/**\n * Created by PhpStorm.\n * User: ellermister\n * Date: 2023/11/14\n * Time: 2:19\n */\n\nnamespace Libs\\Redirects;\n\n\nclass PasswordHandler extends Handler\n{\n    function getHandlerName(): string\n    {\n        return \"password\";\n    }\n\n    function isAuthorize(): bool\n    {\n        if (isset($_REQUEST['pass'])) {\n            if($_REQUEST['pass'] == $this->data['extend']['password']){\n                return true;\n            }\n        }\n        view('password');\n        return false;\n    }\n\n    function showPage(): bool\n    {\n        return false;\n    }\n\n    function requireAuthorize(): bool\n    {\n        return true;\n    }\n}"
  },
  {
    "path": "libs/Redirects/RedirectRequest.php",
    "content": "<?php\n/**\n * Created by PhpStorm.\n * User: ellermister\n * Date: 2023/11/13\n * Time: 1:55\n */\n\nnamespace Libs\\Redirects;\n\n\nuse Libs\\EncryptTool;\n\n/**\n * Class RedirectHandler\n *\n * @package Libs\n */\nclass RedirectRequest\n{\n\n    protected $url;\n    protected $hash;\n    /**\n     * @var array normal,encrypt,password\n     */\n    protected $encryptTypes = [];\n    protected $extend = [];\n\n\n    /**\n     * @var array\n     */\n    protected $handlers = [];\n\n    public function __construct(string $url, array $encryptTypes, string $hash, array $extend)\n    {\n        $this->url = $url;\n        $this->encryptTypes = $encryptTypes;\n        $this->hash = $hash;\n        $this->extend = $extend;\n\n        // 优先级\n        $this->handlers = [\n            $this->makeHandler(BanChinaBrowser::class),\n            $this->makeHandler(WhisperHandler::class),\n            $this->makeHandler(EncryptHandler::class),\n            $this->makeHandler(PasswordHandler::class),\n            $this->makeHandler(PCOnlyHandler::class),\n            $this->makeHandler(MobileOnlyHandler::class),\n            $this->makeHandler(NormalHandler::class),\n            $this->makeHandler(OnceHandler::class),\n            $this->makeHandler(FakePageHandler::class),\n            $this->makeHandler(DynamicHandler::class),\n        ];\n    }\n\n    /**\n     * @param string $class\n     * @return Handler\n     */\n    function makeHandler(string $class): Handler\n    {\n        return new $class(array(\n            'url'          => $this->url,\n            'hash'         => $this->hash,\n            'encryptTypes' => $this->encryptTypes,\n            'extend'       => $this->extend,\n        ), $this);\n    }\n\n\n    public function hasTypes(string $name): bool\n    {\n        return in_array($name, $this->encryptTypes);\n    }\n\n    protected function notify($event): bool\n    {\n        foreach ($this->handlers as $handler) {\n            if ($this->hasTypes($handler->getHandlerName())) {\n                if ($handler->notify($event, $this)) {\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n\n    public function handle()\n    {\n\n        try {\n            if ($this->notify(Handler::EVENT_FIRST)) {\n                // 被拦截，则终止\n                exit(0);\n            }\n\n\n            if ($this->notify(Handler::EVENT_SHOW_PAGE)) {\n                // 渲染完成再去通知完成\n                $this->notify(Handler::EVENT_DONE);\n            }\n\n        } catch (MessageException $exception) {\n            // write log\n            error_log(sprintf('%s: %s', $exception->getFile(), $exception->getMessage()));\n\n            // 这个回调不允许报错\n            if (!$this->notify(Handler::EVENT_EXCEPTION_PAGE)) {\n\n                // 如果没有处理器处理，则直接报错\n                throw $exception;\n            }\n        }\n    }\n\n\n    public function getClientIP(): string\n    {\n        $clientIP = $_SERVER['REMOTE_ADDR'];\n        if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {\n            $clientIP = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])[0];\n        }\n        return $clientIP;\n    }\n\n\n    public function getClient()\n    {\n        if (isset($_GET['client'])) {\n            $guestPass = EncryptTool::getGuestPass();\n            if ($guestPass) {\n                $clientData = EncryptTool::decrypt($guestPass, $_GET['client']);\n            } else {\n                $clientData = urldecode($_GET['client']);\n\n            }\n            $result = explode('|||', $clientData);\n            if (count($result) !== 5) {\n                error_log(sprintf('客户端请求被修改:' . $clientData));\n                return null;\n            }\n            list($appVersion, $appName, $platform, $outerWidth, $outerHeight) = $result;\n            $data = [\n                'appVersion'  => $appVersion,\n                'appName'     => $appName,\n                'platform'    => $platform,\n                'outerWidth'  => $outerWidth,\n                'outerHeight' => $outerHeight,\n            ];\n\n            return new class($data) implements UserClient {\n                protected $data = [];\n\n                public function __construct(array $data)\n                {\n                    $this->data = $data;\n                }\n\n                public function appVersion()\n                {\n                    return $this->data['appVersion'];\n                }\n\n                public function appName()\n                {\n                    return $this->data['appName'];\n                }\n\n                public function platform()\n                {\n                    return $this->data['platform'];\n                }\n\n                public function outerWidth()\n                {\n                    return $this->data['outerWidth'];\n                }\n\n                public function outerHeight()\n                {\n                    return $this->data['outerHeight'];\n                }\n\n            };\n        }\n        return null;\n    }\n}"
  },
  {
    "path": "libs/Redirects/UserClient.php",
    "content": "<?php\n/**\n * Created by PhpStorm.\n * User: ellermister\n * Date: 2023/11/14\n * Time: 12:05\n */\n\nnamespace Libs\\Redirects;\n\n\ninterface UserClient\n{\n\n    public function appVersion();\n    public function appName();\n    public function platform();\n    public function outerWidth();\n    public function outerHeight();\n}"
  },
  {
    "path": "libs/Redirects/WhisperHandler.php",
    "content": "<?php\n/**\n * Created by PhpStorm.\n * User: ellermister\n * Date: 2023/11/14\n * Time: 3:43\n */\n\nnamespace Libs\\Redirects;\n\n\nclass WhisperHandler extends Handler\n{\n    function getHandlerName(): string\n    {\n        return \"whisper\";\n    }\n\n    function requireAuthorize(): bool\n    {\n        return false;\n    }\n\n    function isAuthorize(): bool\n    {\n        return true;\n    }\n\n    function showPage(): bool\n    {\n        view('whisper2', [\n            'url'     => $this->data['url'],\n            'whisper' => $this->data['extend']['whisper'],\n        ]);\n\n        return true;\n    }\n\n}"
  },
  {
    "path": "libs/ShortURL.php",
    "content": "<?php\n/**\n * Created by PhpStorm.\n * User: ellermister\n * Date: 2023/11/13\n * Time: 1:21\n */\n\nnamespace Libs;\n\n\nclass ShortURL\n{\n\n    public function getRandStr($len)\n    {\n        $strs = \"QWERTYUIOPASDFGHJKLZXCVBNM1234567890qwertyuiopasdfghjklzxcvbnm\";\n        $value = '';\n        while (strlen($value) < $len) {\n            $value .= substr(str_shuffle($strs), mt_rand(0, strlen($strs) - 11), $len);\n        }\n        return substr($value, 0, $len);\n    }\n\n    /**\n     * 获取一个可用的哈希\n     * @return false|string\n     */\n    public function urlHash()\n    {\n        $hash = $this->getRandStr(5);\n        $cm = new \\Libs\\Cache\\CacheManager();\n        while ($cm->hasCache('url_' . $hash)) {\n            $hash = $this->getRandStr(5);\n        }\n        return $hash;\n    }\n\n\n    /**\n     * 映射URL和HASH关系\n     *\n     * @param $url\n     * @param $encrypt_type\n     * @param $extent\n     * @return bool|string\n     */\n    public function urlToHash($url, $encrypt_type, $extent)\n    {\n        $hash = $this->urlHash();\n        $cm = new \\Libs\\Cache\\CacheManager();\n        $cm->putCache('url_' . $hash, ['url' => $url, 'encrypt_type' => $encrypt_type, 'extent' => $extent], -1);\n        return $hash;\n    }\n\n\n    /**\n     * 从HASH中还原URL\n     *\n     * @param $hash\n     * @return mixed|string\n     */\n    public function hashToUrl($hash)\n    {\n        $cm = new \\Libs\\Cache\\CacheManager();\n        if ($cm->hasCache('url_' . $hash)) {\n            $url = $cm->getCache('url_' . $hash);\n        }\n        return $url ?? '';\n    }\n\n\n    /**\n     * 移除 hash\n     * @param string $hash\n     */\n    public function removeHash(string $hash)\n    {\n        $cm = new \\Libs\\Cache\\CacheManager();\n        $cm->clearCache(\"url_\".$hash);\n    }\n\n\n    /**\n     * URL转短链接\n     *\n     * @param $url\n     * @param string $encrypt_type\n     * @param string $extent\n     * @return string\n     */\n    public function urlToShort($url, $encrypt_type = 'encrypt', $extent = '')\n    {\n        if (!preg_match('/^[A-z]+:\\/\\//i', $url)) {\n            $url = 'http://' . $url;\n        }\n        $id = $this->urlToHash($url, $encrypt_type, $extent);\n        $shortUrl = sprintf('%s://%s/%s/%s', IS_HTTPS ? 'https' : 'http', $_SERVER['HTTP_HOST'], ltrim(SUB_PATH, '/') . 's', $id);\n        $this->addUrlRecord($url);\n        return ($shortUrl);\n    }\n\n    /**\n     * 自增统计URL生成次数\n     *\n     * @param $url\n     */\n    public function addUrlRecord($url)\n    {\n        $cache = [];\n        $cm = new \\Libs\\Cache\\CacheManager();\n        if ($cm->hasCache('manage')) {\n            $cache = $cm->getCache('manage');\n        }\n        $cache[$url] = isset($cache[$url]) ? $cache[$url] + 1 : 1;\n        $cm = new \\Libs\\Cache\\CacheManager();\n        $cm->putCache('manage', $cache, -1);\n        $this->addUrlRecordHistory($url);\n    }\n\n\n    function getUrlRecord($url = false)\n    {\n        $count = 0;\n        $cache = [];\n        $cm = new \\Libs\\Cache\\CacheManager();\n        if ($cm->hasCache('manage')) {\n            $cache = $cm->getCache('manage');\n        }\n        if ($url) {\n            $count += $cache[$url];\n        } else {\n            foreach ($cache as $value) {\n                $count += intval($value);\n            }\n        }\n\n        return $count;\n    }\n\n    function cleanUrlRecord($url = false)\n    {\n        $cache = [];\n        $cm = new \\Libs\\Cache\\CacheManager();\n        if ($cm->hasCache('manage')) {\n            $cache = $cm->getCache('manage');\n        }\n        if ($url) {\n            unset($cache[$url]);\n        } else {\n            $cache = [];\n        }\n\n        $cm = new \\Libs\\Cache\\CacheManager();\n        $cm->putCache('manage', $cache, -1);\n    }\n\n    /**\n     * 自增统计URL历史生成次数\n     *\n     * @param $url\n     */\n    function addUrlRecordHistory($url)\n    {\n        $cache = [];\n        $cm = new \\Libs\\Cache\\CacheManager();\n        if ($cm->hasCache('history')) {\n            $cache = $cm->getCache('history');\n        }\n        $cache['count'] = isset($cache['count']) ? $cache['count'] + 1 : 1;\n        $cache['url'][] = $url;\n\n        $cm = new \\Libs\\Cache\\CacheManager();\n        $cm->putCache('history', $cache, -1);\n    }\n\n    function getUrlRecordHistory()\n    {\n        $cache = [];\n        $cm = new \\Libs\\Cache\\CacheManager();\n        if ($cm->hasCache('history')) {\n            $cache = $cm->getCache('history');\n        }\n        return $cache['count'] ?? 0;\n    }\n}"
  },
  {
    "path": "static/basic.js",
    "content": "function encryptUTF8(key, plaintext) {\n    let cyphertext = [];\n    // Convert to hex to properly handle UTF8\n    plaintext = Array.from(plaintext).map(function(c) {\n        if(c.charCodeAt(0) < 128) return c.charCodeAt(0).toString(16).padStart(2, '0');\n        else return encodeURIComponent(c).replace(/\\%/g,'').toLowerCase();\n    }).join('');\n    \n    // Convert each hex to decimal\n    plaintext = plaintext.match(/.{1,2}/g).map(x => parseInt(x, 16));\n    // Perform xor operation\n    for (let i = 0; i < plaintext.length; i++) {\n        cyphertext.push(plaintext[i] ^ key.charCodeAt(Math.floor(i % key.length)));\n    }\n    // Convert to hex\n    cyphertext = cyphertext.map(function(x) {\n        return x.toString(16).padStart(2, '0');\n    });\n    return cyphertext.join('');\n}\n\n// Super simple XOR decrypt function\nfunction decryptUTF8(key, cyphertext) {\n    try {\n        cyphertext = cyphertext.match(/.{1,2}/g).map(x => parseInt(x, 16));\n        let plaintext = [];\n        for (let i = 0; i < cyphertext.length; i++) {\n            plaintext.push((cyphertext[i] ^ key.charCodeAt(Math.floor(i % key.length))).toString(16).padStart(2, '0'));\n        }\n        return decodeURIComponent('%' + plaintext.join('').match(/.{1,2}/g).join('%'));\n    }\n    catch(e) {\n        return false;\n    }\n}"
  },
  {
    "path": "view/ban_china_browser.php",
    "content": "<!DOCTYPE html>\n<html lang=\"<?php echo get_lang() ?>\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>WARNING</title>\n    <meta name=\"referrer\" content=\"no-referrer\" />\n    <style>\n        .main-tips{\n            text-align: center;\n            padding: 20px;\n            flex-direction: column;\n            align-items: center;\n            display: flex;\n        }\n        .main-tips h2{\n            user-select: none;\n        }\n        .main-tips pre{\n            padding: 12px;\n            background: #ccc;\n        }\n    </style>\n</head>\n\n<body>\n    <div class=\"main-tips\">\n        <h2><?php echo __('Please use a non-China browser');?></h2>\n        <pre onclick=\"allSelectContent()\" id=\"url\"></pre>\n        <label><?php echo __('Please copy this link to open in other browsers');?></label>\n    </div>\n    <script>\n        let safeURL = new URL(location.href)\n        safeURL.search = \"\"\n\n        let url = document.getElementById('url')\n        url.innerText = safeURL.href\n\n        function allSelectContent(){\n            let url = document.getElementById('url')\n            var selection = document.getSelection()\n\n            var range = document.createRange()\n            range.selectNode(url)\n\n            selection.removeAllRanges()\n            selection.addRange(range)\n        }\n    </script>\n</body>\n</html>"
  },
  {
    "path": "view/client.php",
    "content": "<!DOCTYPE html>\n<html lang=\"<?php echo get_lang() ?>\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>redirecting...</title>\n    <meta name=\"referrer\" content=\"no-referrer\" />\n    <script src=\"/static/basic.js\"></script>\n    <script>\n        const url = new URL(document.location);\n\n        if (url.searchParams.has(\"client\")) {\n            url.searchParams.delete('client');\n        }\n\n        let pass = \"<?php echo ENABLE_CLIENT_ENCRYPT?  \\Libs\\EncryptTool::initGuestPass():''; ?>\";\n        let clientData = `${window.navigator.appVersion}|||${window.navigator.appName}|||${window.navigator.platform}|||${window.outerWidth}|||${window.outerHeight}`\n        if(pass){\n            url.searchParams.append(\"client\", encryptUTF8(pass, clientData))\n        }else{\n            url.searchParams.append(\"client\", encodeURI(clientData))\n        }\n        console.debug(`url = ${url}`)\n        location.href = url\n    </script>\n</head>\n</html>"
  },
  {
    "path": "view/dynamic.php",
    "content": "<!DOCTYPE html>\n<html lang=\"<?php echo get_lang() ?>\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>redirecting....</title>\n    <meta name=\"referrer\" content=\"no-referrer\" />\n    <script>\n        document.location.href = '<?php echo $url;?>';\n    </script>\n</head>\n<body>\n    \n</body>\n</html>"
  },
  {
    "path": "view/encrypt.php",
    "content": "<!DOCTYPE html>\n<html lang=\"<?php echo get_lang() ?>\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>rediecting</title>\n    <meta name=\"referrer\" content=\"no-referrer\" />\n    <script src=\"/static/basic.js\"></script>\n\n    <script type=\"text/plain\" id=\"data\">\n        <?php \n            echo $encrypt_data;\n        ?>\n    </script>\n    <script>\n        var data = document.getElementById('data').text.trim()\n        var req = new XMLHttpRequest();\n        const url = new URL(document.location);\n        url.searchParams.append(\"a\",\"1\")\n        req.open('POST', url, true);\n        req.send(data.split(',')[1]);\n        req.onload = function() {\n            let flag = req.response.substr(0, 1)\n            if(flag == \"1\"){\n                eval(req.response.substr(1))\n            }else{\n                let key = data.split(',')[0]\n                let js = decryptUTF8(key, req.response.substr(1))\n                console.debug(`js = ${js}`)\n                eval(js)\n            }\n        }\n    </script>\n</head>\n<body>\n    \n</body>\n</html>"
  },
  {
    "path": "view/password.php",
    "content": "<!doctype html>\n<html lang=\"<?php echo get_lang() ?>\">\n<head>\n    <!-- Required meta tags -->\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n    <!-- Bootstrap CSS -->\n    <link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css\" integrity=\"sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm\" crossorigin=\"anonymous\">\n    <title>password auth!</title>\n    <meta name=\"referrer\" content=\"no-referrer\" />\n</head>\n<body>\n<div class=\"modal fade\" id=\"passwordModal\" tabindex=\"-1\" role=\"dialog\" aria-labelledby=\"passwordModal\" aria-hidden=\"true\">\n  <div class=\"modal-dialog\" role=\"document\">\n    <div class=\"modal-content\">\n      <div class=\"modal-header\">\n        <h5 class=\"modal-title\" id=\"exampleModalLabel\">Plase input</h5>\n        <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\">\n          <span aria-hidden=\"true\">&times;</span>\n        </button>\n      </div>\n      <div class=\"modal-body\">\n        <form>\n          <div class=\"form-group\">\n            <label for=\"input-password\" class=\"col-form-label\">Password:</label>\n            <input type=\"password\" class=\"form-control\" id=\"input-password\">\n          </div>\n        </form>\n      </div>\n      <div class=\"modal-footer\">\n        <button type=\"button\" class=\"btn btn-secondary\" data-dismiss=\"modal\">Close</button>\n        <button type=\"button\" class=\"btn btn-primary\" id=\"next\">Next</button>\n      </div>\n    </div>\n  </div>\n</div>\n\n<!-- Optional JavaScript -->\n<!-- jQuery first, then Popper.js, then Bootstrap JS -->\n<script src=\"https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js\" ></script>\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js\" integrity=\"sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q\" crossorigin=\"anonymous\"></script>\n<script src=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js\" integrity=\"sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl\" crossorigin=\"anonymous\"></script>\n<script type=\"text/javascript\">\n\t$('#passwordModal').modal({backdrop: 'static', keyboard: false});\n\t$('#next').click(function(){\n\t\tlet password = $('#input-password').val();\n\n    const url = new URL(document.location);\n\n    if(url.searchParams.has(\"pass\")){\n      url.searchParams.delete('pass');\n    }\n\n    url.searchParams.append(\"pass\", password)\n    \n\n    console.debug(`url = ${url}`)\n    location.href = url\n\t});\n</script>\n</body>\n</html>"
  },
  {
    "path": "view/welcome.php",
    "content": "<?php defined('PASS') or die('unauthorized access!') ?>\n<!DOCTYPE html>\n<html lang=\"<?php echo get_lang() ?>\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n    <title>GENERATE SHORT URL</title>\n    <link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css\">\n    <link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/editor.md@1.5.0/css/editormd.min.css\"/>\n    <style type=\"text/css\">\n        .hidden {\n            display: none;\n        }\n    </style>\n</head>\n<body>\n\n<div style=\"margin-bottom: 1rem;\">\n    <nav class=\"navbar navbar-expand-lg navbar-dark bg-dark\">\n        <a class=\"navbar-brand\" href=\"/\">SHORTURL</a>\n        <button class=\"navbar-toggler\" type=\"button\" data-toggle=\"collapse\" data-target=\"#navbarNavAltMarkup\"\n                aria-controls=\"navbarNavAltMarkup\" aria-expanded=\"false\" aria-label=\"Toggle navigation\">\n            <span class=\"navbar-toggler-icon\"></span>\n        </button>\n        <div class=\"collapse navbar-collapse\" id=\"navbarNavAltMarkup\">\n            <div class=\"navbar-nav\">\n                <a class=\"nav-item nav-link active\" href=\"/\"><?php echo __('GENERATE') ?> <span class=\"sr-only\">(current)</span></a>\n                <a class=\"nav-item nav-link\"\n                   href=\"https://github.com/ellermister/shorturl\"><?php echo __('GITHUB') ?></a>\n                <a class=\"nav-item nav-link\" href=\"https://github.com/ellermister\"><?php echo __('ABOUT') ?></a>\n            </div>\n        </div>\n    </nav>\n</div>\n\n<div class=\"container\">\n\n    <div class=\"card text-center\">\n        <div class=\"card-header\">\n            <?php echo __('GENERATE SHORT URL') ?>\n        </div>\n        <div class=\"card-body\">\n            <h5 class=\"card-title\"><?php echo __('Quickly generate URL') ?></h5>\n\n            <!-- <div class=\"form-group\">\n                <label for=\"urlTextInput\">URL</label>\n                <input type=\"text\" id=\"urlTextInput\" class=\"form-control\" placeholder=\"Enter URL link\">\n            </div> -->\n\n            <div class=\"input-group mb-3\">\n                <input type=\"text\" id=\"urlTextInput\" class=\"form-control\"\n                       placeholder=\"<?php echo __('Enter URL link') ?>\">\n                <div class=\"input-group-append\">\n                    <button class=\"btn btn-primary\" type=\"button\" id=\"generate\"\n                            onclick=\"javascript:generate()\"><?php echo __('Generate') ?></button>\n                </div>\n            </div>\n            <div class=\"mb-3\" id=\"extent-element\">\n                <h5><?php echo __('Firewall')?></h5>\n                <div class=\"custom-control custom-checkbox custom-control-inline\">\n                    <input type=\"checkbox\" id=\"radio-ban-china_browser\" name=\"encrypt_type\" class=\"custom-control-input\"\n                           value=\"ban_china_browser\" checked=\"\">\n                    <label class=\"custom-control-label\" for=\"radio-ban-china_browser\"><?php echo __('Ban China Browser') ?></label>\n                </div>\n                <div class=\"custom-control custom-checkbox custom-control-inline\">\n                    <input type=\"checkbox\" id=\"radio-fake-page\" name=\"encrypt_type\" class=\"custom-control-input\"\n                           value=\"fake_page\" checked=\"\">\n                    <label class=\"custom-control-label\" for=\"radio-fake-page\"><?php echo __('Fake page') ?></label>\n                </div>\n                <div class=\"custom-control custom-checkbox custom-control-inline\">\n                    <input type=\"checkbox\" id=\"radio-once\" name=\"encrypt_type\" class=\"custom-control-input\"\n                           value=\"once\">\n                    <label class=\"custom-control-label\" for=\"radio-once\"><?php echo __('Redirect once') ?></label>\n                </div>\n                <div class=\"custom-control custom-checkbox custom-control-inline\">\n                    <input type=\"checkbox\" id=\"radio-password\" name=\"encrypt_type\" class=\"custom-control-input\"\n                           value=\"password\">\n                    <label class=\"custom-control-label\" for=\"radio-password\"><?php echo __('Password access') ?></label>\n                </div>\n                <div class=\"custom-control custom-checkbox custom-control-inline\">\n                    <input type=\"checkbox\" id=\"radio-pc-only\" name=\"encrypt_type\" class=\"custom-control-input\"\n                           value=\"pc_only\">\n                    <label class=\"custom-control-label\" for=\"radio-pc-only\"><?php echo __('PC access only') ?></label>\n                </div>\n                <div class=\"custom-control custom-checkbox custom-control-inline\">\n                    <input type=\"checkbox\" id=\"radio-mobile-only\" name=\"encrypt_type\" class=\"custom-control-input\"\n                           value=\"mobile_only\">\n                    <label class=\"custom-control-label\"\n                           for=\"radio-mobile-only\"><?php echo __('Mobile access only') ?></label>\n                </div>\n                <div class=\"custom-control custom-checkbox custom-control-inline\">\n                    <input type=\"checkbox\" id=\"radio-china-only\" name=\"encrypt_type\" class=\"custom-control-input\"\n                           value=\"china_only\">\n                    <label class=\"custom-control-label\"\n                           for=\"radio-china-only\"><?php echo __('Mainland China access only') ?></label>\n                </div>\n                <div class=\"custom-control custom-checkbox custom-control-inline\">\n                    <input type=\"checkbox\" id=\"radio-non-china-only\" name=\"encrypt_type\" class=\"custom-control-input\"\n                           value=\"non_china_only\">\n                    <label class=\"custom-control-label\"\n                           for=\"radio-non-china-only\"><?php echo __('Non-mainland China access only') ?></label>\n                </div>\n                <h5 class=\"mt-2\"><?php echo __('Endpoint');?></h5>\n                <div class=\"custom-control custom-checkbox custom-control-inline\">\n                    <input type=\"checkbox\" id=\"radio-normal\" name=\"encrypt_type\" class=\"custom-control-input\"\n                           value=\"normal\">\n                    <label class=\"custom-control-label\" for=\"radio-normal\"><?php echo __('Normal') ?></label>\n                </div>\n                <div class=\"custom-control custom-checkbox custom-control-inline\">\n                    <input type=\"checkbox\" id=\"radio-dynamic\" name=\"encrypt_type\" class=\"custom-control-input\"\n                           value=\"dynamic\">\n                    <label class=\"custom-control-label\" for=\"radio-dynamic\"><?php echo __('No referer') ?></label>\n                </div>\n                <div class=\"custom-control custom-checkbox custom-control-inline\">\n                    <input type=\"checkbox\" id=\"radio-encrypt\" name=\"encrypt_type\" class=\"custom-control-input\"\n                           value=\"encrypt\" checked=\"\">\n                    <label class=\"custom-control-label\" for=\"radio-encrypt\"><?php echo __('Encrypt redirect') ?></label>\n                </div>\n                <div class=\"custom-control custom-checkbox custom-control-inline\" style=\"display: inline-block;\">\n                    <input type=\"checkbox\" id=\"radio-whisper\" name=\"encrypt_type\" class=\"custom-control-input\"\n                           value=\"whisper\">\n                    <label class=\"custom-control-label\" for=\"radio-whisper\"><?php echo __('Whisper text') ?></label>\n                </div>\n            </div>\n\n            <div class=\"card\">\n                <div class=\"card-body text-left\">\n                    <p><b> 🏄🏼‍♀️ <?php echo __('Normal') ?>: </b><?php echo __('Jump directly to the website') ?><br>\n                        <b>🐸<?php echo __('No referer') ?>: </b><?php echo __('No Referer parameter') ?><br>\n                        <b>🕷 <?php echo __('Encrypt redirect') ?>\n                            : </b><?php echo __('Encrypted access, anti-crawler') ?><br>\n                        <b>👺 <?php echo __('Fake page') ?>\n                            : </b><?php echo __('Use random news, forums, product website information to fool robots') ?>\n                        <br>\n                        <b>🔥 <?php echo __('Redirect once') ?>: </b><?php echo __('Jump only once') ?><br>\n                        <b>🔑 <?php echo __('Password access') ?>: </b><?php echo __('Password required') ?><br>\n                        <b>📝 <?php echo __('Whisper text') ?>: </b><?php echo __('Append rich text information') ?><br>\n                        <b>💻 <?php echo __('PC access only') ?>\n                            : </b><?php echo __('Only PC users can access this page') ?><br>\n                        <b>📱 <?php echo __('Mobile access only') ?>\n                            : </b><?php echo __('Only Mobile users can access this page') ?><br>\n                        <b>🇨🇳 <?php echo __('Access only to users in mainland China') ?>\n                            : </b><?php echo __('Access only to users in mainland China') ?><br>\n                        <b>🗺️ <?php echo __('Only access users who are not in mainland China') ?>\n                            : </b><?php echo __('Only access users who are not in mainland China') ?><br>\n                    </p>\n                </div>\n            </div>\n\n            <div class=\"form-group hidden\" extent=\"radio-password\">\n                <label for=\"input-password\">Password</label>\n                <input type=\"password\" class=\"form-control\" id=\"input-password\" placeholder=\"Password\">\n            </div>\n            <div class=\"form-group hidden\" extent=\"radio-whisper\">\n                <label for=\"exampleFormControlTextarea1\">whisper</label>\n                <div id=\"editor\" style=\"width: 100%;height: 500px;\">\n                    <!-- Tips: Editor.md can auto append a `<textarea>` tag -->\n                    <textarea id=\"input-whisper\" style=\"display:none;\">### Write a message...</textarea>\n                </div>\n            </div>\n\n            <div id=\"let-dialog\"></div>\n\n            <div class=\"modal\" tabindex=\"-1\" role=\"dialog\">\n                <div class=\"modal-dialog\" role=\"document\">\n                    <div class=\"modal-content\">\n                        <div class=\"modal-header\">\n                            <h5 class=\"modal-title\">Result</h5>\n                            <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\">\n                                <span aria-hidden=\"true\">&times;</span>\n                            </button>\n                        </div>\n                        <div class=\"modal-body\">\n                            <p id=\"copy-text\"><input type=\"text\" name=\"\" id=\"\" value=\"https://www.baidu.com\"\n                                                     readonly=\"readonly\"/></p>\n                            <p id=\"copy-result\"></p>\n                        </div>\n                        <div class=\"modal-footer\">\n                            <button type=\"button\" class=\"btn btn-primary\" onclick=\"javascript:copy()\">Copy</button>\n                            <button type=\"button\" class=\"btn btn-secondary\" data-dismiss=\"modal\">Close</button>\n                        </div>\n                    </div>\n                </div>\n            </div>\n\n        </div>\n        <div class=\"card-footer text-muted\">\n            <?php\n            $su = new \\Libs\\ShortURL();\n            echo __('This site generates a total of :url_record_history links，Currently active :url_active_history', ['url_record_history' => $su->getUrlRecordHistory(), 'url_active_history' => $su->getUrlRecord()]) ?>\n            。\n        </div>\n    </div>\n</div>\n\n\n<script src=\"https://cdn.jsdelivr.net/npm/jquery@3.2.1/dist/jquery.min.js\"></script>\n\n<script src=\"https://cdn.jsdelivr.net/npm/popper.js@1.12.9/dist/umd/popper.min.js\"></script>\n<script src=\"https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/js/bootstrap.min.js\"></script>\n<script src=\"https://cdn.jsdelivr.net/npm/editor.md@1.5.0/editormd.min.js\"></script>\n<script type=\"text/html\" id=\"tpl-alert\">\n    <div class=\"alert alert-{{status}} alert-dismissible fade show\" role=\"alert\">\n        <strong>{{status}}!</strong> {{message}}\n        <button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-label=\"Close\">\n            <span aria-hidden=\"true\">&times;</span>\n        </button>\n    </div>\n</script>\n<script type=\"text/javascript\">\n    var editor = null;\n\n    function message(msg, status) {\n        let html = $('#tpl-alert').html();\n        html = html.replace(new RegExp('{{message}}', 'g'), msg);\n        html = html.replace(new RegExp('{{status}}', 'g'), status);\n        $('#let-dialog').html(html);\n    }\n\n    function copy() {\n        $('#copy-text input').select();\n        $('#copy-text input').get(0).setSelectionRange(0, $('#copy-text input').val().length);\n        if (document.execCommand('copy')) {\n            document.execCommand('copy');\n            $('#copy-result').text('copy success!');\n        }\n\n    }\n\n    function cancelCheckedForForm(name, value){\n        $(`[name=\"${name}\"][value=\"${value}\"]`).prop('checked', false);\n    }\n\n    $('#extent-element input[type=\"checkbox\"]').click(function () {\n        var name = $(this).attr('name');\n        $('[extent]').hide();\n        let current = $(this).val();\n        console.log(\"current:\", current);\n        var selected = [];\n        $('[name=\"' + name + '\"]:checked').each(function () {\n            selected.push($(this).val());\n        });\n        // 原始单选 冲突\n        let bindingEndpoint = [\n            'normal',\n            'dynamic',\n            'encrypt',\n            'whisper',\n        ]\n\n        let currentSelected = $(this).val()\n        if(bindingEndpoint.indexOf(currentSelected) > -1){\n            bindingEndpoint.filter(i => i!=currentSelected).map( i =>{\n                cancelCheckedForForm(name, i)\n            })\n        }\n\n        // PC、手机选择 冲突\n        if (current == 'pc_only') {\n            cancelCheckedForForm(name, 'mobile_only')\n        } else if (current == 'mobile_only') {\n            cancelCheckedForForm(name, 'pc_only')\n        }\n        // 大陆、非大陆 冲突\n        if (current == 'china_only') {\n            cancelCheckedForForm(name, 'non_china_only')\n        } else if (current == 'non_china_only') {\n            cancelCheckedForForm(name, 'china_only')\n        }\n\n        let id = $(this).attr('id');\n        $('#extent-element input[type=\"checkbox\"]').each(function () {\n            if (selected.indexOf($(this).val()) != -1) {\n                $('[extent=\"' + $(this).attr('id') + '\"]').show();\n            }\n        });\n        // 富文本首次初始化\n        if (id == 'radio-whisper' && editor == null) {\n            editor = editormd(\"editor\", {\n                // width: \"630px\",\n                height: 630,\n                path: \"https://cdn.jsdelivr.net/npm/editor.md@1.5.0/lib/\"  // Autoload modules mode, codemirror, marked... dependents libs path\n            });\n        }\n\n\n        if(current == \"password\"){\n            $('#input-password').focus();\n        }\n\n    });\n\n    function generate() {\n        let url = $('#urlTextInput').val();\n        var selected = [];\n        let extent = {}\n        $('input[name=\"encrypt_type\"]:checked').each(function () {\n            let encrypt_type = $(this).val();\n            selected.push(encrypt_type);\n            extent[encrypt_type] = $('#input-' + encrypt_type).val();\n        });\n        $.ajax({\n            type: \"post\",\n            url: \"<?php echo rtrim(SUB_PATH,'/');?>/api/link\",\n            async: true,\n            dataType: 'json',\n            data: {url: url, encrypt_type: JSON.stringify(selected), extent: JSON.stringify(extent)},\n            success: function (result) {\n                if (result.code === 200) {\n                    // convert to https if need\n                    let shortURL = new URL(result.data)\n                    shortURL.protocol = window.location.protocol\n                    $('#copy-text input').val(shortURL);\n                    message(result.msg, 'success');\n                    $('.modal').modal('show');\n                } else {\n                    message(result.msg, 'error');\n                }\n            }\n        });\n    }\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "view/whisper2.php",
    "content": "<!doctype html>\n<html lang=\"<?php echo get_lang() ?>\">\n<head>\n    <!-- Required meta tags -->\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n    <!-- Bootstrap CSS -->\n    <link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css\"\n          integrity=\"sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm\" crossorigin=\"anonymous\">\n    <link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/editor.md@1.5.0/css/editormd.min.css\"/>\n    <link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/editor.md@1.5.0/css/editormd.preview.css\"/>\n\n    <title>Whisper text!</title>\n</head>\n<body>\n<div class=\"container-fluid\" style=\"margin-top: 40px;\">\n    <a  href=\"<?php echo $url; ?>\" class=\"btn btn-primary btn-lg\" role=\"button\">See details</a>\n    <div id=\"editormd-view\">\n        <textarea style=\"display:none;\" name=\"editormd-markdown-doc\"></textarea>\n    </div>\n</div>\n\n<!-- Optional JavaScript -->\n<!-- jQuery first, then Popper.js, then Bootstrap JS -->\n<script src=\"https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js\"></script>\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js\"\n        integrity=\"sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q\"\n        crossorigin=\"anonymous\"></script>\n<script src=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js\"\n        integrity=\"sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl\"\n        crossorigin=\"anonymous\"></script>\n<script src=\"https://cdn.jsdelivr.net/npm/editor.md@1.5.0/lib/marked.min.js\"></script>\n<script src=\"https://cdn.jsdelivr.net/npm/editor.md@1.5.0/lib/prettify.min.js\"></script>\n<script src=\"https://cdn.jsdelivr.net/npm/editor.md@1.5.0/lib/flowchart.min.js\"></script>\n<script src=\"https://cdn.jsdelivr.net/npm/editor.md@1.5.0/editormd.min.js\"></script>\n\n<script>\n\nfunction showMarkdown(whisper) {\n    let editormdView = editormd.markdownToHTML(\"editormd-view\", {\n        markdown: whisper,\n        //htmlDecode      : true,       // 开启 HTML 标签解析，为了安全性，默认不开启\n        htmlDecode: \"style,script,iframe\",  // you can filter tags decode\n        //toc             : false,\n        tocm: true,    // Using [TOCM]\n        //tocContainer    : \"#custom-toc-container\", // 自定义 ToC 容器层\n        //gfm             : false,\n        //tocDropdown     : true,\n        // markdownSourceCode : true, // 是否保留 Markdown 源码，即是否删除保存源码的 Textarea 标签\n        emoji: true,\n        taskList: true\n    });\n}\n\nshowMarkdown(window.atob(\"<?php echo base64_encode($whisper); ?>\"));\n\n</script>\n</body>\n</html>"
  }
]