[
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\ncharset = utf-8\nindent_style = space\nindent_size = 2\nend_of_line = lf\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n"
  },
  {
    "path": ".eslintignore",
    "content": "/lib\ncoverage/\npackages/*/node_modules\npackages/*/lib\npackages/*/dist\npackages/*/test/fixtures\npackages/*/coverage\npackages/wepy-cli/templates\npackages/cli/test/core/fixtures\ngulpfile.js\n\n"
  },
  {
    "path": ".eslintrc",
    "content": "{\n  \"parser\": \"babel-eslint\",\n  \"env\": {\n    \"es6\": true,\n    \"node\": true,\n    \"mocha\": true\n  },\n  \"rules\": {\n    \"strict\": [0],\n    \"eqeqeq\": 2,\n    \"quotes\": [2, \"single\", {\"allowTemplateLiterals\": true}],\n    \"no-underscore-dangle\": 0,\n    \"eol-last\": 0,\n    \"camelcase\": 0,\n    \"no-loop-func\": 0,\n    \"no-trailing-spaces\": 0,\n    \"consistent-return\": 0,\n    \"new-cap\": 0,\n    \"no-shadow\": 0,\n    //\"semi\": 0,\n    \"no-process-exit\": 0,\n    \"no-empty\": 0,\n    \"yoda\": 0,\n    \"no-new-func\": 0\n  }\n}\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "content": "提交ISSUE前请确保已认真阅读以下内容\n\n*Please read the following information carefully before you open an issue.*\n\n\n在提交issue之前必须确认以下问题：\n\n*Please make sure you understand the following points:*\n\n\n* 必须是一个bug或者功能新增。\n\n* *It must be a bug or a feature request*\n\n\n* 必须是WePY相关问题，原生小程序问题去[开发者论坛](https://developers.weixin.qq.com/)。\n\n* *It must be a WePY issue.*\n\n\n* 已经在issue中搜索过，并且没有找到相似的issue或者解决方案。\n\n* *I searched issue already but I didn't find any relevant issues or solutions.*\n\n\n* 完善下面模板中的信息\n\n* *Please fill out the following template*\n\n\n\n阅读完后请在提交的issue中删除以上内容，包括分割线\n\nDELETE THE INFORMATION ABOVE(INCLUDE THE SEPARATION LINE) BEFORE YOU OPEN AN ISSUE\n\n------------------------\n## Description\n\n  [问题描述：站在其它人的角度尽可能清晰地、简洁地把问题描述清楚]\n  \n  [Description of the issue]\n\n## Environment\n\n  * Platform: [开发者工具/iOS/Andriod/Web]\n  * Platform version: [对应工具或者iOS或者Andriod的版本号]\n  * Wechat version: [微信版本号]\n  * wepy-cli version: [wepy-cli -v]\n  * wepy version: [在package.json里]\n  * other version: [如果是插件问题，请列出问题插件的版本号]\n  \n## Reproduce\n\n  [如何重现问题]\n  \n  [How to reproduce the issue]\n\n### Observed Results\n\n  [实际表现]\n  \n  [Observed Results]\n  \n### Expected Results\n\n  [期望表现]\n  \n  [Expected Results]\n  \n\n## Relevant Code / Logs\n\n  ```\n  // TODO(you): code or logs here to reproduce the problem\n  // 可以使用小程序代码片段功能，方便其它人帮助你定位代码问题\n  // 详情可参考这里：https://developers.weixin.qq.com/miniprogram/dev/devtools/minicode.html\n  ```\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "<!--\nThank you for your pull request. Please provide a description above and review\nthe requirements below.\n\nBug fixes and new features should include tests and possibly benchmarks.\n-->\n\n##### Checklist\n<!-- Remove items that do not apply. For completed items, change [ ] to [x]. -->\n\n- [ ] `npm run test` passes\n- [ ] tests and/or benchmarks are included\n- [ ] cases or donate is changed or added\n- [ ] documentation is changed or added\n"
  },
  {
    "path": ".github/stale.yml",
    "content": "# Number of days of inactivity before an issue becomes stale\ndaysUntilStale: 3600\n# Number of days of inactivity before a stale issue is closed\ndaysUntilClose: 1700\n# Issues with these labels will never be considered stale\nexemptLabels:\n  - pinned\n  - security\n# Label to use when marking an issue as stale\nstaleLabel: Inactive\n# Comment to post when marking an issue as stale. Set to `false` to disable\nmarkComment: >\n  This issue has been automatically marked as stale because it has not had\n  recent activity. It will be closed if no further activity occurs. Thank you\n  for your contributions.\n  因为这个 Issue 最近没有任何有效回复，所以被自动标记为了`stale`。\n  如果在未来7天依旧没有任何激活操作，那么该 Issue 将会被自动关闭。\n  感谢您的提问。\n# Comment to post when closing a stale issue. Set to `false` to disable\ncloseComment: false\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: WePY CI Build\n\non: [push, pull_request]\n\njobs:\n  build:\n    runs-on: ubuntu-18.04\n    strategy:\n      matrix:\n        node-version: [10.x]\n    steps:\n    - name: Install expect\n      run: | \n        sudo apt -qy update && sudo apt install -y expect\n    - uses: actions/checkout@v2\n    - name: Use Node.js ${{ matrix.node-version }}\n      uses: actions/setup-node@v1\n      with:\n        node-version: ${{ matrix.node-version }}\n    - run: npm install\n    - run: npm run bootstrap \n    - run: npm run test\n    - run: npm run bootstrap:prod\n    - run: npm run test:build\n    - name: Coveralls\n      uses: coverallsapp/github-action@master\n      with:\n        github-token: ${{ secrets.GITHUB_TOKEN }}\n  release:\n    if: github.event_name == 'push' && startsWith(github.event.head_commit.message, 'release:')\n    name: Release\n    runs-on: ubuntu-18.04\n    needs: [build]\n    steps:\n    - uses: actions/checkout@v2\n    - uses: actions/setup-node@v1\n      with:\n        node-version: 12\n        registry-url: https://registry.npmjs.org/\n    - run: git reset --hard\n    - run: |\n        git config --global user.email \"gcaufy@gmail.com\"\n        git config --global user.name \"WePY CI\"\n    - run: npm install\n    - run: npm run bootstrap\n    - run: git status\n    - run: git checkout .\n    - name: NPM release\n      env:\n        NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}\n        GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        COMMIT_MESSAGE: ${{ github.event.head_commit.message }}\n      run: node ./scripts/ci-release.js\n    - run: git status\n    - run: git log\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "# This is a basic workflow to help you get started with Actions\n\nname: Release\n\n# Controls when the action will run. Triggers the workflow on push or pull request\n# events but only for the master branch\non:\n  push:\n    tags:\n      - '**'\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v2\n      - name: Use Node.js ${{ matrix.node-version }}\n        uses: actions/setup-node@v1\n        with:\n          node-version: '10.19'\n      - run: npm install\n      - run: npm run bootstrap\n      - run: npm run test\n      - name: Set Tag Variable\n        id: vars\n        run: echo ::set-output name=tag::${GITHUB_REF:10}\n      - name: Check Tag\n        env:\n          RELEASE_VERSION: ${{ steps.vars.outputs.tag }}\n        run: |\n          echo $GITHUB_REF\n          echo $RELEASE_VERSION\n          echo ${{ steps.vars.outputs.tag }}\n\n      - name: Build dist\n        run: npm run build\n      - name: NPM release\n        env:\n          TAG_NAME: ${{ steps.vars.outputs.tag}}\n          NPM_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}\n        run: |\n          echo \"//registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN}\" > ~/.npmrc\n          node ./scripts/npm-ci-release.js \"$TAG_NAME\"\n          node ./scripts/npm-tags.js \"$TAG_NAME\" next\n"
  },
  {
    "path": ".gitignore",
    "content": "node_modules/\nsftp-config.json\ndiff\nlog\nnpm-debug.log\ndemo/\n.nyc_output/\n.vscode\ncoverage\nlerna-debug.log\n/packages/*/lib\n.DS_Store\n.idea\n/yarn.lock\n"
  },
  {
    "path": ".npmignore",
    "content": "node_modules/\ncoverage/\ndemo/\ntest/\nISSUE_TEMPLATE.md\nappveyor.yml\nREADME_zh-CN.md\n*.map\nsrc/\ncoverage"
  },
  {
    "path": ".nycrc",
    "content": "{\n    \"reporter\": [\"lcov\", \"text-summary\"]\n}\n"
  },
  {
    "path": ".prettierrc.yml",
    "content": "# 一行最多 120 字符\nprintWidth: 120\n# 使用 2 个空格缩进\ntabWidth: 2\n# 不使用缩进符，而使用空格\nuseTabs: false\n# 行尾不需要分号\nsemi: true\n# 使用单引号\nsingleQuote: true\n# 对象的 key 仅在必要时用引号\nquoteProps: as-needed\n# jsx 不使用单引号，而使用双引号\njsxSingleQuote: false\n# 末尾不需要逗号\ntrailingComma: none\n# 大括号内的首尾需要空格\nbracketSpacing: true\n# jsx 标签的反尖括号需要换行\njsxBracketSameLine: false\n# 箭头函数，只有一个参数的时候，不需要括号\narrowParens: avoid\n# 每个文件格式化的范围是文件的全部内容\nrangeStart: 0\n# 不需要写文件开头的 @prettier\nrequirePragma: false\n# 不需要自动在文件开头插入 @prettier\ninsertPragma: false\n# 使用默认的折行标准\nproseWrap: preserve\n# 根据显示样式决定 html 要不要折行\nhtmlWhitespaceSensitivity: css\n# 换行符使用 lf\nendOfLine: lf\n# 后缀文件名特有规则\noverrides:\n  - files: '*.{wxss,less}'\n    options:\n      parser: less\n  - files: '*.json,.*rc'\n    options:\n      parser: json\n  - files: '*.{wxml,html}'\n    options:\n      parser: html\n      htmlWhitespaceSensitivity: strict\n      # 避免text标签换行\n      printWidth: 999\n  - files: '*.wxs'\n    options:\n      parser: babel\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: node_js\n\nnode_js:\n  - '10'\n\nmatrix:\n  include:\n    - os: linux\n    - os: osx\n\nsudo: false\n\nbefore_install:\n  - if [[ \"$TRAVIS_OS_NAME\" == \"linux\"                      ]] ; then sudo apt-get -qq update        ; fi\n  - if [[ \"$TRAVIS_OS_NAME\" == \"linux\" && ! $(which expect) ]] ; then sudo apt-get install -y expect ; fi\n  - if [[ \"$TRAVIS_OS_NAME\" == \"osx\"                        ]] ; then stty cols 80                   ; fi\n  - if [[ \"$TRAVIS_OS_NAME\" == \"osx\"                        ]] ; then brew update                    ; fi\n  - if [[ \"$TRAVIS_OS_NAME\" == \"osx\"   && ! $(which expect) ]] ; then brew install expect            ; fi\n\ninstall:\n  - 'npm install'\n  - 'npm run bootstrap'\n\nscript:\n  - 'npm run test'\n  - 'npm run bootstrap:prod'\n  - 'npm run test:build'\n\nafter_script: 'npm install coveralls && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage'\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Change Log\n\n## 2.1.0 (2020-07-04) (beta)\n\n#### :rocket: New Feature\n* `core`\n  * [#2634](https://github.com/Tencent/wepy/pull/2634) feat: added routed lifecycle ([@Gcaufy](https://github.com/Gcaufy))\n* `babel-plugin-import-regenerator`, `cli`, `compiler-babel`, `compiler-less`, `compiler-postcss`, `compiler-sass`, `compiler-stylus`, `compiler-typescript`, `core`, `plugin-define`, `plugin-eslint`, `plugin-uglifyjs`, `redux`, `use-intercept`, `use-promisify`, `x`\n  * [#2620](https://github.com/Tencent/wepy/pull/2620) feat: added ci npm release support ([@Gcaufy](https://github.com/Gcaufy))\n\n#### :bug: Bug Fix\n* `core`\n  * [#2633](https://github.com/Tencent/wepy/pull/2633) fix(core): 修复了 type 必填的问题 ([@Gcaufy](https://github.com/Gcaufy))\n\n#### Committers: 5\n- Damon Chen ([@chenyu445](https://github.com/chenyu445))\n- Deep ([@deepfunc](https://github.com/deepfunc))\n- Gcaufy ([@Gcaufy](https://github.com/Gcaufy))\n- Sail ([@dlhandsome](https://github.com/dlhandsome))\n- 这也太那个了吧 ([@dev-itsheng](https://github.com/dev-itsheng))\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing\n\n我们提倡您通过提 issue 和 pull request 方式来促进 WePY 的发展。\n\n\n## Acknowledgements\n\n非常感谢以下几位贡献者对于 WePY 的做出的贡献：\n\n- dlhandsome [awsomeduan@gmail.com](mailto:awsomeduan@gmail.com)\n- dolymood [dolymood@gmail.com](mailto:dolymood@gmail.com)\n- baisheng [baisheng@gmail.com](mailto:baisheng@gmail.com)\n- deepfunc [xiekai0601@gmail.com](mailto:xiekai0601@gmail.com)\n- nishino-tsukasa [nishinotsukasavirgo@gmail.com](mailto:nishinotsukasavirgo@gmail.com)\n\n其中特别致谢 dlhandsome 提交的38个 commits, 对 WePY 做出了1,350增加和362处删减(截止02/28/18日)。\n\nWePY 持续招募贡献者，即使是在 issue 中回答问题，或者做一些简单的 bugfix ，也会给 WePY 带来很大的帮助。\n\nWePY 已开发近一年，在此感谢所有开发者对于 WePY 的喜欢和支持，希望你能够成为 WePY 的核心贡献者，加入 WePY ，共同打造一个更棒的小程序开发框架！🍾🎉\n\n​                       \n\n## Issue 提交\n\n#### 对于贡献者\n\n在提 issue 前请确保满足一下条件：\n\n- 必须是一个 bug 或者功能新增。\n- 必须是 WePY 相关问题，原生小程序问题去[开发者论坛](https://developers.weixin.qq.com/)。\n- 已经在 issue 中搜索过，并且没有找到相似的 issue 或者解决方案。\n- 完善下面模板中的信息\n\n如果已经满足以上条件，我们提供了 issue 的标准模版，请按照模板填写。\n\n​             \n\n##  Pull request\n\n我们除了希望听到您的反馈和建议外，我们也希望您接受代码形式的直接帮助，对我们的 GitHub 发出 pull request 请求。\n\n以下是具体步骤：\n\n#### Fork仓库\n\n点击 `Fork` 按钮，将需要参与的项目仓库 fork 到自己的 Github 中。\n\n#### Clone 已 fork 项目\n\n在自己的 github 中，找到 fork 下来的项目，git clone 到本地。\n\n```bash\n$ git clone git@github.com:<yourname>/wepy.git\n```\n\n#### 添加 WePY 仓库\n\n将 fork 源仓库连接到本地仓库：\n\n```bash\n$ git remote add <name> <url>\n# 例如：\n$ git remote add wepy git@github.com:Tencent/wepy.git\n```\n\n#### 保持与 WePY 仓库的同步\n\n更新上游仓库：\n\n```bash\n$ git pull --rebase <name> <branch>\n# 等同于以下两条命令\n$ git fetch <name> <branch>\n$ git rebase <name>/<branch>\n```\n\n#### commit 信息提交\n\ncommit 信息请遵循[commit消息约定](./CONTRIBUTING_COMMIT.md)，以便可以自动生成 `CHANGELOG` 。具体格式请参考 commit 文档规范。\n\n\n\n#### 开发调试代码\n\n```bash\n# Build code\n$ npm run build\n\n# Watch\n$ npm run watch\n\n# Run test cases\n$ npm run test\n\n# Useage\n$ wepy build # Global wepy you installed by npm\n\n$ wepy-dev build # Local wepy you compiled by your local repository\n\n$ wepy-debug build # Debug local wepy using node --inspect\n```\n"
  },
  {
    "path": "CONTRIBUTING_COMMIT.md",
    "content": "# Commit规范\n\n在对项目作出更改后，我们需要生成 commit 来记录自己的更改。以下是参照 Angular 对 commit 格式的规范：\n\n## (1) 格式\n\n提交信息包括三个部分：`Header`，`Body` 和 `Footer`。\n\n```\n<Header>\n\n<Body>\n\n<Footer>\n```\n\n其中，Header 是必需的，Body 和 Footer 可以省略。\n\n#### 1> Header\n\nHeader 部分只有一行，包括俩个字段：`type`（必需）和`subject`（必需）。\n\n```\n<type>: <subject>\n```\n\n**type**\n\ntype 用于说明 commit 的类别，可以使用如下类别：\n\n- feat：新功能（feature）\n- fix：修补bug\n- doc：文档（documentation）\n- style： 格式（不影响代码运行的变动）\n- refactor：重构（即不是新增功能，也不是修改bug的代码变动）\n- test：增加测试\n- chore：构建过程或辅助工具的变动\n\n**subject**\n\nsubject 是 commit 目的的简短描述。\n\n- 以动词开头，使用第一人称现在时，比如改变，而不是改变了。\n- 结尾不加句号（。）\n\n#### 2> Body\n\nBody 部分是对本次 commit 的详细描述，可以分成多行。下面是一个范例。\n\n```\nMore detailed explanatory text, if necessary.  Wrap it to \nabout 72 characters or so. \n\nFurther paragraphs come after blank lines.\n\n- Bullet points are okay, too\n- Use a hanging indent\n```\n\n**注意：**应该说明代码变动的动机，以及与以前行为的对比。\n\n#### 3> Footer\n\n​\tFooter 部分应该包含：(1)Breaking Changes;  (2)关闭 issue；\n\n​\t**Breaking Changes**：\n\n​\t如果当前代码与上一个版本不兼容，则 Footer 部分以`BREAKING CHANGE`开头，后面是对变动的描述、以及变动理由和迁移方法。这种使用较少，了解即可。\n\n​\t**Issue 部分：**\n\n- 通过 commit 关联 issue：\n\n  如果当前提交信息关联了某个 issue，那么可以在 Footer 部分关联这个 issue：\n\n  ```\n  issue #2\n  ```\n\n- 通过 commit 关闭 issue，当提交到**默认分支**时，提交信息里可以使用 `fix/fixes/fixed` ， `close/closes/closed` 或者 `resolve/resolves/resolved`等关键词，后面再跟上 issue 号，这样就会关闭这个 issue：\n\n```\nCloses #1\n```\n\n​\t注意，如果不是提交到默认分支，那么并不能关闭这个 issue，但是在这个 issue 下面会显示相关的信息表示曾经想要关闭这个 issue，当这个分支合并到默认分支时，就可以关闭这个 issue 了。\n\n#### 4> 例子\n\n下面是一个完整的例子：\n\n```\nfeat: 添加了分享功能\n\n给每篇文章添加了分享功能\n\n- 添加分享到微信功能\n- 添加分享到朋友圈功能\n\nIssue #1, #2\nCloses #1\n```\n"
  },
  {
    "path": "LICENSE",
    "content": "Tencent is pleased to support the open source community by making WePY available.\nCopyright (C) 2017 THL A29 Limited, a Tencent company.  All rights reserved.\nIf you have downloaded a copy of the WePY binary from Tencent, please note that the WePY binary is licensed under the MIT License.\nIf you have downloaded a copy of the WePY source code from Tencent, please note that WePY source code is licensed under the MIT License, except for the third-party components listed below which are subject to different license terms.  Your integration of WePY into your own projects may require compliance with the MIT License, as well as the other licenses applicable to the third-party components included within WePY.\nA copy of the MIT License is included in this file.\n\nOther dependencies and licenses:\n\nOpen Source Software Licensed Under the BSD 3-Clause License:\n----------------------------------------------------------------------------------------\n1. istanbul  0.4.5\nCopyright 2012 Yahoo! Inc.\nAll rights reserved.\n\n\nTerms of the BSD 3-Clause License:\n--------------------------------------------------------------------\n\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\nRedistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n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Neither the name of [copyright holder] nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\nTHIS 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\n\n\nOpen Source Software Licensed Under the MIT License:\n----------------------------------------------------------------------------------------\n1. bable  6.5.2\nCopyright (c) 2014-2016 Sebastian McKenzie <sebmck@gmail.com>\n\n2. eslint  3.11.1\nCopyright JS Foundation and other contributors, https://js.foundation\n\n3. gulp  3.9.1\nCopyright (c) 2013-2016 Fractal <contact@wearefractal.com>\n\n4. lerna  2.0.0\nCopyright (c) 2015-2016 Sebastian McKenzie <sebmck@gmail.com>\n\n5. mocha  3.2.0\nCopyright (c) 2016 JS Foundation and contributors, https://js.foundation\n\n6. promise-polyfill  6.0.2\nCopyright (c) 2014 Taylor Hakes\nCopyright (c) 2014 Forbes Lindesay\n\n7. postcss  5.2.16\nCopyright 2013 Andrey Sitnik <andrey@sitnik.ru>\n\n8. sass  4.0.0\nCopyright (c) Natalie Weizenbaum <nweiz@google.com>\n\n9. stylus  0.54.5\nCopyright (c) Automattic <developer.wordpress.com>\n\n10. imagemin  5.2.2\nCopyright (c) imagemin (github.com/imagemin)\n\n11. redux  2.0.0\nCopyright (c) 2015 Dan Abramov\n\n12. axios  0.16.1\nCopyright (c) 2014 Matt Zabriskie\n\n13. vue  1.0.28\nCopyright (c) 2013-2016 Yuxi Evan You\n\n14. xmldom  0.1.27\nCopyright (c) jindw <jindw@xidea.org> (http://www.xidea.org)\n\n15. pug  2.0.0-beta6\nCopyright (c) 2009-2014 TJ Holowaychuk <tj@vision-media.ca>\n\n\nTerms of the MIT License:\n---------------------------------------------------\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "[English](./README_EN.md) | 简体中文\n\n> **📦 项目已归档**\n>\n> 随着微信小程序生态的不断演进，本项目已不再活跃维护。WePY 早已完成了它的历史使命，现有代码已不再具有参考意义，我们建议新项目选用更现代的方案。\n>\n> 在开源的这些年里，由于个人精力问题，导致项目的维护和响应未能做好，在此真诚地向各位贡献者和使用者说一声抱歉。\n>\n> 再次感谢大家理解，继续前行 🤝\n\n## WePY 2 (beta)\n\n[![npm version](https://badge.fury.io/js/wepy.svg)](https://badge.fury.io/js/wepy)\n[![travis-ci](https://travis-ci.org/Tencent/wepy.svg?branch=1.7.x)](https://travis-ci.org/Tencent/wepy)\n![Github CI](https://github.com/Tencent/wepy/workflows/WePY%20CI%20Build/badge.svg?branch=2.0.x)\n[![Coverage Status](https://coveralls.io/repos/github/Tencent/wepy/badge.svg?branch=1.7.x)](https://coveralls.io/github/Tencent/wepy?branch=1.7.x)\n[![Dependency Status](https://david-dm.org/Tencent/wepy.svg)](https://david-dm.org/Tencent/wepy)\n\n### 介绍\n\nWePY 资源汇总：[awesome-wepy](https://github.com/aben1188/awesome-wepy)\n\nWePY (发音: /'wepi/)是一款让小程序支持组件化开发的框架，通过预编译的手段让开发者可以选择自己喜欢的开发风格去开发小程序。框架的细节优化，Promise，Async Functions 的引入都是为了能让开发小程序项目变得更加简单，高效。\n\n同时 WePY 也是一款成长中的框架，大量吸收借鉴了一些优化前端工具以及框架的设计理念和思想。如果 WePY 有不足地方，或者你有更好的想法，欢迎提交 ISSUE 或者 PR。\n\n\n### 特性：\n\n- 类 Vue 开发风格\n- 支持自定义组件开发\n- 支持引入 NPM 包\n- 支持 [Promise](https://github.com/wepyjs/wepy/wiki/wepy%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8Promise)\n- 支持 ES2015+ 特性，如 [Async Functions](https://github.com/wepyjs/wepy/wiki/wepy%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8async-await)\n- 支持多种编译器，Less/Sass/Stylus/PostCSS、Babel/Typescript、Pug\n- 支持多种插件处理，文件压缩，图片压缩，内容替换等\n- 支持 Sourcemap，ESLint 等\n- 小程序细节优化，如请求列队，事件优化等\n\n### Demo\n\n```html\n<style lang=\"less\">\n@color: #4D926F;\n  .num {\n  color: @color;\n  }\n</style>\n<template>\n  <div class=\"container\">\n    <div class=\"num\" @tap=\"num++\">\n      {{num}}\n    </div>\n    <custom-component></custom-component>\n    <vendor-component></vendor-component>\n    <div>{{text}}</div>\n    <input v-model=\"text\"/>\n  </div>\n</template>\n<config>\n{\n  usingComponents: {\n    customComponent: '@/components/customComponent',\n    vendorComponent: 'module:vendorComponent'\n  }\n}\n</config>\n\n<script>\n  import wepy from '@wepy/core';\n\n  wepy.page({\n    data: {\n      num: 0,\n      text: 'Hello World',\n    },\n  });\n</script>\n```\n\n### 安装使用\n\n#### 安装（更新） wepy 命令行工具。\n\n```console\nnpm install @wepy/cli@next -g\n```\n\n#### 生成开发示例\n\n```console\nwepy init standard myproject\n```\n\n#### 安装依赖\n\n```console\ncd myproject\nnpm install\n```\n\n#### 开发实时编译\n\n```console\nwepy build --watch\n```\n\n#### 开发者工具导入项目\n\n使用`微信开发者工具`新建项目，本地开发选择项目根目录，会自动导入项目配置。\n\n### 哪些小程序是用 WePY 开发的\n\n腾讯疫苗查询小程序、\n腾讯翻译君小程序、\n腾讯地图小程序、\n玩转故宫小程序、\n手机充值+、\n手机余额查询、\n手机流量充值优惠、\n[友福图书馆](https://library.ufutx.com)[（开源）](https://github.com/glore/library)、\n[素洁商城](https://github.com/dyq086/wxYuHanStore)[（开源）](https://github.com/dyq086/wxYuHanStore)、\n[NewsLite](https://github.com/yshkk/shanbay-mina)[（开源）](https://github.com/yshkk/shanbay-mina)、\n[西安找拼车](https://github.com/chenqingspring)[（开源）](https://github.com/chenqingspring)、\n[深大的树洞](https://github.com/jas0ncn/szushudong)[（开源）](https://github.com/jas0ncn/szushudong)、\n[求知微阅读](https://github.com/KingJeason/wepy-books)[（开源）](https://github.com/KingJeason/wepy-books)、\n[给你的 iPhone X 换个发型](https://bangs.baran.wang/)、\n[天天跟我买](http://www.xiaohongchun.com.cn/index)、\n[坚橙](https://zhanart.com/wepy.html)、\n群脱单、\n米淘联盟、\n帮助圈、\n众安保险福利、\n阅邻二手书、\n趣店招聘、\n[满熊阅读（开源：](https://github.com/Thunf/wepy-demo-bookmall) [微信小程序](https://github.com/Thunf/wepy-demo-bookmall)、[支付宝小程序）](https://github.com/Thunf/wepy-demo-bookmall/tree/alipay)、\n育儿柚道、\n平行进口报价内参、\nGitHub 掘金版、\n班级群管、\n鲜花说小店、\n逛人备忘、\n英语助手君、\n花花百科、\n独角兽公司、\n爱羽客羽毛球、\n斑马小店、\n小小羽球、\n培恩医学、\n农资优选、\n公务员朝夕刷题、\n七弦琴小助手、\n七弦琴大数据、\n爽到家小程序、\n[应用全球排行](https://github.com/szpnygo/wepy_ios_top)[（开源）](https://github.com/szpnygo/wepy_ios_top)、\n[we 川大](https://github.com/mohuishou/scuplus-wechat)[（开源）](https://github.com/mohuishou/scuplus-wechat)、\n聊会儿、\n[诗词墨客](https://github.com/huangjianke/weapp-poem)[（开源）](https://github.com/huangjianke/weapp-poem)、\n[南京邮电大学](https://github.com/GreenPomelo/Undergraduate)[（开源）](https://github.com/GreenPomelo/Undergraduate)\n\n...\n\n### 交流群\n\nWePY 交流群已满 500 人，请加 gcaufy_helper 好友或者扫码加好友，验证回复 `wepy` 按照指引进群。\n\n![wepy_qr_code](https://user-images.githubusercontent.com/2182004/82732473-feb50c80-9d3f-11ea-9a5f-0efc6ce40f74.png)\n\n### 参与贡献\n\n如果你有好的意见或建议，欢迎给我们提 Issues 或 Pull Requests，为提升微信小程序开发体验贡献力量。<br>详见：[CONTRIBUTING.md](./CONTRIBUTING.md)\n\n[腾讯开源激励计划](https://opensource.tencent.com/contribution) 鼓励开发者的参与和贡献，期待你的加入。\n\n### Links\n\n[Documentation](https://tencent.github.io/wepy/)\n\n[Changelog](https://tencent.github.io/wepy/document.html#/changelog)\n\n[Contributing](./CONTRIBUTING.md)\n\n[License MIT](./LICENSE)\n"
  },
  {
    "path": "README_EN.md",
    "content": "English | [简体中文](./README.md)\n\n> **📦 This project has been archived**\n>\n> As the WeChat Mini Program ecosystem continues to evolve, this project is no longer actively maintained. WePY has long since fulfilled its historical mission. The existing code is no longer a recommended reference; we suggest adopting more modern solutions for new projects.\n>\n> Over the years of open source, due to limited personal bandwidth, the project was not maintained as well as it should have been. I sincerely apologize to all contributors and users for that.\n>\n> Thank you for your understanding, and keep moving forward 🤝\n\n## WePY 2 (beta)\n\n[![npm version](https://badge.fury.io/js/wepy.svg)](https://badge.fury.io/js/wepy)\n[![travis-ci](https://travis-ci.org/Tencent/wepy.svg?branch=1.7.x)](https://travis-ci.org/Tencent/wepy)\n![Github CI](https://github.com/Tencent/wepy/workflows/WePY%20CI%20Build/badge.svg?branch=2.0.x)\n[![Coverage Status](https://coveralls.io/repos/github/Tencent/wepy/badge.svg?branch=1.7.x)](https://coveralls.io/github/Tencent/wepy?branch=1.7.x)\n[![Dependency Status](https://david-dm.org/Tencent/wepy.svg)](https://david-dm.org/Tencent/wepy)\n\n### Introduce\n\nWePY resource summary：[awesome-wepy](https://github.com/aben1188/awesome-wepy)\n\nWePY (pronounced: /'wepi/) is a framework that enables componentization of small programs by pre-compiling them so that developers can choose their own development style.Details optimization of the framework, the introduction of Promise and Async Functions are all aimed at making it easier and more efficient to develop applets.\n\nAt the same time, WePY is also a growing framework, drawing heavily on the design concepts and ideas of some front-end optimization tools and frameworks.If WePY has a problem, or if you have a better idea, feel free to submit an ISSUE or PR.\n\n\n### Features:\n\n- Class Vue development style\n- Support for custom component development\n- Support for introducing NPM packages\n- support [Promise](https://github.com/wepyjs/wepy/wiki/wepy%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8Promise)\n- Support for ES2015+ features，如 [Async Functions](https://github.com/wepyjs/wepy/wiki/wepy%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8async-await)\n- Supports multiple compilers, Less/Sass/Stylus/PostCSS, Babel/Typescript, Pug\n- Supports a variety of plug-in processing, file compression, image compression, content replacement, etc\n- Supports Sourcemap, ESLint, etc\n- Small program details optimization, such as request queuing, event optimization, etc\n\n### Demo\n\n```html\n<style lang=\"less\">\n@color: #4D926F;\n  .num {\n  color: @color;\n  }\n</style>\n<template>\n  <div class=\"container\">\n    <div class=\"num\" @tap=\"num++\">\n      {{num}}\n    </div>\n    <custom-component></custom-component>\n    <vendor-component></vendor-component>\n    <div>{{text}}</div>\n    <input v-model=\"text\"/>\n  </div>\n</template>\n<config>\n{\n  usingComponents: {\n    customComponent: '@/components/customComponent',\n    vendorComponent: 'module:vendorComponent'\n  }\n}\n</config>\n\n<script>\n  import wepy from '@wepy/core';\n\n  wepy.page({\n    data: {\n      num: 0,\n      text: 'Hello World',\n    },\n  });\n</script>\n```\n\n### Usage\n\n#### Install (upgrade) the WEPY command-line tool.\n\n```bash\nnpm install @wepy/cli@next -g\n```\n\n#### Get start with an example\n\n```console\nwepy init standard myproject\n```\n\n#### Install dependencies\n\n```console\ncd myproject\nnpm install\n```\n\n#### Watch mode\n\n```console\nwepy build --watch\n```\n\n#### Import project\n\nCreate a new project using`WeChat developer tool`.If the local developer selects the project root directory, the project configuration will be automatically imported.\n\n### Which applets are developed with WePY\n\n腾讯疫苗查询小程序、\n腾讯翻译君小程序、\n腾讯地图小程序、\n玩转故宫小程序、\n手机充值+、\n手机余额查询、\n手机流量充值优惠、\n[友福图书馆](https://library.ufutx.com)[（开源）](https://github.com/glore/library)、\n[素洁商城](https://github.com/dyq086/wxYuHanStore)[（开源）](https://github.com/dyq086/wxYuHanStore)、\n[NewsLite](https://github.com/yshkk/shanbay-mina)[（开源）](https://github.com/yshkk/shanbay-mina)、\n[西安找拼车](https://github.com/chenqingspring)[（开源）](https://github.com/chenqingspring)、\n[深大的树洞](https://github.com/jas0ncn/szushudong)[（开源）](https://github.com/jas0ncn/szushudong)、\n[求知微阅读](https://github.com/KingJeason/wepy-books)[（开源）](https://github.com/KingJeason/wepy-books)、\n[给你的 iPhone X 换个发型](https://bangs.baran.wang/)、\n[天天跟我买](http://www.xiaohongchun.com.cn/index)、\n[坚橙](https://zhanart.com/wepy.html)、\n群脱单、\n米淘联盟、\n帮助圈、\n众安保险福利、\n阅邻二手书、\n趣店招聘、\n[满熊阅读（开源：](https://github.com/Thunf/wepy-demo-bookmall) [微信小程序](https://github.com/Thunf/wepy-demo-bookmall)、[支付宝小程序）](https://github.com/Thunf/wepy-demo-bookmall/tree/alipay)、\n育儿柚道、\n平行进口报价内参、\nGitHub 掘金版、\n班级群管、\n鲜花说小店、\n逛人备忘、\n英语助手君、\n花花百科、\n独角兽公司、\n爱羽客羽毛球、\n斑马小店、\n小小羽球、\n培恩医学、\n农资优选、\n公务员朝夕刷题、\n七弦琴小助手、\n七弦琴大数据、\n爽到家小程序、\n[应用全球排行](https://github.com/szpnygo/wepy_ios_top)[（开源）](https://github.com/szpnygo/wepy_ios_top)、\n[we 川大](https://github.com/mohuishou/scuplus-wechat)[（开源）](https://github.com/mohuishou/scuplus-wechat)、\n聊会儿、\n[诗词墨客](https://github.com/huangjianke/weapp-poem)[（开源）](https://github.com/huangjianke/weapp-poem)、\n[南京邮电大学](https://github.com/GreenPomelo/Undergraduate)[（开源）](https://github.com/GreenPomelo/Undergraduate)\n\n...\n\n### Wechat group\n\nWePY group has reached 500 members，Please add gcaufy_helper friends or scan the code to add friends, verify the reply 'wepy' according to the reference to enter the group.\n\n![wepy_qr_code](https://user-images.githubusercontent.com/2182004/82732473-feb50c80-9d3f-11ea-9a5f-0efc6ce40f74.png)\n\n### Contribution\n\nIf you have any comments or Suggestions, please feel free to contribute to improving the WeChat app-development experience by asking for Issues or Pull Requests.<br>see details：[CONTRIBUTING.md](./CONTRIBUTING.md)\n\n[Tencent Open Source Incentive Plan](https://opensource.tencent.com/contribution) EncouraTencent Open Source Incentive Plange developers to participate and contribute. Look forward to your participation.\n\n### Links\n\n[Documentation](https://tencent.github.io/wepy/)\n\n[Changelog](https://tencent.github.io/wepy/document.html#/changelog)\n\n[Contributing](./CONTRIBUTING.md)\n\n[License MIT](./LICENSE)\n"
  },
  {
    "path": "lerna.json",
    "content": "{\n  \"packages\": [\n    \"packages/*\"\n  ],\n  \"version\": \"2.1.0\",\n  \"message\": \"chore(release): publish\",\n  \"command\": {\n    \"publish\": {\n      \"commitHooks\": false,\n      \"conventionalCommits\": true,\n      \"message\": \"chore(release): publish %s\"\n    }\n  }\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"wepy\",\n  \"version\": \"0.0.0\",\n  \"description\": \"\",\n  \"main\": \"\",\n  \"scripts\": {\n    \"lint\": \"eslint ./ --ext .js\",\n    \"dev\": \"chokidar '**/*.wpy' '**/*.js' -c 'npm run dev:all' -i '/dist/'\",\n    \"build\": \"node ./scripts/build.js\",\n    \"build:core\": \"rollup -w -c scripts/config.js --environment TARGET:core\",\n    \"bootstrap\": \"./node_modules/.bin/lerna bootstrap --loglevel silly\",\n    \"bootstrap:prod\": \"./node_modules/.bin/lerna bootstrap --loglevel -- --production --no-optional\",\n    \"test\": \"npm run lint -- --fix && npm run test:cov\",\n    \"test:unit\": \"node ./test/unit.js\",\n    \"test:cov\": \"nyc npm run test:unit\",\n    \"test:build\": \"./test/build.sh\",\n    \"clean\": \"node ./scripts/clean.js\",\n    \"view\": \"./node_modules/.bin/verpub view -l\",\n    \"release\": \"./node_modules/.bin/verpub publish\",\n    \"release:dry\": \"./node_modules/.bin/verpub publish --dry-run\",\n    \"changelog\": \"lerna-changelog\",\n    \"commit\": \"git cz\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git@github.com:Tencent/wepy.git\"\n  },\n  \"author\": \"Gcaufy\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/Tencent/wepy/issues\"\n  },\n  \"homepage\": \"https://github.com/Tencent/wepy#readme\",\n  \"devDependencies\": {\n    \"babel\": \"^6.5.2\",\n    \"babel-cli\": \"^6.18.0\",\n    \"babel-eslint\": \"^7.1.1\",\n    \"babel-preset-es2015\": \"^6.18.0\",\n    \"babel-preset-stage-1\": \"^6.16.0\",\n    \"chai\": \"^4.1.2\",\n    \"chalk\": \"^1.1.3\",\n    \"chokidar\": \"^3.4.0\",\n    \"commitizen\": \"^3.1.1\",\n    \"cz-conventional-changelog\": \"^2.1.0\",\n    \"enquirer\": \"^2.3.0\",\n    \"eslint\": \"^7.5.0\",\n    \"eslint-config-prettier\": \"^6.10.0\",\n    \"eslint-plugin-prettier\": \"^3.1.2\",\n    \"esm\": \"^3.2.25\",\n    \"event-stream\": \"3.3.4\",\n    \"fs-extra\": \"^5.0.0\",\n    \"husky\": \"^1.3.1\",\n    \"istanbul\": \"^0.4.5\",\n    \"jsonlint\": \"^1.6.2\",\n    \"learn\": \"^0.1.5\",\n    \"lerna\": \"^3.22.1\",\n    \"lerna-changelog\": \"^1.0.1\",\n    \"less\": \"^3.9.0\",\n    \"mkpath\": \"^1.0.0\",\n    \"mocha\": \"^6.2.3\",\n    \"nyc\": \"^15.0.0\",\n    \"prettier\": \"^1.18.2\",\n    \"read-pkg\": \"^4.0.1\",\n    \"rimraf\": \"^3.0.2\",\n    \"rollup\": \"^0.56.5\",\n    \"rollup-plugin-buble\": \"^0.19.2\",\n    \"rollup-plugin-replace\": \"^2.0.0\",\n    \"serve-static\": \"^1.11.1\",\n    \"through2\": \"^2.0.3\",\n    \"validate-commit-msg\": \"^2.14.0\",\n    \"verpub\": \"^0.1.2\"\n  },\n  \"babel\": {\n    \"comments\": false,\n    \"presets\": [\n      [\n        \"es2015\",\n        {\n          \"loose\": true\n        }\n      ],\n      \"stage-1\"\n    ],\n    \"plugins\": [],\n    \"ignore\": [\n      \"./packages/wepy-web/src/components/*.vue\"\n    ],\n    \"env\": {\n      \"test\": {\n        \"auxiliaryCommentBefore\": \"istanbul ignore next\",\n        \"plugins\": [\n          \"istanbul\"\n        ]\n      }\n    }\n  },\n  \"engines\": {\n    \"node\": \">=8.9.4\"\n  },\n  \"husky\": {\n    \"hooks\": {\n      \"pre-commit\": \"npm run lint\",\n      \"pre-push\": \"npm run test\",\n      \"commit-msg\": \"npx validate-commit-msg\"\n    }\n  },\n  \"changelog\": {\n    \"labels\": {\n      \"feat\": \":rocket: New Feature\",\n      \"bug\": \":bug: Bug Fix\",\n      \"doc\": \":memo: Documentation\",\n      \"internal\": \":house: Internal\",\n      \"breaking\": \":boom: Breaking Change\"\n    }\n  },\n  \"config\": {\n    \"validate-commit-msg\": {\n      \"helpMessage\": \"\\nPlease fix your commit message (and consider using http://npm.im/commitizen)\\n\",\n      \"types\": [\n        \"feat\",\n        \"fix\",\n        \"docs\",\n        \"style\",\n        \"refactor\",\n        \"perf\",\n        \"test\",\n        \"chore\",\n        \"revert\",\n        \"build\",\n        \"release\",\n        \"custom\"\n      ],\n      \"warnOnFail\": false,\n      \"autoFix\": true\n    },\n    \"commitizen\": {\n      \"path\": \"./node_modules/cz-conventional-changelog\"\n    }\n  }\n}\n"
  },
  {
    "path": "packages/babel-plugin-import-regenerator/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n# 2.1.0 (2020-07-04)\n\n**Note:** Version bump only for package @wepy/babel-plugin-import-regenerator\n\n\n\n\n\n# 2.1.0-alpha.10 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/babel-plugin-import-regenerator\n\n\n\n\n\n# 2.1.0-alpha.9 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/babel-plugin-import-regenerator\n\n\n\n\n\n# 2.1.0-alpha.8 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/babel-plugin-import-regenerator\n\n\n\n\n\n# 2.1.0-alpha.7 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/babel-plugin-import-regenerator\n\n\n\n\n\n# 2.1.0-alpha.6 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/babel-plugin-import-regenerator\n\n\n\n\n\n# 2.1.0-alpha.5 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/babel-plugin-import-regenerator\n\n\n\n\n\n# [2.1.0-alpha.4](https://github.com/Tencent/wepy/compare/v2.1.0-alpha.2...v2.1.0-alpha.4) (2020-06-20)\n\n**Note:** Version bump only for package @wepy/babel-plugin-import-regenerator\n"
  },
  {
    "path": "packages/babel-plugin-import-regenerator/README.md",
    "content": "[English](./README_EN.md) | [简体中文]\n\n# @wepy/babel-plugin-import-regenerator\n\n允许wepy使用 `Async Functions`.\n\n## 安装\n\n```\n# Install regenerator-runtime dependence\n$ npm install regenerator-runtime --save\n\n# Install babel plugin \n$ npm install @wepy/babel-plugin-import-regenerator --save-dev\n```\n\n## 用法\n\n在 wepy.config.js 中放入以下内容:\n\n\n```js\n\n{\n  ....\n    compilers: {\n      babel: {\n        presets: [\n          '@babel/preset-env'\n        ],\n        plugins: [\n          '@wepy/babel-plugin-import-regenerator'\n        ]\n      }\n    }\n}\n```\n\n## License\n\nMIT\n"
  },
  {
    "path": "packages/babel-plugin-import-regenerator/README_EN.md",
    "content": "English | [简体中文](./README.md)\n\n# @wepy/babel-plugin-import-regenerator\n\nAllow wepy to use `Async Functions`.\n\n## Installation\n\n```\n# Install regenerator-runtime dependence\n$ npm install regenerator-runtime --save\n\n# Install babel plugin \n$ npm install @wepy/babel-plugin-import-regenerator --save-dev\n```\n\n## Usage\n\nPut something like this in your wepy.config.js:\n\n\n```js\n\n{\n  ....\n    compilers: {\n      babel: {\n        presets: [\n          '@babel/preset-env'\n        ],\n        plugins: [\n          '@wepy/babel-plugin-import-regenerator'\n        ]\n      }\n    }\n}\n```\n\n## License\n\nMIT\n"
  },
  {
    "path": "packages/babel-plugin-import-regenerator/index.js",
    "content": "const helperModelImports = require('@babel/helper-module-imports');\n\nlet wm = new WeakMap();\n\nexports = module.exports = ({ types: t }) => {\n  return {\n    visitor: {\n      CallExpression(path) {\n        let callee = path.get('callee');\n\n        if (callee.node && callee.node.object && callee.node.property) {\n          if (t.isIdentifier(callee.node.object, { name: 'regeneratorRuntime' })) {\n            let programPath = path.scope.getProgramParent().path;\n            let runtimeId;\n\n            if (wm.has(programPath.node)) {\n              runtimeId = t.identifier(wm.get(programPath.node));\n            } else {\n              runtimeId = helperModelImports.addDefault(programPath, 'regenerator-runtime', {\n                nameHint: 'regeneratorRuntime',\n                importedInterop: 'uncompiled',\n                blockHoist: 3\n              });\n              wm.set(programPath.node, runtimeId.name);\n            }\n            callee.node.object.name = runtimeId.name;\n          }\n        }\n      }\n    }\n  };\n};\n"
  },
  {
    "path": "packages/babel-plugin-import-regenerator/package.json",
    "content": "{\n  \"name\": \"@wepy/babel-plugin-import-regenerator\",\n  \"version\": \"2.1.0\",\n  \"description\": \"A babel plugin to add a global generator import\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"mocha ./test/*.test.js\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/Tencent/wepy.git\"\n  },\n  \"keywords\": [\n    \"regenerator-runtime\"\n  ],\n  \"author\": {\n    \"name\": \"Gcaufy\"\n  },\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/Tencent/wepy/issues\"\n  },\n  \"homepage\": \"https://github.com/Tencent/wepy#readme\",\n  \"dependencies\": {\n    \"@babel/helper-module-imports\": \"^7.0.0\"\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.1.0\",\n    \"babel-preset-env\": \"^1.7.0\",\n    \"chai\": \"^4.1.2\"\n  },\n  \"readme\": \"ERROR: No README data found!\",\n  \"_id\": \"@wepy/babel-plugin-import-regenerator@0.0.5\",\n  \"_commitid\": \"ebdaf08\",\n  \"gitHead\": \"5a25776457360bbbbc54a4d059f6bc7c032d5df3\"\n}\n"
  },
  {
    "path": "packages/babel-plugin-import-regenerator/test/fixtures/mutiple-async/actual.js",
    "content": "exports = module.exports = {\n  foo () {\n    return Promise.resolve(1);\n  },\n  async bar () {\n    console.log(await foo());\n  },\n  async bar2 () {\n    return await foo();\n  },\n  async bar3 () {\n    let result = await bar2();\n    console.log(result);\n  }\n}\n"
  },
  {
    "path": "packages/babel-plugin-import-regenerator/test/fixtures/mutiple-async/expected.js",
    "content": "\"use strict\";\n\nvar _regeneratorRuntime2 = require(\"regenerator-runtime\");\n\nvar _regeneratorRuntime3 = _interopRequireDefault(_regeneratorRuntime2);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }\n\nfunction _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"next\", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"throw\", err); } _next(undefined); }); }; }\n\nexports = module.exports = {\n  foo: function foo() {\n    return Promise.resolve(1);\n  },\n  bar: function () {\n    var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime3.default.mark(function _callee() {\n      return _regeneratorRuntime3.default.wrap(function _callee$(_context) {\n        while (1) {\n          switch (_context.prev = _context.next) {\n            case 0:\n              _context.t0 = console;\n              _context.next = 3;\n              return foo();\n\n            case 3:\n              _context.t1 = _context.sent;\n\n              _context.t0.log.call(_context.t0, _context.t1);\n\n            case 5:\n            case \"end\":\n              return _context.stop();\n          }\n        }\n      }, _callee, this);\n    }));\n\n    function bar() {\n      return _ref.apply(this, arguments);\n    }\n\n    return bar;\n  }(),\n  bar2: function () {\n    var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime3.default.mark(function _callee2() {\n      return _regeneratorRuntime3.default.wrap(function _callee2$(_context2) {\n        while (1) {\n          switch (_context2.prev = _context2.next) {\n            case 0:\n              _context2.next = 2;\n              return foo();\n\n            case 2:\n              return _context2.abrupt(\"return\", _context2.sent);\n\n            case 3:\n            case \"end\":\n              return _context2.stop();\n          }\n        }\n      }, _callee2, this);\n    }));\n\n    function bar2() {\n      return _ref2.apply(this, arguments);\n    }\n\n    return bar2;\n  }(),\n  bar3: function () {\n    var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime3.default.mark(function _callee3() {\n      var result;\n      return _regeneratorRuntime3.default.wrap(function _callee3$(_context3) {\n        while (1) {\n          switch (_context3.prev = _context3.next) {\n            case 0:\n              _context3.next = 2;\n              return bar2();\n\n            case 2:\n              result = _context3.sent;\n              console.log(result);\n\n            case 4:\n            case \"end\":\n              return _context3.stop();\n          }\n        }\n      }, _callee3, this);\n    }));\n\n    function bar3() {\n      return _ref3.apply(this, arguments);\n    }\n\n    return bar3;\n  }()\n};\n"
  },
  {
    "path": "packages/babel-plugin-import-regenerator/test/fixtures/normal/actual.js",
    "content": "import wepy from '@wepy/core'\n\nwepy.page({\n  methods: {\n    sleep (s) {\n      return new Promise((resolve, reject) => {\n        setTimeout(() => {\n          resolve('promise resolved')\n        }, s * 1000)\n      })\n    },\n    async testAsync () {\n      const result = await this.sleep(3)\n      console.log(result)\n    }\n  }\n})"
  },
  {
    "path": "packages/babel-plugin-import-regenerator/test/fixtures/normal/expected.js",
    "content": "\"use strict\";\n\nvar _regeneratorRuntime2 = require(\"regenerator-runtime\");\n\nvar _regeneratorRuntime3 = _interopRequireDefault(_regeneratorRuntime2);\n\nvar _core = require(\"@wepy/core\");\n\nvar _core2 = _interopRequireDefault(_core);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }\n\nfunction _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"next\", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"throw\", err); } _next(undefined); }); }; }\n\n_core2.default.page({\n  methods: {\n    sleep: function sleep(s) {\n      return new Promise(function (resolve, reject) {\n        setTimeout(function () {\n          resolve('promise resolved');\n        }, s * 1000);\n      });\n    },\n    testAsync: function () {\n      var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime3.default.mark(function _callee() {\n        var result;\n        return _regeneratorRuntime3.default.wrap(function _callee$(_context) {\n          while (1) {\n            switch (_context.prev = _context.next) {\n              case 0:\n                _context.next = 2;\n                return this.sleep(3);\n\n              case 2:\n                result = _context.sent;\n                console.log(result);\n\n              case 4:\n              case \"end\":\n                return _context.stop();\n            }\n          }\n        }, _callee, this);\n      }));\n\n      function testAsync() {\n        return _ref.apply(this, arguments);\n      }\n\n      return testAsync;\n    }()\n  }\n});\n"
  },
  {
    "path": "packages/babel-plugin-import-regenerator/test/index.test.js",
    "content": "const { transform } = require('@babel/core');\nconst { readdirSync, readFileSync } = require('fs');\nconst { join } = require('path');\nconst plugin = require('../index');\nconst expect = require('chai').expect;\n\ndescribe('babel-plugin-import-regenerator', () => {\n  let fixturesDir = join(__dirname, 'fixtures');\n  let fixtures = readdirSync(fixturesDir);\n\n  fixtures.forEach(caseName => {\n    const actualFile = join(fixturesDir, caseName, 'actual.js');\n    const expectedFile = join(fixturesDir, caseName, 'expected.js');\n\n    it(`should work with ${caseName.split('-').join(' ')}`, () => {\n      const actual = transform(readFileSync(actualFile), {\n        presets: ['env'],\n        plugins: [plugin]\n      }).code;\n\n      const expected = readFileSync(expectedFile, 'utf-8');\n      expect(actual.trim()).to.equal(expected.trim());\n    });\n  });\n});\n"
  },
  {
    "path": "packages/cli/.gitignore",
    "content": "node_modules/\nsftp-config.json\ndiff\nlog\nnpm-debug.log\nlib/\ndemo/\n.vscode"
  },
  {
    "path": "packages/cli/.npmignore",
    "content": "node_modules/\nsrc/\ncoverage/\ndemo/\ntest/\nISSUE_TEMPLATE.md\nappveyor.yml\nREADME_zh-CN.md\n*.map"
  },
  {
    "path": "packages/cli/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n# 2.1.0 (2020-07-04)\n\n**Note:** Version bump only for package @wepy/cli\n\n\n\n\n\n# 2.1.0-alpha.10 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/cli\n\n\n\n\n\n# 2.1.0-alpha.9 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/cli\n\n\n\n\n\n# 2.1.0-alpha.8 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/cli\n\n\n\n\n\n# 2.1.0-alpha.7 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/cli\n\n\n\n\n\n# 2.1.0-alpha.6 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/cli\n\n\n\n\n\n# 2.1.0-alpha.5 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/cli\n\n\n\n\n\n# [2.1.0-alpha.4](https://github.com/wepyjs/wepy/compare/v2.1.0-alpha.2...v2.1.0-alpha.4) (2020-06-20)\n\n**Note:** Version bump only for package @wepy/cli\n"
  },
  {
    "path": "packages/cli/README.md",
    "content": "# 小程序框架wepy命令行工具\n\n参见：[小程序框架wepy](https://github.com/wepyjs/wepy)\n\n\n### 安装\n```bash\nnpm install wepy-cli -g\n```\n\n### Changelog\n[查看CHANGELOG](https://github.com/wepyjs/wepy/blob/master/CHANGELOG.md)\n"
  },
  {
    "path": "packages/cli/bin/cli/ask.js",
    "content": "const async = require('async');\nconst inquirer = require('inquirer');\nconst evaluate = require('./eval');\n\n// Support types from prompt-for which was used before\nconst promptMapping = {\n  string: 'input',\n  boolean: 'confirm'\n};\n\n/**\n * Ask questions, return results.\n *\n * @param {Object} prompts\n * @param {Object} data\n * @param {Function} done\n */\n\nexports = module.exports = function ask(prompts, data, done) {\n  async.eachSeries(\n    Object.keys(prompts),\n    (key, next) => {\n      prompt(data, key, prompts[key], next);\n    },\n    done\n  );\n};\n\n/**\n * Inquirer prompt wrapper.\n *\n * @param {Object} data\n * @param {String} key\n * @param {Object} prompt\n * @param {Function} done\n */\n\nfunction prompt(data, key, prompt, done) {\n  // skip prompts whose when condition is not met\n  if (prompt.when && !evaluate(prompt.when, data)) {\n    return done();\n  }\n\n  let promptDefault = prompt.default;\n  if (typeof prompt.default === 'function') {\n    promptDefault = function() {\n      return prompt.default.bind(this)(data);\n    };\n  }\n\n  inquirer\n    .prompt([\n      {\n        type: promptMapping[prompt.type] || prompt.type,\n        name: key,\n        message: prompt.message || prompt.label || key,\n        default: promptDefault,\n        choices: prompt.choices || [],\n        validate: prompt.validate || (() => true)\n      }\n    ])\n    .then(answers => {\n      if (Array.isArray(answers[key])) {\n        data[key] = {};\n        answers[key].forEach(multiChoiceAnswer => {\n          data[key][multiChoiceAnswer] = true;\n        });\n      } else if (typeof answers[key] === 'string') {\n        data[key] = answers[key].replace(/\"/g, '\\\\\"');\n      } else {\n        data[key] = answers[key];\n      }\n      done();\n    })\n    .catch(done);\n}\n"
  },
  {
    "path": "packages/cli/bin/cli/check-version.js",
    "content": "const semver = require('semver');\nconst request = require('request');\nconst chalk = require('chalk');\nconst pkgConfig = require('../../package.json');\n\nexports = module.exports = function checkVersion() {\n  /**\n   * 检测当前node版本是否符合要求\n   */\n  return new Promise((resolve, reject) => {\n    if (!semver.satisfies(process.version, pkgConfig.engines.node)) {\n      // eslint-disable-next-line no-console\n      reject(new Error('  You must upgrade node to >=' + pkgConfig.engines.node + '.x to use @wepy/cli'));\n      return;\n    }\n    request(\n      {\n        url: 'https://registry.npmjs.org/@wepy/cli',\n        timeout: 1000\n      },\n      (err, res, body) => {\n        if (!err && res.statusCode === 200) {\n          const latestVersion = JSON.parse(body)['dist-tags'].latest;\n          const localVersion = pkgConfig.version;\n          if (semver.lt(localVersion, latestVersion)) {\n            /* eslint-disable no-console */\n            console.log(chalk.yellow('  A newer version of @wepy/cli is available.'));\n            console.log();\n            console.log('  latest:    ' + chalk.green(latestVersion));\n            console.log('  installed: ' + chalk.red(localVersion));\n            console.log();\n            /* eslint-enable no-console */\n          }\n        }\n        resolve(true);\n      }\n    );\n  });\n};\n"
  },
  {
    "path": "packages/cli/bin/cli/download.js",
    "content": "const download = require('download');\nconst downloadGitRepo = require('download-git-repo');\n\n/**\n * download official template zip\n * @param {*} template template name\n */\nexports = module.exports = {\n  downloadOfficialZip(template, dist, options) {\n    const templateName = template.split('#')[0];\n    const branch = template.split('#')[1] || '2.0.x';\n    if (branch === '2.0.x') {\n      return this.downloadFromCos(templateName, dist, options).catch(() => {\n        return this.downloadFromGitRaw(branch, templateName, dist, options);\n      });\n    } else {\n      return this.downloadFromGitRaw(branch, templateName, dist, options);\n    }\n  },\n  downloadFromGitRaw(template, dist, options, branch = '2.0.x') {\n    const rawUrl = `https://raw.githubusercontent.com/wepyjs/wepy_templates/${branch}/zips/${template}.zip`;\n    return download(rawUrl, dist, options).catch(e => {\n      e.url = rawUrl;\n      throw e;\n    });\n  },\n  downloadFromCos(template, dist, options) {\n    const cosUrl = `https://wepy-templates-1251238373.cos.ap-guangzhou.myqcloud.com/${template}.zip`;\n    return download(cosUrl, dist, options).catch(e => {\n      e.url = cosUrl;\n      throw e;\n    });\n  },\n  downloadRepo(template, dist, opt) {\n    return new Promise((resolve, reject) => {\n      downloadGitRepo(template, dist, opt, err => {\n        if (err) {\n          reject(err);\n        } else {\n          resolve(true);\n        }\n      });\n    });\n  }\n};\n"
  },
  {
    "path": "packages/cli/bin/cli/eval.js",
    "content": "/**\n * Evaluate an expression in meta.json in the context of\n * prompt answers data.\n */\nexports = module.exports = function evaluate(exp, data) {\n  const fn = new Function('data', 'with (data) { return ' + exp + '}');\n  try {\n    return fn(data);\n  } catch (e) {\n    return null;\n    //console.error(chalk.red('Error when evaluating filter condition: ' + exp));\n  }\n};\n"
  },
  {
    "path": "packages/cli/bin/cli/filter.js",
    "content": "const match = require('minimatch');\nconst evaluate = require('./eval');\n\nexports = module.exports = function filter(files, filters, data, done) {\n  if (!filters) {\n    return done();\n  }\n  const fileNames = Object.keys(files);\n  Object.keys(filters).forEach(glob => {\n    fileNames.forEach(file => {\n      if (match(file, glob, { dot: true })) {\n        const condition = filters[glob];\n        if (!evaluate(condition, data)) {\n          delete files[file];\n        }\n      }\n    });\n  });\n  done();\n};\n"
  },
  {
    "path": "packages/cli/bin/cli/generate.js",
    "content": "const chalk = require('chalk');\nconst Metalsmith = require('metalsmith');\nconst Handlebars = require('handlebars');\nconst async = require('async');\nconst ncp = require('ncp');\nconst handlebars = require('consolidate').handlebars;\nconst path = require('path');\nconst multimatch = require('multimatch');\nconst getOptions = require('./options');\nconst ask = require('./ask');\nconst filter = require('./filter');\nconst logger = require('./logger');\n\n// register handlebars helper\nHandlebars.registerHelper('if_eq', function(a, b, opts) {\n  return a === b ? opts.fn(this) : opts.inverse(this);\n});\n\nHandlebars.registerHelper('unless_eq', function(a, b, opts) {\n  return a === b ? opts.inverse(this) : opts.fn(this);\n});\n\n/**\n * Generate a template given a `src` and `dest`.\n *\n * @param {String} name\n * @param {String} src\n * @param {String} dest\n * @param {Function} done\n */\n\nexports = module.exports = function generate(name, src, dest, done) {\n  const opts = getOptions(name, src);\n\n  // This is a github project, and there is no meta.json or meta.js\n  if (opts.status === false) {\n    // Directly copy the project to dest.\n    ncp.ncp(src, dest, function(err) {\n      done(err);\n    });\n    return {};\n  }\n  const metalsmith = Metalsmith(path.join(src, 'template'));\n  const data = Object.assign(metalsmith.metadata(), {\n    destDirName: name,\n    inPlace: dest === process.cwd(),\n    noEscape: true\n  });\n  opts.helpers &&\n    Object.keys(opts.helpers).map(key => {\n      Handlebars.registerHelper(key, opts.helpers[key]);\n    });\n\n  const helpers = { chalk, logger };\n\n  if (opts.metalsmith && typeof opts.metalsmith.before === 'function') {\n    opts.metalsmith.before(metalsmith, opts, helpers);\n  }\n\n  metalsmith\n    .use((process.argv.indexOf('--no-interactive') > -1 ? buildInlineArgs : askQuestions)(opts.prompts))\n    .use(filterFiles(opts.filters))\n    .use(renderTemplateFiles(opts.skipInterpolation));\n\n  if (typeof opts.metalsmith === 'function') {\n    opts.metalsmith(metalsmith, opts, helpers);\n  } else if (opts.metalsmith && typeof opts.metalsmith.after === 'function') {\n    opts.metalsmith.after(metalsmith, opts, helpers);\n  }\n\n  metalsmith\n    .clean(false)\n    .source('.') // start = require('emplate root instead of `./src` which is Metalsmith's default for `source);\n    .destination(dest)\n    .build((err, files) => {\n      done(err);\n      if (typeof opts.complete === 'function') {\n        const helpers = { chalk, logger, files };\n        opts.complete(data, helpers);\n      } else {\n        logMessage(opts.completeMessage, data);\n      }\n    });\n\n  return data;\n};\n\n/**\n * Create a middleware for asking questions.\n *\n * @param {Object} prompts\n * @return {Function}\n */\n\nfunction askQuestions(prompts) {\n  return (files, metalsmith, done) => {\n    ask(prompts, metalsmith.metadata(), done);\n  };\n}\n\n/**\n * Get default value of a prompt item\n *\n * @param {String} value\n * @return {Function}\n */\n\nfunction getDefault(item) {\n  if (item.type === 'string') {\n    return item.default || '';\n  } else if (item.type === 'confirm') {\n    return item.default || true;\n  } else if (item.type === 'list') {\n    return item.default || item.choices[0];\n  } else {\n    throw new Error('Unrecongnize type: ' + item.type + ' in ' + JSON.stringify(item));\n  }\n}\n\n/**\n * Create a middleware using inline arguments.\n *\n * @param {Object} prompts\n * @return {Function}\n */\n\nfunction buildInlineArgs(prompts) {\n  const inlineArgs = {};\n  for (const k in prompts) {\n    const argIndex = process.argv.indexOf('--' + k);\n    if (argIndex > -1) {\n      inlineArgs[k] = process.argv[argIndex + 1];\n    } else {\n      inlineArgs[k] = getDefault(prompts[k]);\n    }\n    // eslint-disable-next-line no-console\n    console.log([chalk.green('?'), chalk.bold(prompts[k].message), chalk.cyan(inlineArgs[k])].join(' '));\n  }\n  return (files, metalsmith, done) => {\n    Object.assign(metalsmith.metadata(), inlineArgs);\n    done();\n  };\n}\n\n/**\n * Create a middleware for filtering files.\n *\n * @param {Object} filters\n * @return {Function}\n */\n\nfunction filterFiles(filters) {\n  return (files, metalsmith, done) => {\n    filter(files, filters, metalsmith.metadata(), done);\n  };\n}\n\n/**\n * Template in place plugin.\n *\n * @param {Object} files\n * @param {Metalsmith} metalsmith\n * @param {Function} done\n */\n\nfunction renderTemplateFiles(skipInterpolation) {\n  skipInterpolation = typeof skipInterpolation === 'string' ? [skipInterpolation] : skipInterpolation;\n  return (files, metalsmith, done) => {\n    const keys = Object.keys(files);\n    const metalsmithMetadata = metalsmith.metadata();\n    async.each(\n      keys,\n      (file, next) => {\n        // skipping files with skipInterpolation option\n        if (skipInterpolation && multimatch([file], skipInterpolation, { dot: true }).length) {\n          return next();\n        }\n        const str = files[file].contents.toString();\n        // do not attempt to render files that do not have mustaches\n        if (!/{{([^{}]+)}}/g.test(str)) {\n          return next();\n        }\n        handlebars.render(str, metalsmithMetadata, (err, res) => {\n          if (err) {\n            err.message = `[${file}] ${err.message}`;\n            return next(err);\n          }\n          files[file].contents = Buffer.from(res);\n          next();\n        });\n      },\n      done\n    );\n  };\n}\n\n/**\n * Display template complete message.\n *\n * @param {String} message\n * @param {Object} data\n */\n\nfunction logMessage(message, data) {\n  if (!message) return;\n  handlebars.render(message, data, (err, res) => {\n    if (err) {\n      // eslint-disable-next-line no-console\n      console.error('\\n   Error when rendering template complete message: ' + err.message.trim());\n    } else {\n      // eslint-disable-next-line no-console\n      console.log(\n        '\\n' +\n          res\n            .split(/\\r?\\n/g)\n            .map(line => '   ' + line)\n            .join('\\n')\n      );\n    }\n  });\n}\n"
  },
  {
    "path": "packages/cli/bin/cli/git-user.js",
    "content": "const execSync = require('child_process').execSync;\n\nexports = module.exports = function getGitUser() {\n  let name;\n  let email;\n\n  try {\n    name = execSync('git config --get user.name');\n    email = execSync('git config --get user.email');\n  } catch (e) {}\n\n  name = name && name.toString().trim();\n  email = email && ' <' + email.toString().trim() + '>';\n  return (name || '') + (email || '');\n};\n"
  },
  {
    "path": "packages/cli/bin/cli/local-path.js",
    "content": "const path = require('path');\n\nexports = module.exports = {\n  isLocalPath(templatePath) {\n    // templatePath example:\n    // .wepy_templates\n    // E:\\workspace\\wepy_templates\\standard\n    return /^[./]|(^[a-zA-Z]:)/.test(templatePath);\n  },\n  getTemplatePath(templatePath) {\n    return path.isAbsolute(templatePath) ? templatePath : path.normalize(path.join(process.cwd(), templatePath));\n  }\n};\n"
  },
  {
    "path": "packages/cli/bin/cli/logger.js",
    "content": "const chalk = require('chalk');\nconst format = require('util').format;\n\n/**\n * Prefix.\n */\n\nconst prefix = '   @wepy/cli';\nconst sep = chalk.gray('·');\n\n/**\n * Log a `message` to the console.\n *\n * @param {String} message\n */\n\nexports = module.exports = {\n  log(...args) {\n    const msg = format.apply(format, args);\n    // eslint-disable-next-line no-console\n    console.log(chalk.white(prefix), sep, msg);\n  },\n\n  /**\n   * Log an error `message` to the console and exit.\n   *\n   * @param {String} message\n   */\n\n  fatal(...args) {\n    if (args[0] instanceof Error) args[0] = args[0].message.trim();\n    const msg = format.apply(format, args);\n    // eslint-disable-next-line no-console\n    console.error(chalk.red(prefix), sep, msg);\n    process.exit(1);\n  },\n\n  /**\n   * Log a success `message` to the console and exit.\n   *\n   * @param {String} message\n   */\n\n  success(...args) {\n    const msg = format.apply(format, args);\n    // eslint-disable-next-line no-console\n    console.log(chalk.white(prefix), sep, msg);\n  }\n};\n"
  },
  {
    "path": "packages/cli/bin/cli/options.js",
    "content": "const path = require('path');\nconst metadata = require('read-metadata');\nconst fs = require('fs');\nconst getGitUser = require('./git-user');\nconst validateName = require('validate-npm-package-name');\n\n/**\n * Read prompts metadata.\n *\n * @param {String} dir\n * @return {Object}\n */\n\nexports = module.exports = function options(name, dir) {\n  const opts = getMetadata(dir);\n\n  setDefault(opts, 'name', name);\n  setValidateName(opts);\n\n  const author = getGitUser();\n  if (author) {\n    setDefault(opts, 'author', author);\n  }\n\n  return opts;\n};\n\n/**\n * Gets the metadata from either a meta.json or meta.js file.\n *\n * @param  {String} dir\n * @return {Object}\n */\n\nfunction getMetadata(dir) {\n  const json = path.join(dir, 'meta.json');\n  const js = path.join(dir, 'meta.js');\n  let opts = {};\n  opts.status = true;\n\n  if (fs.existsSync(json)) {\n    opts = metadata.sync(json);\n  } else if (fs.existsSync(js)) {\n    const req = require(path.resolve(js));\n    if (req !== Object(req)) {\n      throw new Error('meta.js needs to expose an object');\n    }\n    opts = req;\n  } else {\n    opts.status = false;\n  }\n\n  return opts;\n}\n\n/**\n * Set the default value for a prompt question\n *\n * @param {Object} opts\n * @param {String} key\n * @param {String} val\n */\n\nfunction setDefault(opts, key, val) {\n  if (opts.schema) {\n    opts.prompts = opts.schema;\n    delete opts.schema;\n  }\n  const prompts = opts.prompts || (opts.prompts = {});\n  if (!prompts[key] || typeof prompts[key] !== 'object') {\n    prompts[key] = {\n      type: 'string',\n      default: val\n    };\n  } else {\n    prompts[key]['default'] = val;\n  }\n}\n\nfunction setValidateName(opts) {\n  const name = opts.prompts.name;\n  const customValidate = name.validate;\n  name.validate = name => {\n    const its = validateName(name);\n    if (!its.validForNewPackages) {\n      const errors = (its.errors || []).concat(its.warnings || []);\n      return 'Sorry, ' + errors.join(' and ') + '.';\n    }\n    if (typeof customValidate === 'function') return customValidate(name);\n    return true;\n  };\n}\n"
  },
  {
    "path": "packages/cli/bin/wepy-build.js",
    "content": "const compile = require('../core/compile');\nconst parseOptions = require('../core/parseOptions');\nconst logger = require('../core/util/logger');\n\nexports = module.exports = program => {\n  let options;\n  try {\n    options = parseOptions.convert(program);\n  } catch (e) {\n    const msg = e.message;\n    if (msg.indexOf('plugins expect a Array') > -1) {\n      logger.error(`Parse WePY config failed. Are you trying to use WePY 2 to build WePY 1 project?`);\n    } else {\n      logger.error(`Parse WePY config failed.`);\n    }\n    logger.error(e.message);\n    process.exit();\n  }\n  const compilation = compile(options || {});\n  compilation.run().catch(e => {\n    compilation.logger.error('init', e.message);\n  });\n};\n"
  },
  {
    "path": "packages/cli/bin/wepy-init.js",
    "content": "const fs = require('fs');\nconst path = require('path');\nconst chalk = require('chalk');\nconst tildify = require('tildify');\nconst inquirer = require('inquirer');\nconst home = require('user-home');\nconst rm = require('rimraf').sync;\nconst download = require('./cli/download');\nconst localPath = require('./cli/local-path');\nconst checkVersion = require('./cli/check-version');\nconst generate = require('./cli/generate');\nconst logger = require('./../util/logger');\n\nexports = module.exports = (template, rawName, program) => {\n  function gen(templatePath) {\n    logger.verbose('Start to generate project');\n    // eslint-disable-next-line no-console\n    console.log();\n    return new Promise((resolve, reject) => {\n      return generate(name, templatePath, to, err => {\n        if (err) {\n          reject(err);\n        } else {\n          resolve(true);\n        }\n      });\n    })\n      .catch(e => {\n        logger.error('Generate project failed');\n        logger.error(e);\n        return false;\n      })\n      .then(conti => {\n        if (conti) {\n          // eslint-disable-next-line no-console\n          console.log();\n          logger.info(`Generated \"${name}\".`);\n        }\n      });\n  }\n\n  function run() {\n    if (localPath.isLocalPath(template)) {\n      logger.verbose('Use local path template');\n      // use local/cache template\n      // Example:\n      // wepy init E:\\workspace\\wepy_templates\\standard my-wepy-project\n      // wepy init standard my-wepy-project --offline\n      const templatePath = localPath.getTemplatePath(template);\n      if (fs.existsSync(templatePath)) {\n        gen(templatePath);\n      } else {\n        logger.error(`Local template \"${template}\" not found.`);\n      }\n    } else {\n      logger.verbose(`Version check`);\n      checkVersion().then(() => {\n        downloadAndGenerate(template);\n      });\n    }\n  }\n\n  function downloadLog(msg, type = 'verbose') {\n    logger[type](msg);\n  }\n\n  function downloadOfficialTemplate(templateName, dist, opt, branch) {\n    downloadLog(`Download template \"${templateName}\" in branch \"${branch}\" from Github Raw`);\n    return download\n      .downloadFromGitRaw(templateName, dist, opt, branch)\n      .catch(e => {\n        if (branch === '2.0.x') {\n          downloadLog(`Download URL is: ${e.url}`);\n          downloadLog(`Download from Github raw failed, try Tencent COS download`, 'warn');\n          downloadLog(e, 'warn');\n          return download.downloadFromCos(templateName, tmp, opt);\n        } else {\n          throw e;\n        }\n      })\n      .catch(e => {\n        downloadLog(`Download URL is: ${e.url}`);\n        throw e;\n      });\n  }\n\n  function downloadAndGenerate(template) {\n    if (fs.existsSync(tmp)) {\n      rm(tmp);\n    }\n    if (!hasSlash) {\n      let [templateName, branch] = template.split('#');\n      downloadLog(`Donwnloading template \"${templateName}\"`);\n      return downloadOfficialTemplate(templateName, tmp, { extract: true }, branch || '2.0.x')\n        .then(() => {\n          downloadLog('Download success, start generate template');\n          return true;\n        })\n        .catch(e => {\n          if (e.statusCode === 404) {\n            logger.error(`Unrecongnized template: \"${template}\". Try \"wepy list\" to show all available templates `);\n          } else {\n            logger.error(`Download template failed`);\n            logger.error(e);\n          }\n          return false;\n        })\n        .then(conti => {\n          if (conti) {\n            return gen(tmp);\n          }\n        });\n    } else {\n      // use third party template\n      downloadLog('Donwnloading github repo \"${template}\"');\n      return download\n        .downloadRepo(template, tmp, { clone })\n        .then(() => {\n          downloadLog('Download repository success, start generate template');\n          return true;\n        })\n        .catch(e => {\n          logger.error('Failed to download repo ' + template);\n          logger.error(e);\n          return false;\n        })\n        .then(conti => {\n          if (conti) {\n            return gen(tmp);\n          }\n        });\n    }\n  }\n\n  const hasSlash = template.indexOf('/') > -1;\n  const inPlace = !rawName || rawName === '.';\n  const name = inPlace ? path.relative('../', process.cwd()) : rawName;\n  const to = path.resolve(rawName || '.');\n  const clone = program.clone || false;\n  const offline = program.offline || false;\n\n  let tmp = path.join(home, '.wepy_templates', template.replace(/\\//g, '-'));\n\n  /**\n   * use offline cache\n   */\n  if (offline) {\n    // eslint-disable-next-line no-console\n    logger.notice(`Use cached template at ${chalk.yellow(tildify(tmp))}`);\n    template = tmp;\n  }\n\n  if (fs.existsSync(to)) {\n    inquirer\n      .prompt([\n        {\n          type: 'confirm',\n          message: inPlace ? 'Generate project in current directory?' : 'Target directory exists. Continue?',\n          name: 'ok'\n        }\n      ])\n      .then(answers => {\n        if (answers.ok) {\n          run();\n        }\n      })\n      .catch();\n  } else {\n    run();\n  }\n};\n"
  },
  {
    "path": "packages/cli/bin/wepy-list.js",
    "content": "#!/usr/bin/env node\n\nconst chalk = require('chalk');\nconst request = require('request');\nconst Table = require('tty-table');\nconst ta = require('time-ago');\n\nexports = module.exports = program => {\n  request(\n    {\n      url: 'https://raw.githubusercontent.com/wepyjs/wepy-templates/2.0.x/meta.json',\n      headers: {\n        'User-Agent': 'wepy-cli'\n      }\n    },\n    (err, res, body) => {\n      if (!body) {\n        // eslint-disable-next-line no-console\n        console.error('Something wrong with your network');\n        return;\n      }\n      if (body.message) {\n        // eslint-disable-next-line no-console\n        console.error(body.messge);\n        return;\n      }\n      let official, github;\n      try {\n        body = JSON.parse(body);\n        official = body.official;\n        github = body.github;\n      } catch (e) {\n        // eslint-disable-next-line no-console\n        console.error('Something wrong with your network');\n      }\n      if (!program.github && Array.isArray(official)) {\n        // eslint-disable-next-line no-console\n        console.log('\\n  Available official templates:\\n');\n        /*\n            official.forEach(repo => {\n\n              console.log(\n            '  ' + chalk.yellow('♚') +\n            '  ' + chalk.blue(repo.name) +\n            ' - ' + repo.description);\n            });\n            */\n        let tableHead = [\n          {\n            value: 'Name',\n            width: 20,\n            color: 'blue'\n          },\n          {\n            value: 'Description',\n            width: 60,\n            align: 'left',\n            paddingLeft: 2,\n            key: 'description'\n          }\n        ];\n        let rows = [];\n        official.forEach(repo => {\n          rows.push([repo.name, repo.description]);\n        });\n\n        let offical = Table(tableHead, rows, {\n          borderStyle: 2\n        });\n        // eslint-disable-next-line no-console\n        console.log(`     e.g., wepy init ${rows[0][0]} myproject`);\n        // eslint-disable-next-line no-console\n        console.log(offical.render());\n      }\n      if (Array.isArray(github)) {\n        // eslint-disable-next-line no-console\n        console.log('\\n  Available github projects:\\n');\n\n        let tableHead = [\n          {\n            value: 'Repository',\n            width: 30,\n            color: 'blue',\n            key: 'repo'\n          },\n          {\n            value: 'Stars',\n            width: 8,\n            key: 'star'\n          },\n          {\n            value: 'Description',\n            width: 60,\n            align: 'left',\n            paddingLeft: 2,\n            key: 'description'\n          },\n          {\n            value: 'Last Updated',\n            width: 25,\n            key: 'last_update',\n            formatter: function(v) {\n              let date = new Date(v);\n              if (date.toString() === 'Invalid Date') {\n                return '----';\n              } else {\n                return ta.ago(v);\n              }\n            }\n          }\n        ];\n\n        let map = tableHead.map(v => v.key);\n\n        let showItems = [];\n        let rows = [];\n        let MAX_COUNT = program.github ? 0 : 5;\n        if (MAX_COUNT && github.length > MAX_COUNT) {\n          for (let i = 0, l = github.length; i < l; i++) {\n            if (i >= MAX_COUNT) break;\n            showItems.push(github[i]);\n          }\n        } else {\n          showItems = github;\n        }\n        showItems.forEach(repo => {\n          let row = [];\n          map.forEach(title => {\n            row.push(repo[title] || '');\n          });\n          rows.push(row);\n        });\n        if (MAX_COUNT && github.length > MAX_COUNT) {\n          rows.push(['....', '..', '....', '....']);\n        }\n\n        let githubTable = Table(tableHead, rows, {\n          borderStyle: 2\n        });\n        // eslint-disable-next-line no-console\n        console.log(`     e.g., wepy init ${rows[0][0]} myproject`);\n        // eslint-disable-next-line no-console\n        console.log(githubTable.render());\n\n        if (MAX_COUNT && github.length > MAX_COUNT) {\n          // eslint-disable-next-line no-console\n          console.log(chalk.gray(`  use 'wepy list --github' to see all github projects`));\n        }\n        if (program.github) {\n          // eslint-disable-next-line no-console\n          console.log(chalk.gray(`  You can registe your project from here: https://github.com/wepyjs/wepy_templates`));\n        }\n        // eslint-disable-next-line no-console\n        console.log('\\n');\n      }\n    }\n  );\n};\n"
  },
  {
    "path": "packages/cli/bin/wepy-new.js",
    "content": "#!/usr/bin/env node\n\nconst chalk = require('chalk');\n\nexports = module.exports = proj => {\n  if (typeof proj !== 'string') proj = 'myproject';\n  // eslint-disable-next-line no-console\n  console.log('');\n  // eslint-disable-next-line no-console\n  console.log(`deprecated command, please use ` + chalk.blue(`wepy init standard ${proj}`) + ` instead`);\n  // eslint-disable-next-line no-console\n  console.log('');\n};\n"
  },
  {
    "path": "packages/cli/bin/wepy-upgrade.js",
    "content": "const exec = require('child_process').exec;\nconst util = require('../util');\n\nfunction upgradeCLI(cb) {\n  let cmd = 'npm install wepy-cli -g';\n  util.log('升级中，可能需要几分钟, 请耐心等待...', '信息');\n  util.log('执行命令: ' + cmd, '执行');\n  let fcmd = exec(cmd, () => {\n    util.log('完成安装最新版本wepy-cli', '完成');\n    cb && cb();\n  });\n  fcmd.stdout.on('data', d => {\n    // eslint-disable-next-line no-console\n    console.log(d.substring(d, d.length - 1));\n  });\n}\n\nfunction upgradeWepy(cb) {\n  let cmd = 'npm install wepy --save';\n  util.log('升级中，可能需要几分钟, 请耐心等待...', '信息');\n  util.log('执行命令: ' + cmd, '执行');\n  let fcmd = exec(cmd, () => {\n    util.log('完成安装最新版本wepy', '完成');\n\n    let cmd = 'wepy build --no-cache';\n    util.log('执行命令: ' + cmd, '执行');\n\n    let fcmd3 = exec(cmd, () => {\n      util.log('完成升级', '完成');\n      cb && cb();\n    });\n    fcmd3.stdout.on('data', d => {\n      // eslint-disable-next-line no-console\n      console.log(d.substring(d, d.length - 1));\n    });\n  });\n  fcmd.stdout.on('data', d => {\n    // eslint-disable-next-line no-console\n    console.log(d.substring(d, d.length - 1));\n  });\n}\n\nexports = module.exports = program => {\n  if (program.cli) {\n    upgradeCLI();\n  } else {\n    upgradeWepy();\n  }\n};\n"
  },
  {
    "path": "packages/cli/bin/wepy.js",
    "content": "#!/usr/bin/env node\n\nconst chalk = require('chalk');\nconst program = require('commander');\nconst logger = require('../core/util/logger');\n\nprogram\n  .version(require('../package.json').version, '-v, --version')\n  .option('-l, --log <level>', 'change the log level')\n  .usage('<command> [options]');\n\nprogram\n  .command('init <template-name> [project-name]')\n  .allowUnknownOption()\n  .description('generate a new project from a template')\n  .action(require('./wepy-init'))\n  .usage('<template-name> [project-name]')\n  .option('-c --clone', 'use git clone')\n  .option('--offline', 'use cached template')\n  .option('--no-interactive', 'no interactive to use the options to create template')\n  .on('--help', () => {\n    /* eslint-disable no-console */\n    console.log();\n    console.log('  Example:');\n    console.log();\n    console.log(chalk.gray('   # create a new project with an official template'));\n    console.log('  $ wepy init standard my-project');\n    console.log();\n    console.log(chalk.gray('   # create a new project straight from a github template'));\n    console.log('  $ wepy init username/repo my-project');\n    console.log();\n    /* eslint-enable no-console */\n  });\n\nprogram\n  .command('build')\n  .description('build your project')\n  .action(require('./wepy-build'))\n\n  .option('-f, --file <file>', '待编译wpy文件')\n  .option('-s, --source <source>', '源码目录')\n  .option('-t, --target <target>', '生成代码目录')\n  .option('-o, --output <type>', '编译类型：web，weapp。默认为weapp')\n  .option('-p, --platform <type>', '编译平台：browser, wechat，qq。默认为browser')\n  .option('-w, --watch', '监听文件改动')\n  .option('--no-cache', '对于引用到的文件，即使无改动也会再次编译');\n\nprogram\n  .command('list')\n  .description('list available official templates')\n  .action(require('./wepy-list'))\n\n  .option('-g, --github', 'list all registered github projects');\n\n/*\nprogram\n  .command('upgrade')\n  .description('upgrade to the latest version')\n  .action(require('./wepy-upgrade'))\n  .option('--cli', 'upgrade wepy-cli')\n  .option('--wepy', 'upgrade wepy');\n*/\n\nprogram\n  .command('new')\n  .description('deprecated command, use \"wepy init <template-name> <project-name>\" instead')\n  .action(require('./wepy-new'));\n\nprogram.parse(process.argv);\n\nif (program.log) {\n  logger.level(program.log);\n}\n"
  },
  {
    "path": "packages/cli/core/ast/index.js",
    "content": ""
  },
  {
    "path": "packages/cli/core/ast/paramsDetect.js",
    "content": "const acorn = require('acorn');\nconst walk = require('acorn/dist/walk');\n\nfunction isScope(node) {\n  return (\n    node.type === 'FunctionExpression' ||\n    node.type === 'FunctionDeclaration' ||\n    node.type === 'ArrowFunctionExpression' ||\n    node.type === 'Program'\n  );\n}\nfunction isBlockScope(node) {\n  return node.type === 'BlockStatement' || isScope(node);\n}\n\nfunction declaresArguments(node) {\n  return node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration';\n}\n\nfunction declaresThis(node) {\n  return node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration';\n}\n\nfunction reallyParse(source, options) {\n  var parseOptions = Object.assign({}, options, {\n    allowReturnOutsideFunction: true,\n    allowImportExportEverywhere: true,\n    allowHashBang: true\n  });\n  return acorn.parse(source, parseOptions);\n}\nmodule.exports = findGlobals;\nmodule.exports.parse = reallyParse;\nfunction findGlobals(source, options) {\n  options = options || {};\n  let globals = [];\n  let expressions = [];\n  let callee;\n  var ast;\n  // istanbul ignore else\n  if (typeof source === 'string') {\n    ast = reallyParse(source, options);\n  } else {\n    ast = source;\n  }\n  // istanbul ignore if\n  if (!(ast && typeof ast === 'object' && ast.type === 'Program')) {\n    throw new TypeError('Source must be either a string of JavaScript or an acorn AST');\n  }\n  var declareFunction = function(node) {\n    var fn = node;\n    fn.locals = fn.locals || {};\n    node.params.forEach(function(node) {\n      declarePattern(node, fn);\n    });\n    if (node.id) {\n      fn.locals[node.id.name] = true;\n    }\n  };\n  var declarePattern = function(node, parent) {\n    switch (node.type) {\n      case 'Identifier':\n        parent.locals[node.name] = true;\n        break;\n      case 'ObjectPattern':\n        node.properties.forEach(function(node) {\n          declarePattern(node.value, parent);\n        });\n        break;\n      case 'ArrayPattern':\n        node.elements.forEach(function(node) {\n          if (node) declarePattern(node, parent);\n        });\n        break;\n      case 'RestElement':\n        declarePattern(node.argument, parent);\n        break;\n      case 'AssignmentPattern':\n        declarePattern(node.left, parent);\n        break;\n      // istanbul ignore next\n      default:\n        throw new Error('Unrecognized pattern type: ' + node.type);\n    }\n  };\n  var declareModuleSpecifier = function(node) {\n    ast.locals = ast.locals || {};\n    ast.locals[node.local.name] = true;\n  };\n  walk.ancestor(ast, {\n    VariableDeclaration: function(node, parents) {\n      var parent = null;\n      for (var i = parents.length - 1; i >= 0 && parent === null; i--) {\n        if (node.kind === 'var' ? isScope(parents[i]) : isBlockScope(parents[i])) {\n          parent = parents[i];\n        }\n      }\n      parent.locals = parent.locals || {};\n      node.declarations.forEach(function(declaration) {\n        declarePattern(declaration.id, parent);\n      });\n    },\n    FunctionDeclaration: function(node, parents) {\n      var parent = null;\n      for (var i = parents.length - 2; i >= 0 && parent === null; i--) {\n        if (isScope(parents[i])) {\n          parent = parents[i];\n        }\n      }\n      parent.locals = parent.locals || {};\n      parent.locals[node.id.name] = true;\n      declareFunction(node);\n    },\n    Function: declareFunction,\n    ClassDeclaration: function(node, parents) {\n      var parent = null;\n      for (var i = parents.length - 2; i >= 0 && parent === null; i--) {\n        if (isScope(parents[i])) {\n          parent = parents[i];\n        }\n      }\n      parent.locals = parent.locals || {};\n      parent.locals[node.id.name] = true;\n    },\n    TryStatement: function(node) {\n      if (node.handler === null) return;\n      node.handler.locals = node.handler.locals || {};\n      node.handler.locals[node.handler.param.name] = true;\n    },\n    ImportDefaultSpecifier: declareModuleSpecifier,\n    ImportSpecifier: declareModuleSpecifier,\n    ImportNamespaceSpecifier: declareModuleSpecifier\n  });\n  function identifier(node, parents) {\n    var name = node.name;\n    if (name === 'undefined') return;\n    for (var i = 0; i < parents.length; i++) {\n      if (name === 'arguments' && declaresArguments(parents[i])) {\n        return;\n      }\n      if (parents[i].locals && name in parents[i].locals) {\n        return;\n      }\n    }\n    node.parents = parents;\n    globals[name] = globals[name] || {};\n    let callable = false;\n    if (parents && parents.length > 2) {\n      let parent = parents[parents.length - 2];\n      callable = parent.type === 'CallExpression' && parent.callee === node;\n    }\n    globals[name].callable = globals[name].callable || callable;\n    globals[name].nodes = globals[name].nodes || [];\n    globals[name].nodes.push(node);\n  }\n  walk.ancestor(ast, {\n    VariablePattern: identifier,\n    Identifier: identifier,\n    CallExpression: function(node) {\n      callee = getNameForExpression(node.callee);\n      expressions = node.arguments.map(arg => {\n        let p = getNameForExpression(arg);\n        p.node = arg;\n        return p;\n      });\n    },\n    ThisExpression: function(node, parents) {\n      for (var i = 0; i < parents.length; i++) {\n        if (declaresThis(parents[i])) {\n          return;\n        }\n      }\n      node.parents = parents;\n      globals.push(node);\n    }\n  });\n  return {\n    identifiers: globals,\n    callee,\n    params: expressions\n  };\n}\n\nfunction getNameForExpression(expression) {\n  let expr = expression;\n  const exprName = [];\n  while (expr.type === 'MemberExpression' && expr.property.type === (expr.computed ? 'Literal' : 'Identifier')) {\n    exprName.push(expr.computed ? expr.property.value : expr.property.name);\n    expr = expr.object;\n  }\n  if (expr.type === 'Identifier') {\n    exprName.push(expr.name);\n  } else if (expr.type === 'Literal') {\n    exprName.push(expr.value);\n  }\n  let name = exprName.pop();\n  let t;\n  while ((t = exprName.pop())) {\n    name += typeof t === 'number' ? `[${t}]` : `.${t}`;\n  }\n  return {\n    name,\n    type: expr.type\n  };\n}\n"
  },
  {
    "path": "packages/cli/core/ast/parseClass.js",
    "content": "const walk = require('acorn/dist/walk');\nconst toAST = require('./toAST');\n\nexports = module.exports = function parseClass(source) {\n  source = '(' + source + ');';\n  const ast = toAST(source);\n  let result = [];\n  walk.ancestor(ast, {\n    ObjectExpression(node) {\n      node.properties.forEach(p => {\n        let value = p.key.type === 'Identifier' ? p.key.name : p.key.type === 'Literal' ? p.key.value : undefined;\n        if (value) {\n          if (p.value.type === 'Identifier') {\n            result.push({\n              [value]: p.value.name\n            });\n          } else {\n            result.push({\n              [value]: source.substring(p.value.start, p.value.end)\n            });\n          }\n        }\n      });\n    },\n    ArrayExpression(node) {\n      node.elements.forEach(p => {\n        if (p.type === 'Identifier') {\n          result.push(p.name);\n        }\n      });\n    },\n    ConditionalExpression() {\n      result.push(source);\n    }\n  });\n\n  return result;\n};\n"
  },
  {
    "path": "packages/cli/core/ast/toAST.js",
    "content": "const acorn = require('acorn-dynamic-import').default;\n\nconst ECMA_VERSION = 2017;\n\nconst POSSIBLE_AST_OPTIONS = [\n  {\n    ranges: true,\n    locations: true,\n    ecmaVersion: ECMA_VERSION,\n    sourceType: 'module',\n    plugins: {\n      dynamicImport: true\n    }\n  },\n  {\n    ranges: true,\n    locations: true,\n    ecmaVersion: ECMA_VERSION,\n    sourceType: 'script',\n    plugins: {\n      dynamicImport: true\n    }\n  }\n];\n\nexports = module.exports = function ast(source) {\n  let ast;\n  const comments = [];\n  for (let i = 0, len = POSSIBLE_AST_OPTIONS.length; i < len; i++) {\n    if (!ast) {\n      try {\n        comments.length = 0;\n        POSSIBLE_AST_OPTIONS[i].onComment = comments;\n        ast = acorn.parse(source, POSSIBLE_AST_OPTIONS[i]);\n      } catch (e) {\n        // ignore the error\n      }\n    }\n  }\n\n  if (!ast) {\n    ast = acorn.parse(source, {\n      ranges: true,\n      locations: true,\n      ecmaVersion: ECMA_VERSION,\n      sourceType: 'module',\n      plugins: {\n        dynamicImport: true\n      },\n      onComment: comments\n    });\n  }\n\n  if (!ast || typeof ast !== 'object') {\n    throw new Error(`Source could't be parsed`);\n  }\n  return ast;\n};\n"
  },
  {
    "path": "packages/cli/core/ast/walker.js",
    "content": "class AstWalker {\n  constructor(compilation, ast, lang) {\n    this.ast = ast;\n    this.state = {};\n    this.deps = [];\n    this.replacements = [];\n    this.compilation = compilation;\n    this.lang = lang;\n  }\n\n  run() {\n    this.scope = {\n      inTry: false,\n      definitions: [],\n      instances: [],\n      renames: {}\n    };\n    this.prewalkStatements(this.ast.body);\n    this.walkStatements(this.ast.body);\n  }\n  // Walking iterates the statements and expressions and processes them\n  walkStatements(statements) {\n    for (let index = 0, len = statements.length; index < len; index++) {\n      const statement = statements[index];\n      this.walkStatement(statement);\n    }\n  }\n  walkStatement(statement) {\n    // if(this.applyPluginsBailResult1(\"statement\", statement) !== undefined) return;\n    const handler = this['walk' + statement.type];\n    if (handler) handler.call(this, statement);\n  }\n\n  walkClass(classy) {\n    if (classy.superClass) this.walkExpression(classy.superClass);\n    if (classy.body && classy.body.type === 'ClassBody') {\n      classy.body.body.forEach(methodDefinition => {\n        if (methodDefinition.type === 'MethodDefinition') this.walkMethodDefinition(methodDefinition);\n      });\n    }\n  }\n\n  walkMethodDefinition(methodDefinition) {\n    if (methodDefinition.computed && methodDefinition.key) this.walkExpression(methodDefinition.key);\n    if (methodDefinition.value) this.walkExpression(methodDefinition.value);\n  }\n\n  // Prewalking iterates the scope for variable declarations\n  prewalkStatements(statements) {\n    for (let index = 0, len = statements.length; index < len; index++) {\n      const statement = statements[index];\n      this.prewalkStatement(statement);\n    }\n  }\n\n  prewalkStatement(statement) {\n    const handler = this['prewalk' + statement.type];\n    if (handler) handler.call(this, statement);\n  }\n\n  // Real Statements\n  prewalkBlockStatement(statement) {\n    this.prewalkStatements(statement.body);\n  }\n\n  walkBlockStatement(statement) {\n    this.walkStatements(statement.body);\n  }\n\n  walkExpressionStatement(statement) {\n    this.walkExpression(statement.expression);\n  }\n\n  prewalkIfStatement(statement) {\n    this.prewalkStatement(statement.consequent);\n    if (statement.alternate) this.prewalkStatement(statement.alternate);\n  }\n\n  walkIfStatement(statement) {\n    const result = undefined;\n    // const result = this.applyPluginsBailResult1(\"statement if\", statement);\n    if (result === undefined) {\n      this.walkExpression(statement.test);\n      this.walkStatement(statement.consequent);\n      if (statement.alternate) this.walkStatement(statement.alternate);\n    } else {\n      if (result) this.walkStatement(statement.consequent);\n      else if (statement.alternate) this.walkStatement(statement.alternate);\n    }\n  }\n\n  prewalkLabeledStatement(statement) {\n    this.prewalkStatement(statement.body);\n  }\n\n  walkLabeledStatement(statement) {\n    const result = undefined;\n    // const result = this.applyPluginsBailResult1(\"label \" + statement.label.name, statement);\n    if (result !== true) this.walkStatement(statement.body);\n  }\n\n  prewalkWithStatement(statement) {\n    this.prewalkStatement(statement.body);\n  }\n\n  walkWithStatement(statement) {\n    this.walkExpression(statement.object);\n    this.walkStatement(statement.body);\n  }\n\n  prewalkSwitchStatement(statement) {\n    this.prewalkSwitchCases(statement.cases);\n  }\n\n  walkSwitchStatement(statement) {\n    this.walkExpression(statement.discriminant);\n    this.walkSwitchCases(statement.cases);\n  }\n\n  walkTerminatingStatement(statement) {\n    if (statement.argument) this.walkExpression(statement.argument);\n  }\n\n  walkReturnStatement(statement) {\n    this.walkTerminatingStatement(statement);\n  }\n\n  walkThrowStatement(statement) {\n    this.walkTerminatingStatement(statement);\n  }\n\n  prewalkTryStatement(statement) {\n    this.prewalkStatement(statement.block);\n  }\n\n  walkTryStatement(statement) {\n    if (this.scope.inTry) {\n      this.walkStatement(statement.block);\n    } else {\n      this.scope.inTry = true;\n      this.walkStatement(statement.block);\n      this.scope.inTry = false;\n    }\n    if (statement.handler) this.walkCatchClause(statement.handler);\n    if (statement.finalizer) this.walkStatement(statement.finalizer);\n  }\n\n  prewalkWhileStatement(statement) {\n    this.prewalkStatement(statement.body);\n  }\n\n  walkWhileStatement(statement) {\n    this.walkExpression(statement.test);\n    this.walkStatement(statement.body);\n  }\n\n  prewalkDoWhileStatement(statement) {\n    this.prewalkStatement(statement.body);\n  }\n\n  walkDoWhileStatement(statement) {\n    this.walkStatement(statement.body);\n    this.walkExpression(statement.test);\n  }\n\n  prewalkForStatement(statement) {\n    if (statement.init) {\n      if (statement.init.type === 'VariableDeclaration') this.prewalkStatement(statement.init);\n    }\n    this.prewalkStatement(statement.body);\n  }\n\n  walkForStatement(statement) {\n    if (statement.init) {\n      if (statement.init.type === 'VariableDeclaration') this.walkStatement(statement.init);\n      else this.walkExpression(statement.init);\n    }\n    if (statement.test) this.walkExpression(statement.test);\n    if (statement.update) this.walkExpression(statement.update);\n    this.walkStatement(statement.body);\n  }\n\n  prewalkForInStatement(statement) {\n    if (statement.left.type === 'VariableDeclaration') this.prewalkStatement(statement.left);\n    this.prewalkStatement(statement.body);\n  }\n\n  walkForInStatement(statement) {\n    if (statement.left.type === 'VariableDeclaration') this.walkStatement(statement.left);\n    else this.walkExpression(statement.left);\n    this.walkExpression(statement.right);\n    this.walkStatement(statement.body);\n  }\n\n  prewalkForOfStatement(statement) {\n    if (statement.left.type === 'VariableDeclaration') this.prewalkStatement(statement.left);\n    this.prewalkStatement(statement.body);\n  }\n\n  walkForOfStatement(statement) {\n    if (statement.left.type === 'VariableDeclaration') this.walkStatement(statement.left);\n    else this.walkExpression(statement.left);\n    this.walkExpression(statement.right);\n    this.walkStatement(statement.body);\n  }\n\n  // Declarations\n  prewalkFunctionDeclaration(statement) {\n    if (statement.id) {\n      this.scope.renames['$' + statement.id.name] = undefined;\n      this.scope.definitions.push(statement.id.name);\n    }\n  }\n\n  walkFunctionDeclaration(statement) {\n    statement.params.forEach(param => {\n      this.walkPattern(param);\n    });\n    this.inScope(statement.params, () => {\n      if (statement.body.type === 'BlockStatement') {\n        this.prewalkStatement(statement.body);\n        this.walkStatement(statement.body);\n      } else {\n        this.walkExpression(statement.body);\n      }\n    });\n  }\n\n  prewalkImportDeclaration(statement) {\n    const source = statement.source.value;\n    let dep = {\n      statement: statement,\n      expr: statement.source,\n      module: source,\n      loc: statement.source.loc\n    };\n    this.deps.push(dep);\n    return;\n    /*\n    // this.applyPluginsBailResult(\"import\", statement, source);\n    statement.specifiers.forEach(function(specifier) {\n      const name = specifier.local.name;\n      this.scope.renames['$' + name] = undefined;\n      this.scope.definitions.push(name);\n      switch (specifier.type) {\n        case 'ImportDefaultSpecifier':\n          // this.applyPluginsBailResult(\"import specifier\", statement, source, \"default\", name);\n          break;\n        case 'ImportSpecifier':\n          // this.applyPluginsBailResult(\"import specifier\", statement, source, specifier.imported.name, name);\n          break;\n        case 'ImportNamespaceSpecifier':\n          // this.applyPluginsBailResult(\"import specifier\", statement, source, null, name);\n          break;\n      }\n    }, this);\n    */\n  }\n\n  prewalkExportNamedDeclaration(statement) {\n    /*\n    let source;\n    if (statement.source) {\n      source = statement.source.value;\n      // this.applyPluginsBailResult(\"export import\", statement, source);\n    } else {\n      // this.applyPluginsBailResult1(\"export\", statement);\n    }*/\n    if (statement.declaration) {\n      if (/Expression$/.test(statement.declaration.type)) {\n        throw new Error(`Doesn't occur?`);\n      } else {\n        this.prewalkStatement(statement.declaration);\n        /*\n        const pos = this.scope.definitions.length;\n        const newDefs = this.scope.definitions.slice(pos);\n        for (let index = newDefs.length - 1; index >= 0; index--) {\n          const def = newDefs[index];\n          // this.applyPluginsBailResult(\"export specifier\", statement, def, def, index);\n        }*/\n      }\n    }\n    if (statement.specifiers) {\n      for (let specifierIndex = 0; specifierIndex < statement.specifiers.length; specifierIndex++) {\n        const specifier = statement.specifiers[specifierIndex];\n        switch (specifier.type) {\n          case 'ExportSpecifier': {\n            //const name = specifier.exported.name;\n            /*\n              if(source)\n                // this.applyPluginsBailResult(\"export import specifier\", statement, source, specifier.local.name, name, specifierIndex);\n              else\n                // this.applyPluginsBailResult(\"export specifier\", statement, specifier.local.name, name, specifierIndex);\n              */\n            break;\n          }\n        }\n      }\n    }\n  }\n\n  walkExportNamedDeclaration(statement) {\n    if (statement.declaration) {\n      this.walkStatement(statement.declaration);\n    }\n  }\n\n  prewalkExportDefaultDeclaration(statement) {\n    if (/Declaration$/.test(statement.declaration.type)) {\n      this.prewalkStatement(statement.declaration);\n      /*\n      const pos = this.scope.definitions.length;\n      const newDefs = this.scope.definitions.slice(pos);\n      for (let index = 0, len = newDefs.length; index < len; index++) {\n        const def = newDefs[index];\n        // this.applyPluginsBailResult(\"export specifier\", statement, def, \"default\");\n      }*/\n    }\n  }\n\n  walkExportDefaultDeclaration(statement) {\n    // this.applyPluginsBailResult1(\"export\", statement);\n    if (/Declaration$/.test(statement.declaration.type)) {\n    } else {\n      this.walkExpression(statement.declaration);\n    }\n  }\n\n  /*\n  prewalkExportAllDeclaration(statement) {\n    // const source = statement.source.value;\n    // this.applyPluginsBailResult(\"export import\", statement, source);\n    // this.applyPluginsBailResult(\"export import specifier\", statement, source, null, null, 0);\n  }*/\n\n  prewalkVariableDeclaration(statement) {\n    if (statement.declarations) this.prewalkVariableDeclarators(statement.declarations);\n  }\n\n  walkVariableDeclaration(statement) {\n    if (statement.declarations) this.walkVariableDeclarators(statement.declarations);\n  }\n\n  prewalkClassDeclaration(statement) {\n    if (statement.id) {\n      this.scope.renames['$' + statement.id.name] = undefined;\n      this.scope.definitions.push(statement.id.name);\n    }\n  }\n\n  walkClassDeclaration(statement) {\n    this.walkClass(statement);\n  }\n\n  prewalkSwitchCases(switchCases) {\n    for (let index = 0, len = switchCases.length; index < len; index++) {\n      const switchCase = switchCases[index];\n      this.prewalkStatements(switchCase.consequent);\n    }\n  }\n\n  walkSwitchCases(switchCases) {\n    for (let index = 0, len = switchCases.length; index < len; index++) {\n      const switchCase = switchCases[index];\n\n      if (switchCase.test) {\n        this.walkExpression(switchCase.test);\n      }\n      this.walkStatements(switchCase.consequent);\n    }\n  }\n\n  walkCatchClause(catchClause) {\n    this.inScope([catchClause.param], () => {\n      this.prewalkStatement(catchClause.body);\n      this.walkStatement(catchClause.body);\n    });\n  }\n\n  prewalkVariableDeclarators(declarators) {\n    declarators.forEach(declarator => {\n      switch (declarator.type) {\n        case 'VariableDeclarator': {\n          this.enterPattern(declarator.id, (name, decl) => {\n            // For old version compiler-babel, we can remove it later\n            if (this.compilation.hasHook('prewalk-' + declarator.type, this, declarator, name, decl)) {\n              this.compilation.hook('prewalk-' + declarator.type, this, declarator, name, decl);\n            } else {\n              // Ignore child scope\n              if (this.scope.instances && declarator.init && declarator.init.type === 'CallExpression') {\n                if (declarator.init.callee.name === 'require') {\n                  if (\n                    declarator.init.arguments &&\n                    declarator.init.arguments[0] &&\n                    declarator.init.arguments[0].value === 'wepy'\n                  ) {\n                    this.scope.instances.push(name);\n                  }\n                } else if (declarator.init.callee.name === '_interopRequireDefault') {\n                  this.scope.instances.push(name + '.default');\n                }\n              }\n            }\n\n            if (!this.applyMethods(`var${declarator.kind}${name}`, decl)) {\n              if (!this.applyMethods(`var${name}`, decl)) {\n                this.scope.renames['$' + name] = undefined;\n                if (this.scope.definitions.indexOf(name) < 0) this.scope.definitions.push(name);\n              }\n            }\n            /*\n              if(true || !this.applyPluginsBailResult1(\"var-\" + declarator.kind + \" \" + name, decl)) {\n                if(true || !this.applyPluginsBailResult1(\"var \" + name, decl)) {\n                  this.scope.renames[\"$\" + name] = undefined;\n                  if(this.scope.definitions.indexOf(name) < 0)\n                    this.scope.definitions.push(name);\n                }\n              }*/\n          });\n          break;\n        }\n      }\n    });\n  }\n\n  walkVariableDeclarators(declarators) {\n    declarators.forEach(declarator => {\n      switch (declarator.type) {\n        case 'VariableDeclarator': {\n          const renameIdentifier = declarator.init && this.getRenameIdentifier(declarator.init);\n          if (\n            renameIdentifier &&\n            declarator.id.type === 'Identifier' &&\n            this.applyMethods('canrename' + renameIdentifier, declarator.init)\n          ) {\n            // if(renameIdentifier && declarator.id.type === \"Identifier\" && this.applyPluginsBailResult1(\"can-rename \" + renameIdentifier, declarator.init)) {\n            // renaming with \"var a = b;\"\n            if (!this.applyMethods('rename' + renameIdentifier, declarator.init)) {\n              // if(!this.applyPluginsBailResult1(\"rename \" + renameIdentifier, declarator.init)) {\n              this.scope.renames['$' + declarator.id.name] =\n                this.scope.renames['$' + renameIdentifier] || renameIdentifier;\n              const idx = this.scope.definitions.indexOf(declarator.id.name);\n              if (idx >= 0) this.scope.definitions.splice(idx, 1);\n            }\n          } else {\n            this.walkPattern(declarator.id);\n            if (declarator.init) this.walkExpression(declarator.init);\n          }\n          break;\n        }\n      }\n    });\n  }\n\n  walkPattern(pattern) {\n    if (pattern.type === 'Identifier') return;\n    if (this['walk' + pattern.type]) this['walk' + pattern.type](pattern);\n  }\n\n  walkAssignmentPattern(pattern) {\n    this.walkExpression(pattern.right);\n    this.walkPattern(pattern.left);\n  }\n\n  walkObjectPattern(pattern) {\n    for (let i = 0, len = pattern.properties.length; i < len; i++) {\n      const prop = pattern.properties[i];\n      if (prop) {\n        if (prop.computed) this.walkExpression(prop.key);\n        if (prop.value) this.walkPattern(prop.value);\n      }\n    }\n  }\n\n  walkArrayPattern(pattern) {\n    for (let i = 0, len = pattern.elements.length; i < len; i++) {\n      const element = pattern.elements[i];\n      if (element) this.walkPattern(element);\n    }\n  }\n\n  walkRestElement(pattern) {\n    this.walkPattern(pattern.argument);\n  }\n\n  walkExpressions(expressions) {\n    for (let expressionsIndex = 0, len = expressions.length; expressionsIndex < len; expressionsIndex++) {\n      const expression = expressions[expressionsIndex];\n      if (expression) this.walkExpression(expression);\n    }\n  }\n\n  walkExpression(expression) {\n    if (this['walk' + expression.type]) return this['walk' + expression.type](expression);\n  }\n\n  walkAwaitExpression(expression) {\n    const argument = expression.argument;\n    if (this['walk' + argument.type]) return this['walk' + argument.type](argument);\n  }\n\n  walkArrayExpression(expression) {\n    if (expression.elements) this.walkExpressions(expression.elements);\n  }\n\n  walkSpreadElement(expression) {\n    if (expression.argument) this.walkExpression(expression.argument);\n  }\n\n  walkObjectExpression(expression) {\n    for (let propIndex = 0, len = expression.properties.length; propIndex < len; propIndex++) {\n      const prop = expression.properties[propIndex];\n      if (prop.computed) this.walkExpression(prop.key);\n      if (prop.shorthand) this.scope.inShorthand = true;\n      this.walkExpression(prop.value);\n      if (prop.shorthand) this.scope.inShorthand = false;\n    }\n  }\n\n  walkFunctionExpression(expression) {\n    expression.params.forEach(param => {\n      this.walkPattern(param);\n    });\n    this.inScope(expression.params, () => {\n      if (expression.body.type === 'BlockStatement') {\n        this.prewalkStatement(expression.body);\n        this.walkStatement(expression.body);\n      } else {\n        this.walkExpression(expression.body);\n      }\n    });\n  }\n\n  walkArrowFunctionExpression(expression) {\n    expression.params.forEach(param => {\n      this.walkPattern(param);\n    });\n    this.inScope(expression.params, () => {\n      if (expression.body.type === 'BlockStatement') {\n        this.prewalkStatement(expression.body);\n        this.walkStatement(expression.body);\n      } else {\n        this.walkExpression(expression.body);\n      }\n    });\n  }\n\n  walkSequenceExpression(expression) {\n    if (expression.expressions) this.walkExpressions(expression.expressions);\n  }\n\n  walkUpdateExpression(expression) {\n    this.walkExpression(expression.argument);\n  }\n\n  walkUnaryExpression(expression) {\n    if (expression.operator === 'typeof') {\n      const exprName = this.getNameForExpression(expression.argument);\n      if (exprName && exprName.free) {\n        let hookName = 'walker-unary-expression-undefined';\n        if (this.compilation.hasHook(hookName)) {\n          this.compilation.hookSeq(hookName, this, expression, exprName);\n        }\n      }\n    }\n    this.walkExpression(expression.argument);\n  }\n\n  walkLeftRightExpression(expression) {\n    this.walkExpression(expression.left);\n    this.walkExpression(expression.right);\n  }\n\n  walkBinaryExpression(expression) {\n    this.walkLeftRightExpression(expression);\n  }\n\n  walkLogicalExpression(expression) {\n    this.walkLeftRightExpression(expression);\n  }\n\n  walkAssignmentExpression(expression) {\n    const renameIdentifier = this.getRenameIdentifier(expression.right);\n    if (\n      expression.left.type === 'Identifier' &&\n      renameIdentifier &&\n      this.applyMethods('canrename' + renameIdentifier, expression.right)\n    ) {\n      // if(expression.left.type === \"Identifier\" && renameIdentifier && this.applyPluginsBailResult1(\"can-rename \" + renameIdentifier, expression.right)) {\n      // renaming \"a = b;\"\n      if (!this.applyMethods('rename' + renameIdentifier, expression.right)) {\n        // if(!this.applyPluginsBailResult1(\"rename \" + renameIdentifier, expression.right)) {\n        this.scope.renames['$' + expression.left.name] = renameIdentifier;\n        const idx = this.scope.definitions.indexOf(expression.left.name);\n        if (idx >= 0) this.scope.definitions.splice(idx, 1);\n      }\n    } else if (expression.left.type === 'Identifier') {\n      if (!this.applyMethods('assigned' + expression.left.name, expression)) {\n        // if(!this.applyPluginsBailResult1(\"assigned \" + expression.left.name, expression)) {\n        this.walkExpression(expression.right);\n      }\n      this.scope.renames['$' + expression.left.name] = undefined;\n      if (!this.applyMethods('assign' + expression.left.name, expression)) {\n        // if(!this.applyPluginsBailResult1(\"assign \" + expression.left.name, expression)) {\n        this.walkExpression(expression.left);\n      }\n    } else if (\n      expression.left.type === 'MemberExpression' &&\n      expression.left.object.name === '_this' &&\n      expression.left.property.name === 'config' &&\n      expression.right.type === 'ObjectExpression'\n    ) {\n      // _this.config = {}\n      this.config = expression.right;\n    } else if (\n      expression.left.type === 'MemberExpression' &&\n      expression.left.object.name === 'exports' &&\n      (expression.left.property.name === 'default' || expression.left.property.value === 'default') &&\n      expression.right.type === 'Identifier'\n    ) {\n      // _this.config = {}\n      this.export = expression;\n    } else if (\n      expression.left.type === 'MemberExpression' &&\n      expression.left.object.type === 'ThisExpression' &&\n      expression.left.property.name === 'components' &&\n      expression.right.type === 'ObjectExpression'\n    ) {\n      // this.components = {}\n      this.components = expression;\n    } else {\n      this.walkExpression(expression.right);\n      this.walkPattern(expression.left);\n      this.enterPattern(expression.left, name => {\n        this.scope.renames['$' + name] = undefined;\n      });\n    }\n  }\n\n  walkConditionalExpression(expression) {\n    const result = undefined;\n\n    // const result = this.applyPluginsBailResult1(\"expression ?:\", expression);\n    if (result === undefined) {\n      this.walkExpression(expression.test);\n      this.walkExpression(expression.consequent);\n      if (expression.alternate) this.walkExpression(expression.alternate);\n    } else {\n      if (result) this.walkExpression(expression.consequent);\n      else if (expression.alternate) this.walkExpression(expression.alternate);\n    }\n  }\n\n  walkNewExpression(expression) {\n    this.walkExpression(expression.callee);\n    if (expression.arguments) this.walkExpressions(expression.arguments);\n  }\n\n  walkYieldExpression(expression) {\n    if (expression.argument) this.walkExpression(expression.argument);\n  }\n\n  walkTemplateLiteral(expression) {\n    if (expression.expressions) this.walkExpressions(expression.expressions);\n  }\n\n  walkTaggedTemplateExpression(expression) {\n    if (expression.tag) this.walkExpression(expression.tag);\n    if (expression.quasi && expression.quasi.expressions) this.walkExpressions(expression.quasi.expressions);\n  }\n\n  walkClassExpression(expression) {\n    this.walkClass(expression);\n  }\n\n  walkCallExpression(expression) {\n    let result;\n    function walkIIFE(functionExpression, options, currentThis) {\n      function renameArgOrThis(argOrThis) {\n        const renameIdentifier = this.getRenameIdentifier(argOrThis);\n        if (renameIdentifier && this.applyMethods('canrename' + renameIdentifier, argOrThis)) {\n          // if(renameIdentifier && this.applyPluginsBailResult1(\"can-rename \" + renameIdentifier, argOrThis)) {\n          if (!this.applyMethods('rename' + renameIdentifier, argOrThis))\n            // if(!this.applyPluginsBailResult1(\"rename \" + renameIdentifier, argOrThis))\n            return renameIdentifier;\n        }\n        this.walkExpression(argOrThis);\n      }\n      const params = functionExpression.params;\n      const renameThis = currentThis ? renameArgOrThis.call(this, currentThis) : null;\n      const args = options.map(renameArgOrThis, this);\n      this.inScope(\n        params.filter(function(identifier, idx) {\n          return !args[idx];\n        }),\n        () => {\n          if (renameThis) {\n            this.scope.renames.$this = renameThis;\n          }\n          for (let i = 0; i < args.length; i++) {\n            const param = args[i];\n            if (!param) continue;\n            if (!params[i] || params[i].type !== 'Identifier') continue;\n            this.scope.renames['$' + params[i].name] = param;\n          }\n          if (functionExpression.body.type === 'BlockStatement') {\n            this.prewalkStatement(functionExpression.body);\n            this.walkStatement(functionExpression.body);\n          } else this.walkExpression(functionExpression.body);\n        }\n      );\n    }\n    if (\n      expression.callee.type === 'MemberExpression' &&\n      expression.callee.object.type === 'FunctionExpression' &&\n      !expression.callee.computed &&\n      ['call', 'bind'].indexOf(expression.callee.property.name) >= 0 &&\n      expression.arguments &&\n      expression.arguments.length > 0\n    ) {\n      // (function(...) { }.call/bind(?, ...))\n      walkIIFE.call(this, expression.callee.object, expression.arguments.slice(1), expression.arguments[0]);\n    } else if (expression.callee.type === 'FunctionExpression' && expression.arguments) {\n      // (function(...) { }(...))\n      walkIIFE.call(this, expression.callee, expression.arguments);\n    } else if (expression.callee.type === 'Import') {\n      // result = this.applyPluginsBailResult1(\"import-call\", expression);\n      if (result === true) return;\n\n      if (expression.arguments) this.walkExpressions(expression.arguments);\n    } else {\n      if (expression.callee.type === 'MemberExpression') {\n        let exprName = this.getNameForExpression(expression.callee);\n        // For old version compiler-babel, we can remove it later\n        if (this.compilation.hasHook('walker-detect-entry')) {\n          this.compilation.hook('walker-detect-entry', this, expression, exprName);\n        } else {\n          if (this.scope.instances && exprName && this.scope.instances.indexOf(exprName.instance) !== -1) {\n            // calling wepy instance\n            if (['app', 'page', 'component'].indexOf(exprName.callee) !== -1) {\n              this.entry = expression;\n            }\n          }\n        }\n      }\n\n      const callee = this.evaluateExpression(expression.callee);\n      if (callee.identifier) {\n        let fn = `call${callee.identifier}`;\n        if (this[fn]) {\n          result = this[fn](expression);\n        }\n        // result = this.applyPluginsBailResult1(\"call \" + callee.identifier, expression);\n        if (result === true) return;\n        let identifier = callee.identifier.replace(/\\.[^.]+$/, '.*');\n        if (identifier !== callee.identifier) {\n          let fn = `call${identifier}`;\n          if (this[fn]) {\n            result = this[fn](expression);\n          }\n          // result = this.applyPluginsBailResult1(\"call \" + identifier, expression);\n          if (result === true) return;\n        }\n      }\n\n      if (expression.callee) this.walkExpression(expression.callee);\n      if (expression.arguments) this.walkExpressions(expression.arguments);\n    }\n  }\n\n  walkMemberExpression(expression) {\n    const exprName = this.getNameForExpression(expression);\n    if (exprName && exprName.free) {\n      let hookName = 'walker-member-expression-undefined';\n      if (this.compilation.hasHook(hookName)) {\n        this.compilation.hookSeq(hookName, this, expression, exprName);\n      }\n    }\n    this.walkExpression(expression.object);\n    if (expression.computed === true) this.walkExpression(expression.property);\n  }\n\n  walkIdentifier(expression) {\n    if (this.scope.definitions.indexOf(expression.name) === -1) {\n      let hookName = 'walker-identifier-undefined';\n      if (this.compilation.hasHook(hookName)) {\n        this.compilation.hookSeq(hookName, this, expression);\n      }\n    }\n  }\n\n  inScope(params, fn) {\n    const oldScope = this.scope;\n    this.scope = {\n      inTry: false,\n      inShorthand: false,\n      definitions: oldScope.definitions.slice(),\n      renames: Object.create(oldScope.renames)\n    };\n\n    this.scope.renames.$this = undefined;\n\n    for (let paramIndex = 0, len = params.length; paramIndex < len; paramIndex++) {\n      const param = params[paramIndex];\n\n      if (typeof param !== 'string') {\n        this.enterPattern(param, param => {\n          this.scope.renames['$' + param] = undefined;\n          this.scope.definitions.push(param);\n        });\n      } else {\n        this.scope.renames['$' + param] = undefined;\n        this.scope.definitions.push(param);\n      }\n    }\n\n    fn();\n    this.scope = oldScope;\n  }\n\n  enterPattern(pattern, onIdent) {\n    if (pattern && this['enter' + pattern.type]) this['enter' + pattern.type](pattern, onIdent);\n  }\n\n  enterIdentifier(pattern, onIdent) {\n    onIdent(pattern.name, pattern);\n  }\n\n  enterObjectPattern(pattern, onIdent) {\n    for (let propIndex = 0, len = pattern.properties.length; propIndex < len; propIndex++) {\n      const prop = pattern.properties[propIndex];\n      this.enterPattern(prop.value, onIdent);\n    }\n  }\n\n  enterArrayPattern(pattern, onIdent) {\n    for (let elementIndex = 0, len = pattern.elements.length; elementIndex < len; elementIndex++) {\n      const element = pattern.elements[elementIndex];\n      this.enterPattern(element, onIdent);\n    }\n  }\n\n  enterRestElement(pattern, onIdent) {\n    this.enterPattern(pattern.argument, onIdent);\n  }\n\n  enterAssignmentPattern(pattern, onIdent) {\n    this.enterPattern(pattern.left, onIdent);\n  }\n\n  evaluateExpression(expression) {\n    try {\n      let result;\n      let fn = `evaluate${expression.type}`;\n      if (this[fn]) {\n        result = this[fn](expression);\n      }\n      // const result = this.applyPluginsBailResult1(\"evaluate \" + expression.type, expression);\n      if (result !== undefined) return result;\n    } catch (e) {\n      // eslint-disable-next-line no-console\n      console.warn(e);\n      // ignore error\n    }\n    return expression.range;\n    // return new BasicEvaluatedExpression().setRange(expression.range);\n  }\n\n  getRenameIdentifier(expr) {\n    const result = this.evaluateExpression(expr);\n    if (!result) return;\n    if (result.identifier) return result.identifier;\n    return;\n  }\n\n  parseString(expression) {\n    switch (expression.type) {\n      case 'BinaryExpression':\n        if (expression.operator === '+') return this.parseString(expression.left) + this.parseString(expression.right);\n        break;\n      case 'Literal':\n        return expression.value + '';\n    }\n    throw new Error(expression.type + ' is not supported as parameter for require');\n  }\n\n  parseCalculatedString(expression) {\n    switch (expression.type) {\n      case 'BinaryExpression':\n        if (expression.operator === '+') {\n          const left = this.parseCalculatedString(expression.left);\n          const right = this.parseCalculatedString(expression.right);\n          if (left.code) {\n            return {\n              range: left.range,\n              value: left.value,\n              code: true\n            };\n          } else if (right.code) {\n            return {\n              range: [left.range[0], right.range ? right.range[1] : left.range[1]],\n              value: left.value + right.value,\n              code: true\n            };\n          } else {\n            return {\n              range: [left.range[0], right.range[1]],\n              value: left.value + right.value\n            };\n          }\n        }\n        break;\n      case 'ConditionalExpression': {\n        const consequent = this.parseCalculatedString(expression.consequent);\n        const alternate = this.parseCalculatedString(expression.alternate);\n        const items = [];\n        if (consequent.conditional) Array.prototype.push.apply(items, consequent.conditional);\n        else if (!consequent.code) items.push(consequent);\n        else break;\n        if (alternate.conditional) Array.prototype.push.apply(items, alternate.conditional);\n        else if (!alternate.code) items.push(alternate);\n        else break;\n        return {\n          value: '',\n          code: true,\n          conditional: items\n        };\n      }\n      case 'Literal':\n        return {\n          range: expression.range,\n          value: expression.value + ''\n        };\n    }\n    return {\n      value: '',\n      code: true\n    };\n  }\n\n  parseStringArray(expression) {\n    if (expression.type !== 'ArrayExpression') {\n      return [this.parseString(expression)];\n    }\n\n    const arr = [];\n    if (expression.elements)\n      expression.elements.forEach(function(expr) {\n        arr.push(this.parseString(expr));\n      }, this);\n    return arr;\n  }\n\n  parseCalculatedStringArray(expression) {\n    if (expression.type !== 'ArrayExpression') {\n      return [this.parseCalculatedString(expression)];\n    }\n\n    const arr = [];\n    if (expression.elements)\n      expression.elements.forEach(function(expr) {\n        arr.push(this.parseCalculatedString(expr));\n      }, this);\n    return arr;\n  }\n\n  /*\n  parse(source, initialState) {\n    let ast;\n    const comments = [];\n    for (let i = 0, len = POSSIBLE_AST_OPTIONS.length; i < len; i++) {\n      if (!ast) {\n        try {\n          comments.length = 0;\n          POSSIBLE_AST_OPTIONS[i].onComment = comments;\n          ast = acorn.parse(source, POSSIBLE_AST_OPTIONS[i]);\n        } catch (e) {\n          // ignore the error\n        }\n      }\n    }\n    if (!ast) {\n      // for the error\n      ast = acorn.parse(source, {\n        ranges: true,\n        locations: true,\n        ecmaVersion: ECMA_VERSION,\n        sourceType: 'module',\n        plugins: {\n          dynamicImport: true\n        },\n        onComment: comments\n      });\n    }\n    if (!ast || typeof ast !== 'object') throw new Error(\"Source couldn't be parsed\");\n    const oldScope = this.scope;\n    const oldState = this.state;\n    const oldComments = this.comments;\n    this.scope = {\n      inTry: false,\n      definitions: [],\n      renames: {}\n    };\n    const state = (this.state = initialState || {});\n    this.comments = comments;\n    if (this.applyPluginsBailResult('program', ast, comments) === undefined) {\n      this.prewalkStatements(ast.body);\n      this.walkStatements(ast.body);\n    }\n    this.scope = oldScope;\n    this.state = oldState;\n    this.comments = oldComments;\n    return state;\n  } */\n\n  /*\n  evaluate(source) {\n    const ast = acorn.parse('(' + source + ')', {\n      ranges: true,\n      locations: true,\n      ecmaVersion: ECMA_VERSION,\n      sourceType: 'module',\n      plugins: {\n        dynamicImport: true\n      }\n    });\n    if (!ast || typeof ast !== 'object' || ast.type !== 'Program')\n      throw new Error(\"evaluate: Source couldn't be parsed\");\n    if (ast.body.length !== 1 || ast.body[0].type !== 'ExpressionStatement')\n      throw new Error('evaluate: Source is not a expression');\n    return this.evaluateExpression(ast.body[0].expression);\n  }\n\n  getComments(range) {\n    return this.comments.filter(comment => comment.range[0] >= range[0] && comment.range[1] <= range[1]);\n  }\n\n  getCommentOptions(range) {\n    const comments = this.getComments(range);\n    if (comments.length === 0) return null;\n    const options = comments.map(comment => {\n      try {\n        return json5.parse(`{${comment.value}}`);\n      } catch (e) {\n        return {};\n      }\n    });\n    return options.reduce((o, i) => Object.assign(o, i), {});\n  }\n  */\n\n  getNameForExpression(expression) {\n    let expr = expression;\n    const exprName = [];\n    while (expr.type === 'MemberExpression' && expr.property.type === (expr.computed ? 'Literal' : 'Identifier')) {\n      exprName.push(expr.computed ? expr.property.value : expr.property.name);\n      expr = expr.object;\n    }\n    let free;\n    if (expr.type === 'Identifier') {\n      free = this.scope.definitions.indexOf(expr.name) === -1;\n      exprName.push(this.scope.renames['$' + expr.name] || expr.name);\n    } else if (expr.type === 'ThisExpression' && this.scope.renames.$this) {\n      free = true;\n      exprName.push(this.scope.renames.$this);\n    } else if (expr.type === 'ThisExpression') {\n      free = false;\n      exprName.push('this');\n    } else {\n      return null;\n    }\n    let prefix = '';\n    for (let i = exprName.length - 1; i >= 1; i--) prefix += exprName[i] + '.';\n    const name = prefix + exprName[0];\n    const nameGeneral = prefix + '*';\n    return {\n      name,\n      nameGeneral,\n      instance: prefix.substring(0, prefix.length - 1),\n      callee: exprName[0],\n      free\n    };\n  }\n\n  // Plugins\n  evaluateMemberExpression(expression) {\n    let exprName = this.getNameForExpression(expression);\n    if (exprName) {\n      if (exprName.free) {\n        let fn = `evaluateIdentifier${exprName.name}`;\n        let rst;\n        if (this[fn]) {\n          rst = this[fn](expression);\n        }\n        return rst\n          ? rst\n          : {\n              identifier: exprName.name,\n              range: expression.range\n            };\n        // const result = this.applyPluginsBailResult1(\"evaluate Identifier \" + exprName.name, expression);\n        // if(result) return result;\n        // return new BasicEvaluatedExpression().setIdentifier(exprName.name).setRange(expression.range);\n      } else {\n        let fn = `evaluatedefinedIdentifier${exprName.name}`;\n        let rst;\n        if (this[fn]) {\n          rst = this[fn](expression);\n        }\n        return rst;\n        // return this.applyPluginsBailResult1(\"evaluate defined Identifier \" + exprName.name, expression);\n      }\n    }\n  }\n\n  evaluateIdentifier(expr) {\n    const name = this.scope.renames['$' + expr.name] || expr.name;\n    if (this.scope.definitions.indexOf(expr.name) === -1) {\n      let fn = `evaluateIdentifier${name}`;\n      let rst;\n      if (this[fn]) {\n        rst = this[fn](expr);\n      }\n      return rst\n        ? rst\n        : {\n            identifier: name,\n            range: expr.range\n          };\n      // const result = this.applyPluginsBailResult1(\"evaluate Identifier \" + exprName.name, expr);\n      // if(result) return result;\n      // return new BasicEvaluatedexpr().setIdentifier(exprName.name).setRange(expr.range);\n    } else {\n      let fn = `evaluatedefinedIdentifier${name}`;\n      let rst;\n      if (this[fn]) {\n        rst = this[fn](expr);\n      }\n      return rst;\n      // return this.applyPluginsBailResult1(\"evaluate defined Identifier \" + exprName.name, expression);\n    }\n  }\n  applyMethods(method, expr) {\n    let rst;\n    if (this[method]) {\n      rst = this[method](expr);\n    }\n    return rst;\n  }\n  /*\n  callrequire (expr) {\n    // support for browserify style require delegator: \"require(o, !0)\"\n    if(expr.arguments.length !== 2) return;\n    const second = this.evaluateExpression(expr.arguments[1]);\n    if(!second.isBoolean()) return;\n    if(second.asBool() !== true) return;\n    // const dep = new ConstDependency(\"require\", expr.callee.range);\n    const demp = {\n      expression: 'require',\n      range: expr.callee.range\n    };\n    dep.loc = expr.loc;\n    if(this.state.current.dependencies.length > 1) {\n      const last = this.state.current.dependencies[this.state.current.dependencies.length - 1];\n      if(last.critical && last.request === \".\" && last.userRequest === \".\" && last.recursive)\n        this.state.current.dependencies.pop();\n    }\n    this.state.current.addDependency(dep);\n    return true;\n  }*/\n  callrequire(expr) {\n    let param;\n    let dep;\n    let result;\n\n    const old = this.state.current;\n\n    if (expr.arguments.length >= 1) {\n      param = this.evaluateExpression(expr.arguments[0]);\n      dep = {\n        expr: expr,\n        outerRange: param.range,\n        arrayRange: expr.arguments.length > 1 ? expr.arguments[1].range : null,\n        functionRange: expr.arguments.length > 2 ? expr.arguments[2].range : null,\n        errorCallbackRange: this.state.module,\n        module: expr.arguments[0].type === 'Literal' ? expr.arguments[0].value : '',\n        loc: expr.loc\n      };\n      /*\n      dep = new AMDRequireDependenciesBlock(\n        expr,\n        param.range,\n        (expr.arguments.length > 1) ? expr.arguments[1].range : null,\n        (expr.arguments.length > 2) ? expr.arguments[2].range : null,\n        this.state.module,\n        expr.loc\n      );*/\n      this.deps.push(dep);\n      this.state.current = dep;\n    }\n\n    if (expr.arguments.length === 1) {\n      this.inScope([], () => {\n        let fn = `callrequireAmdArray`;\n        result = this[fn] ? this[fn](expr, param) : undefined;\n        // result = this.applyPluginsBailResult(\"call require:amd:array\", expr, param);\n      });\n      this.state.current = old;\n      if (!result) return;\n      // this.state.current.addBlock(dep);\n      return true;\n    }\n\n    if (expr.arguments.length === 2 || expr.arguments.length === 3) {\n      try {\n        this.inScope([], () => {\n          let fn = `callrequireAmdArray`;\n          result = this[fn] ? this[fn](expr, param) : undefined;\n          // result = this.applyPluginsBailResult(\"call require:amd:array\", expr, param);\n        });\n        /*\n        if (!result) {\n          dep = new UnsupportedDependency('unsupported', expr.range);\n          old.addDependency(dep);\n          if (this.state.module)\n            this.state.module.errors.push(\n              new UnsupportedFeatureWarning(\n                this.state.module,\n                'Cannot statically analyse \\'require(..., ...)\\' in line ' + expr.loc.start.line\n              )\n            );\n          dep = null;\n          return true;\n        }\n        dep.functionBindThis = this.processFunctionArgument(parser, expr.arguments[1]);\n        if (expr.arguments.length === 3) {\n          dep.errorCallbackBindThis = this.processFunctionArgument(parser, expr.arguments[2]);\n        }*/\n      } finally {\n        this.state.current = old;\n        if (dep) this.state.current.addBlock(dep);\n      }\n      return true;\n    }\n  }\n\n  callrequireAmdArray(expr, param) {\n    // if(param.isArray()) {\n    if (param.items && param.items.forEach) {\n      param.items.forEach(param => {\n        let result;\n        let fn = `callrequireAmdItem`;\n        if (this[fn]) {\n          result = this[fn](expr, param);\n        }\n        // const result = this.applyPluginsBailResult(\"call require:amd:item\", expr, param);\n        if (result === undefined) {\n          let fn = `callrequireAmdContext`;\n          if (this[fn]) {\n            this[fn](expr, param);\n          }\n          // this.applyPluginsBailResult(\"call require:amd:context\", expr, param);\n        }\n      });\n      return true;\n      // } else if(param.isConstArray()) {\n    } else if (param.array && param.array.length) {\n      const deps = [];\n      param.array.forEach(request => {\n        let dep /*, localModule*/;\n        if (request === 'require') {\n          dep = '__webpack_require__';\n        } else if (['exports', 'module'].indexOf(request) >= 0) {\n          dep = request;\n        } /*else if ((localModule = LocalModulesHelpers.getLocalModule(this.state, request))) {\n          // eslint-disable-line no-cond-assign\n          dep = new LocalModuleDependency(localModule);\n          dep.loc = expr.loc;\n          this.state.current.addDependency(dep);\n        } else {\n          dep = new AMDRequireItemDependency(request);\n          dep.loc = expr.loc;\n          dep.optional = !!this.scope.inTry;\n          this.state.current.addDependency(dep);\n        }*/\n        deps.push(dep);\n      });\n      // const dep = new AMDRequireArrayDependency(deps, param.range);\n      const dep = {\n        // depsArray: depsArray,\n        range: param.range\n      };\n      dep.loc = expr.loc;\n      dep.optional = !!this.scope.inTry;\n      // this.state.current.addDependency(dep);\n      return true;\n    }\n  }\n\n  callrequireAmdItem(expr, param) {\n    if (param.isConditional()) {\n      param.options.forEach(param => {\n        let fn = 'callrequireAmdItem';\n        const result = this[fn] ? this[fn](expr, param) : undefined;\n        // const result = this.applyPluginsBailResult(\"call require:amd:item\", expr, param);\n        if (result === undefined) {\n          let fn = 'callrequireAmdContext';\n          if (this[fn]) {\n            this[fn](expr, param);\n          }\n          this.applyPluginsBailResult('call require:amd:context', expr, param);\n        }\n      });\n      return true;\n    } else if (param.isString()) {\n      /*\n      let dep, localModule;\n      if (param.string === 'require') {\n        dep = new ConstDependency('__webpack_require__', param.string);\n      } else if (param.string === 'module') {\n        dep = new ConstDependency(this.state.module.moduleArgument || 'module', param.range);\n      } else if (param.string === 'exports') {\n        dep = new ConstDependency(this.state.module.exportsArgument || 'exports', param.range);\n      } else if ((localModule = LocalModulesHelpers.getLocalModule(this.state, param.string))) {\n        // eslint-disable-line no-cond-assign\n        dep = new LocalModuleDependency(localModule, param.range);\n      } else {\n        dep = new AMDRequireItemDependency(param.string, param.range);\n      }\n      dep.loc = expr.loc;\n      dep.optional = !!this.scope.inTry;\n      this.state.current.addDependency(dep);\n      */\n      return true;\n    }\n  }\n\n  callrequireAmdContext(/*expr, param*/) {\n    /*\n    const dep = ContextDependencyHelpers.create(AMDRequireContextDependency, param.range, param, expr, options);\n    if (!dep) return;\n    dep.loc = expr.loc;\n    dep.optional = !!this.scope.inTry;\n    this.state.current.addDependency(dep);\n    */\n    return true;\n  }\n}\n\nexports = module.exports = AstWalker;\n"
  },
  {
    "path": "packages/cli/core/ast/wxml.js",
    "content": "const htmlparser = require('htmlparser2');\n\nconst walk = function(ast, opt) {\n  let { type, name, attr } = opt;\n  ast.forEach(item => {\n    if (type && typeof type[item.type] === 'function') {\n      type[item.type].call(null, item);\n    }\n    if (name && typeof name[item.name] === 'function') {\n      name[item.name].call(null, item);\n    }\n    if (attr && item.attribs) {\n      for (let key in item.attribs) {\n        if (attr[key] && typeof attr[key] === 'function') {\n          attr[key].call(null, item, attr, item.attribs[key]);\n        }\n      }\n    }\n  });\n};\n\nconst generate = function(ast) {\n  let str = '';\n  if (!Array.isArray(ast)) {\n    ast = [ast];\n  }\n\n  ast.forEach(item => {\n    if (item.type === 'text') {\n      str += item.data;\n    } else if (item.type === 'tag') {\n      str += '<' + item.name;\n      if (item.attribs) {\n        Object.keys(item.attribs).forEach(attr => {\n          if (item.attribs[attr] !== undefined)\n            str += item.attribs[attr] === true ? ` ${attr}` : ` ${attr}=\"${item.attribs[attr]}\"`;\n        });\n      }\n      str += '>';\n      if (item.children && item.children.length) {\n        str += generate(item.children);\n      }\n      str += `</${item.name}>`;\n    }\n  });\n  return str;\n};\n\nmodule.exports = function ast(html) {\n  return new Promise((resolve, reject) => {\n    const handler = new htmlparser.DomHandler(\n      function(error, dom) {\n        if (error) {\n          reject(error);\n        } else {\n          resolve(dom);\n        }\n      },\n      { withStartIndices: true, withEndIndices: true }\n    );\n    const parser = new htmlparser.Parser(handler, { xmlMode: true });\n    parser.write(html);\n    parser.end();\n  });\n};\n\nmodule.exports.walk = walk;\nmodule.exports.generate = generate;\n"
  },
  {
    "path": "packages/cli/core/compile.js",
    "content": "/**\n * Tencent is pleased to support the open source community by making WePY available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n *\n * Licensed under the MIT License (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n * http://opensource.org/licenses/MIT\n * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n */\nconst fs = require('fs-extra');\nconst path = require('path');\nconst chokidar = require('chokidar');\nconst ResolverFactory = require('enhanced-resolve').ResolverFactory;\nconst node = require('enhanced-resolve/lib/node');\nconst NodeJsInputFileSystem = require('enhanced-resolve/lib/NodeJsInputFileSystem');\nconst CachedInputFileSystem = require('enhanced-resolve/lib/CachedInputFileSystem');\nconst parseOptions = require('./parseOptions');\nconst moduleSet = require('./moduleSet');\nconst fileDep = require('./fileDep');\nconst logger = require('./util/logger');\nconst VENDOR_DIR = require('./util/const').VENDOR_DIR;\nconst Hook = require('./hook');\nconst tag = require('./tag');\nconst { isArr } = require('./util/tools');\nconst { debounce } = require('throttle-debounce');\n\nconst initCompiler = require('./init/compiler');\nconst initParser = require('./init/parser');\nconst initPlugin = require('./init/plugin');\n\nclass Compile extends Hook {\n  constructor(opt) {\n    super();\n    let self = this;\n\n    this.version = require('../package.json').version;\n    this.options = opt;\n\n    if (!path.isAbsolute(opt.entry)) {\n      this.options.entry = path.resolve(path.join(opt.src, opt.entry + opt.wpyExt));\n    }\n\n    this.resolvers = {};\n    this.running = false;\n\n    this.context = process.cwd();\n\n    let appConfig = opt.appConfig || {};\n    let userDefinedTags = appConfig.tags || {};\n\n    this.tags = {\n      htmlTags: tag.combineTag(tag.HTML_TAGS, userDefinedTags.htmlTags),\n      wxmlTags: tag.combineTag(tag.WXML_TAGS, userDefinedTags.wxmlTags),\n      selfCloseTags: tag.SELF_CLOSE_TAGS,\n      html2wxmlMap: tag.combineTagMap(tag.HTML2WXML_MAP, userDefinedTags.html2wxmlMap)\n    };\n\n    this.logger = logger;\n\n    this.inputFileSystem = new CachedInputFileSystem(new NodeJsInputFileSystem(), 60000);\n\n    this.options.resolve.extensions = ['.js', '.ts', '.json', '.node', '.wxs', this.options.wpyExt];\n\n    this.resolvers.normal = ResolverFactory.createResolver(\n      Object.assign(\n        {\n          fileSystem: this.inputFileSystem\n        },\n        this.options.resolve\n      )\n    );\n\n    this.resolvers.context = ResolverFactory.createResolver(\n      Object.assign(\n        {\n          fileSystem: this.inputFileSystem,\n          resolveToContext: true\n        },\n        this.options.resolve\n      )\n    );\n\n    this.resolvers.normal.resolveSync = node.create.sync(\n      Object.assign(\n        {\n          fileSystem: this.inputFileSystem\n        },\n        this.options.resolve\n      )\n    );\n\n    this.resolvers.context.resolveSync = node.create.sync(\n      Object.assign(\n        {\n          fileSystem: this.inputFileSystem,\n          resolveToContext: true\n        },\n        this.options.resolve\n      )\n    );\n\n    let fnNormalBak = this.resolvers.normal.resolve;\n    this.resolvers.normal.resolve = function(...args) {\n      return new Promise((resolve, reject) => {\n        args.push(function(err, filepath, meta) {\n          if (err) {\n            reject(err);\n          } else {\n            resolve({ path: filepath, meta: meta });\n          }\n        });\n        fnNormalBak.apply(self.resolvers.normal, args);\n      });\n    };\n    let fnContextBak = this.resolvers.context.resolve;\n    this.resolvers.context.resolve = function(...args) {\n      return new Promise((resolve, reject) => {\n        args.push(function(err, filepath, meta) {\n          if (err) {\n            reject(err);\n          } else {\n            resolve({ path: filepath, meta: meta });\n          }\n        });\n        fnContextBak.apply(self.resolvers.context, args);\n      });\n    };\n  }\n\n  clear(type) {\n    this.hook('process-clear', type);\n    return this;\n  }\n\n  run() {\n    return this.init().then(() => this.start());\n  }\n\n  init() {\n    this.register('process-clear', () => {\n      this.compiled = {};\n      this.vendors = new moduleSet();\n      this.assets = new moduleSet();\n      this.fileDep = new fileDep();\n    });\n\n    ['output-app', 'output-pages', 'output-components'].forEach(k => {\n      this.register(k, data => {\n        if (!isArr(data)) data = [data];\n\n        data.forEach(v => this.output('wpy', v));\n      });\n    });\n\n    this.register('output-vendor', data => {\n      this.output('vendor', data);\n    });\n\n    this.register('output-assets', list => {\n      list.forEach(file => {\n        this.output('assets', file);\n      });\n    });\n\n    this.register('output-static', () => {\n      let paths = this.options.static;\n      let copy = p => {\n        let relative = path.relative(path.join(this.context, this.options.src), path.join(this.context, p));\n        const target = path.join(this.context, p);\n        if (fs.existsSync(target)) {\n          const dest = path.join(this.context, this.options.output, relative[0] === '.' ? p : relative);\n          return fs.copy(target, dest);\n        }\n        return Promise.resolve(true);\n      };\n      if (typeof paths === 'string') return copy(paths);\n      else if (isArr(paths)) return Promise.all(paths.map(p => copy(p)));\n    });\n\n    initParser(this);\n    initPlugin(this);\n\n    this.hook('process-clear', 'init');\n\n    return initCompiler(this, this.options.compilers);\n  }\n\n  start() {\n    if (this.running) {\n      return;\n    }\n\n    this.running = true;\n    this.logger.info('build app', 'start...');\n\n    this.hookUnique('wepy-parser-wpy', { path: this.options.entry, type: 'app' })\n      .then(app => {\n        let sfc = app.sfc;\n        let config = sfc.config;\n\n        let appConfig = config.parsed.output;\n        if (!appConfig.pages || appConfig.pages.length === 0) {\n          appConfig.pages = [];\n          this.hookUnique('error-handler', {\n            type: 'warn',\n            ctx: app,\n            message: `Missing \"pages\" in App config`\n          });\n        }\n        let pages = appConfig.pages.map(v => {\n          return path.resolve(app.file, '..', v);\n        });\n\n        if (appConfig.subPackages || appConfig.subpackages) {\n          (appConfig.subpackages || appConfig.subPackages).forEach(sub => {\n            // Wepy don't support independent subPackages now\n            if (sub.independent) {\n              this.logger.warn(\n                'Independent subpackages is found in app config. Currently, it is not supported in WePY.'\n              );\n              throw new Error('EXIT');\n            }\n\n            sub.pages.forEach(v => {\n              pages.push(path.resolve(app.file, '../' + sub.root || '', v));\n            });\n          });\n        }\n\n        let pageTasks = pages.map(v => {\n          let file;\n\n          file = v + this.options.wpyExt;\n          if (fs.existsSync(file)) {\n            return this.hookUnique('wepy-parser-wpy', { path: file, type: 'page' });\n          }\n          file = v + '.js';\n          if (fs.existsSync(file)) {\n            return this.hookUnique('wepy-parser-component', { path: file, type: 'page', npm: false });\n          }\n          this.hookUnique('error-handler', {\n            type: 'error',\n            ctx: app,\n            message: `Can not resolve page: ${v}`\n          });\n        });\n\n        let components = [];\n        if (appConfig.usingComponents) {\n          for (let key in appConfig.usingComponents) {\n            let v = appConfig.usingComponents[key];\n            components.push(path.resolve(app.file, '../', v));\n          }\n        }\n\n        let componentsTask = components.map(v => {\n          let file;\n\n          file = v + this.options.wpyExt;\n          if (fs.existsSync(file)) {\n            return this.hookUnique('wepy-parser-wpy', { path: file, type: 'wepy' });\n          }\n          file = v + '.js';\n          if (fs.existsSync(file)) {\n            return this.hookUnique('wepy-parser-component', { path: file, type: 'wepy', npm: false });\n          }\n          this.hookUnique('error-handler', {\n            type: 'error',\n            ctx: app,\n            message: `Can not resolve page: ${v}`\n          });\n        });\n\n        let tasks = [...pageTasks, ...componentsTask];\n        if (appConfig.tabBar && appConfig.tabBar.custom) {\n          let file = path.resolve(app.file, '..', 'custom-tab-bar/index' + this.options.wpyExt);\n          if (fs.existsSync(file)) {\n            tasks.push(this.hookUnique('wepy-parser-wpy', { path: file, type: 'wepy' }));\n          }\n        }\n\n        this.hookSeq('build-app', app);\n        this.hookUnique('output-app', app);\n        return Promise.all(tasks);\n      })\n      .then(this.buildComps.bind(this))\n      .catch(this.handleBuildErr.bind(this));\n  }\n\n  buildComps(comps) {\n    let components = [];\n    let originalComponents = [];\n\n    function buildComponents(comps) {\n      if (!comps) {\n        return Promise.resolve();\n      }\n      this.hookSeq('build-components', comps);\n      this.hookUnique('output-components', comps);\n\n      let tasks = [];\n\n      comps.forEach(comp => {\n        let config = comp.sfc.config || {};\n        let parsed = config.parsed || {};\n        let parsedComponents = parsed.components || [];\n\n        parsedComponents.forEach(com => {\n          if (com.type === 'wepy' && !components.includes(com.path)) {\n            // wepy 组件\n            tasks.push(this.hookUnique('wepy-parser-wpy', com));\n            components.push(com.path);\n          } else if (com.type === 'weapp' && !originalComponents.includes(com.path)) {\n            // 原生组件\n            tasks.push(this.hookUnique('wepy-parser-component', com));\n            originalComponents.push(com.path);\n          }\n        });\n      });\n\n      if (tasks.length) {\n        return Promise.all(tasks).then(buildComponents.bind(this));\n      } else {\n        return Promise.resolve();\n      }\n    }\n\n    return buildComponents\n      .bind(this)(comps)\n      .then(() => {\n        let vendorData = this.hookSeq('build-vendor', {});\n        this.hookUnique('output-vendor', vendorData);\n      })\n      .then(() => {\n        let assetsData = this.hookSeq('build-assets');\n        this.hookUnique('output-assets', assetsData);\n      })\n      .then(() => {\n        return this.hookUnique('output-static');\n      })\n      .then(() => {\n        this.hookSeq('process-done');\n        this.running = false;\n        this.logger.info('build', 'finished');\n        if (this.options.watch) {\n          this.logger.info('watching...');\n          this.watch();\n        }\n      });\n  }\n\n  weappBuild(buildTask) {\n    if (this.running) {\n      return;\n    }\n    this.running = true;\n    this.logger.info('build weapp files', 'start...');\n\n    const tasks = buildTask.files.map(file => {\n      const comp = this.compiled[file];\n\n      return this.hookUnique('wepy-parser-component', comp);\n    });\n\n    Promise.all(tasks)\n      .then(this.buildComps.bind(this))\n      .catch(this.handleBuildErr.bind(this));\n  }\n\n  partialBuild(buildTask) {\n    if (this.running) {\n      return;\n    }\n    this.running = true;\n    this.logger.info('build wpy files', 'start...');\n\n    // just compile these files of wpyExt\n    const tasks = buildTask.files.map(file => {\n      if (fs.existsSync(file)) {\n        let type = 'page';\n        if (this.compiled[file]) {\n          type = this.compiled[file].type;\n        }\n        return this.hookUnique('wepy-parser-wpy', { path: file, type });\n      }\n      this.hookUnique('error-handler', {\n        type: 'error',\n        ctx: {},\n        message: `Can not resolve page: ${file}`\n      });\n    });\n\n    Promise.all(tasks)\n      .then(this.buildComps.bind(this))\n      .catch(this.handleBuildErr.bind(this));\n  }\n\n  assetsBuild(buildTask) {\n    if (this.running) {\n      return;\n    }\n    this.running = true;\n    this.logger.info('build ' + buildTask.assetExt + ' files', 'start...');\n\n    const tasks = buildTask.files.map(file => {\n      const ctx = this.compiled[file];\n      return this.hookUnique('wepy-parser-file', {}, ctx);\n    });\n\n    // just compile, build and out assets\n    Promise.all(tasks)\n      .then(() => {\n        return this.buildComps(undefined);\n      })\n      .catch(this.handleBuildErr.bind(this));\n  }\n\n  handleBuildErr(err) {\n    this.running = false;\n    if (err.message !== 'EXIT') {\n      this.logger.error(err);\n    }\n    if (this.logger.level() !== 'trace') {\n      this.logger.error('compile', 'Compile failed. Add \"--log trace\" to see more details');\n    } else {\n      this.logger.error('compile', 'Compile failed.');\n    }\n    if (this.options.watch) {\n      this.logger.info('watching...');\n      this.watch();\n    }\n  }\n\n  watch() {\n    if (this.watchInitialized) {\n      return;\n    }\n    this.watchInitialized = true;\n    let watchOption = Object.assign({ ignoreInitial: true, depth: 99 }, this.options.watchOption || {});\n    // let target = path.resolve(this.context, this.options.target);\n\n    if (watchOption.ignore) {\n      let type = Object.prototype.toString.call(watchOption.ignore);\n      if (type === '[object String]' || type === '[object RegExp]') {\n        watchOption.ignored = [watchOption.ignored];\n        watchOption.ignored.push(this.options.target);\n      } else if (type === '[object Array]') {\n        watchOption.ignored.push(this.options.target);\n      }\n    } else {\n      watchOption.ignored = [this.options.target];\n    }\n\n    const pendingFiles = [];\n\n    // debounce for watch files\n    const onFileChanged = debounce(300, () => {\n      const changedFiles = pendingFiles.splice(0, pendingFiles.length);\n      if (changedFiles.length > 1) {\n        // if more then one files changed, build the whole app.\n        this.start();\n      } else {\n        let buildTask = {\n          changed: changedFiles[0],\n          partial: true,\n          files: [],\n          outputAssets: false\n        };\n        this.hookAsyncSeq('before-wepy-watch-file-changed', buildTask).then(task => {\n          if (task.weapp && task.files.length > 0) {\n            this.weappBuild(buildTask);\n          } else if (task.outputAssets && task.files.length > 0) {\n            this.assetsBuild(buildTask);\n          } else if (task.partial && task.files.length > 0) {\n            this.partialBuild(buildTask);\n          } else {\n            this.start();\n          }\n        });\n      }\n    });\n\n    chokidar.watch([this.options.src], watchOption).on('all', (evt, filepath) => {\n      if (evt === 'change') {\n        const file = path.resolve(filepath);\n        if (!pendingFiles.includes(file)) {\n          pendingFiles.push(file);\n        }\n        onFileChanged();\n      }\n    });\n  }\n\n  applyCompiler(node, ctx) {\n    ctx.id = this.assets.add(ctx.file);\n\n    if (node.lang) {\n      let hookKey = 'wepy-compiler-' + node.lang;\n\n      if (!this.hasHook(hookKey)) {\n        throw `Missing plugins ${hookKey}`;\n      }\n\n      let task;\n\n      // If file is not changed, and compiled cache exsit.\n      // Style may have dependences, maybe the dependences file changed. so ignore the cache for the style who have deps.\n      if (ctx.useCache && node.compiled && (node.compiled.dep || []).length === 0) {\n        task = Promise.resolve(node);\n      } else {\n        task = this.hookUnique(hookKey, node, ctx);\n      }\n      return task\n        .then(node => {\n          return this.hookAsyncSeq('before-wepy-parser-' + node.type, { node, ctx });\n        })\n        .then(({ node, ctx }) => {\n          return this.hookUnique('wepy-parser-' + node.type, node, ctx);\n        });\n    }\n  }\n\n  getTarget(file, targetDir) {\n    let relative = path.relative(path.join(this.context, this.options.src), file);\n    let targetFile = path.join(this.context, targetDir || this.options.target, relative);\n    return targetFile;\n  }\n\n  getModuleTarget(file, targetDir) {\n    let relative = path.relative(this.context, file);\n    let dirs = relative.split(path.sep);\n    dirs.shift(); // shift node_modules\n    relative = dirs.join(path.sep);\n    let targetFile = path.join(this.context, targetDir || this.options.target, VENDOR_DIR, relative);\n    return targetFile;\n  }\n\n  outputFile(filename, code, encoding) {\n    this.hookAsyncSeq('output-file', { filename, code, encoding })\n      .then(({ filename, code, encoding }) => {\n        if (!code) {\n          logger.silly('output', 'empty content: ' + filename);\n        } else {\n          logger.silly('output', 'write file: ' + filename);\n\n          fs.outputFile(filename, code, encoding || 'utf-8', err => {\n            if (err) {\n              // eslint-disable-next-line no-console\n              console.log(err);\n            }\n          });\n        }\n      })\n      .catch(e => {\n        if (e.handler) {\n          this.hookUnique('error-handler', e.handler, e.error, e.pos);\n        } else {\n          // TODO\n          throw e;\n        }\n      });\n  }\n\n  output(type, item) {\n    let filename, code, encoding;\n\n    if (type === 'wpy') {\n      const sfc = item.sfc;\n      const outputMap = {\n        script: 'js',\n        styles: 'wxss',\n        config: 'json',\n        template: 'wxml'\n      };\n\n      Object.keys(outputMap).forEach(k => {\n        if (sfc[k] && sfc[k].outputCode) {\n          filename = item.outputFile + '.' + outputMap[k];\n          code = sfc[k].outputCode;\n\n          this.outputFile(filename, code, encoding);\n        }\n      });\n    } else {\n      filename = item.targetFile;\n      code = item.outputCode;\n      encoding = item.encoding;\n\n      this.outputFile(filename, code, encoding);\n    }\n  }\n}\n\nexports = module.exports = program => {\n  const opt = parseOptions.parse(program);\n\n  const compilation = new Compile(opt);\n\n  return compilation;\n};\n"
  },
  {
    "path": "packages/cli/core/fileDep.js",
    "content": "class FileDep {\n  constructor() {\n    this._depMap = {};\n    this._depedMap = {};\n  }\n\n  cleanDeps(source) {\n    const deps = this._depMap[source] || [];\n    deps.forEach(dep => {\n      const depeds = this._depedMap[dep] || [];\n      if (depeds.length > 0) {\n        this._depedMap[dep] = depeds.filter(deped => deped !== source);\n        if (this._depedMap[dep].length === 0) {\n          delete this._depedMap[dep];\n        }\n      }\n    });\n    delete this._depMap[source];\n  }\n\n  addDeps(source, deps = []) {\n    if (!this._depMap[source]) {\n      this._depMap[source] = [];\n    }\n    deps.forEach(dep => {\n      if (!this._depMap[source].includes(dep)) {\n        this._depMap[source].push(dep);\n        if (!this._depedMap[dep]) {\n          this._depedMap[dep] = [];\n        }\n        this._depedMap[dep].push(source);\n      }\n    });\n  }\n\n  getDeps(source) {\n    return this._depMap[source] || [];\n  }\n\n  getSources(dep) {\n    return this._depedMap[dep] || [];\n  }\n\n  isInvolved(file) {\n    return this._depMap.hasOwnProperty(file) || this._depedMap.hasOwnProperty(file);\n  }\n}\n\nexports = module.exports = FileDep;\n"
  },
  {
    "path": "packages/cli/core/hook.js",
    "content": "class Hook {\n  constructor() {\n    this._hooks = {};\n  }\n\n  register(key, fn) {\n    if (!this._hooks[key]) {\n      this._hooks[key] = [];\n    }\n    this._hooks[key].push(fn);\n\n    return () => {\n      this.unregister(key, fn);\n    };\n  }\n\n  hasHook(key) {\n    return (this._hooks[key] || []).length > 0;\n  }\n\n  hook(key, ...args) {\n    let rst = [];\n    let fns = this._hooks[key] || [];\n    fns.forEach(fn => {\n      typeof fn === 'function' && rst.push(fn.apply(this, args));\n    });\n    return rst;\n  }\n\n  hookSeq(key, ...args) {\n    let rst = args;\n    let fns = this._hooks[key] || [];\n    let hasHook = false;\n\n    fns.forEach((fn, i) => {\n      if (typeof fn === 'function') {\n        hasHook = true;\n        if (fn.length > 1) {\n          rst = fn.apply(this, rst);\n        } else {\n          rst = fn.call(this, i === 0 ? rst[0] : rst);\n        }\n      }\n    });\n\n    return hasHook ? rst : rst.length <= 1 ? rst[0] : rst;\n  }\n\n  hookUnique(key, ...args) {\n    let fns = this._hooks[key] || [];\n    let lastFn = fns[fns.length - 1];\n\n    if (typeof lastFn === 'function') {\n      return lastFn.apply(this, args);\n    }\n  }\n\n  hookUniqueReturnArg(key, ...args) {\n    let rst = this.hookUnique(key, ...args);\n    if (typeof rst === 'undefined') {\n      rst = args.length <= 1 ? args[0] : args;\n    }\n    return rst;\n  }\n\n  hookAsyncSeq(key, ...args) {\n    // if hook registered, return last rst, else return args\n    let rst = args;\n    let fns = this._hooks[key] || [];\n    let lastRst = rst;\n    let argLength = args.length;\n\n    if (fns.length === 0) {\n      return Promise.resolve(argLength === 1 ? args[0] : args);\n    }\n\n    const iterateFunc = (pfn, cfn) => {\n      return pfn.then(v => {\n        if (!Array.isArray(v)) {\n          v = [v];\n        }\n        lastRst = v;\n        return cfn.apply(this, lastRst);\n      });\n    };\n\n    fns = fns.concat((...lastRst) => Promise.resolve(argLength === 1 ? lastRst[0] : lastRst));\n\n    return fns.reduce(iterateFunc, Promise.resolve(args));\n  }\n\n  hookReturnOrigin(key, ...args) {\n    let fns = this._hooks[key] || [];\n    fns.forEach(fn => {\n      typeof fn === 'function' && fn.apply(this, args);\n    });\n    return args.length <= 1 ? args[0] : args;\n  }\n\n  unregister(key, fn) {\n    let fns = this._hooks[key];\n    if (fns && typeof fn === 'function') {\n      fns = fns.filter(f => f !== fn);\n      if (fns.length > 0) {\n        this._hooks[key] = fns;\n      } else {\n        delete this._hooks[key];\n      }\n    }\n  }\n\n  unregisterAll(key) {\n    delete this._hooks[key];\n  }\n}\n\nexports = module.exports = Hook;\n"
  },
  {
    "path": "packages/cli/core/init/compiler.js",
    "content": "exports = module.exports = function initCompiler(ins, compilers = {}) {\n  let init = Object.keys(compilers).map(c => {\n    let module;\n    let moduleName = `@wepy/compiler-${c}`;\n    return ins.resolvers.context\n      .resolve({}, ins.context, moduleName, {})\n      .then(rst => {\n        try {\n          module = require(rst.path);\n        } catch (e) {\n          ins.logger.error('init', `Failed to load model \"${moduleName}\"`);\n          ins.logger.error('init', e);\n        }\n        module && module(compilers[c]).call(ins);\n        return module;\n      })\n      .catch(e => {\n        ins.logger.error(\n          'init',\n          `Make sure module \"${moduleName}\" is installed. If not please try \"npm install ${moduleName} --save-dev\".`\n        );\n        ins.logger.error('init', e);\n      });\n  });\n  return Promise.all(init).then(compilers => {\n    if (compilers.some(c => !c)) {\n      throw new Error('Initialize failed');\n    }\n    return true;\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/init/parser.js",
    "content": "exports = module.exports = function initParser(ins) {\n  ['wpy', 'script', 'style', 'template', 'config', 'component', 'wxs', 'file'].forEach(k => {\n    require('../plugins/parser/' + k).call(ins);\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/init/plugin.js",
    "content": "const { isArr, isFunc } = require('../util/tools');\n\nfunction checkPlugins(ins, plugins) {\n  if (!isArr(plugins)) {\n    plugins = [plugins];\n  }\n  plugins.forEach(plg => {\n    // ensure plugin is a function\n    // or process would be exit\n    if (!isFunc(plg)) {\n      ins.logger.error(\n        'init',\n        'Plugins init error, plugin must be a function.\\n' + 'Please check your plugin in wepy.config.js file'\n      );\n      throw new Error('EXIT');\n    }\n  });\n\n  return plugins;\n}\n\nexports = module.exports = function(ins) {\n  // system plugins\n  [\n    './../plugins/scriptDepFix',\n    './../plugins/scriptInjection',\n    './../plugins/build/app',\n    './../plugins/build/pages',\n    './../plugins/build/components',\n    './../plugins/build/vendor',\n    './../plugins/build/assets',\n\n    './../plugins/template/parse',\n\n    './../plugins/template/attrs',\n    './../plugins/template/directives',\n\n    './../plugins/helper/supportSrc',\n    './../plugins/helper/sfcCustomBlock',\n    './../plugins/helper/generateCodeFrame',\n    './../plugins/helper/errorHandler',\n\n    './../plugins/compiler/index'\n  ].map(v => require(v).call(ins));\n  // check custom plugins\n  const customPluginFns = checkPlugins(ins, ins.options.plugins);\n\n  customPluginFns.map(fn => fn.call(ins));\n};\n"
  },
  {
    "path": "packages/cli/core/loader.js",
    "content": "/**\n * Tencent is pleased to support the open source community by making WePY available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n *\n * Licensed under the MIT License (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n * http://opensource.org/licenses/MIT\n * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n */\n\nconst Module = require('module');\nconst path = require('path');\nconst logger = require('./util/logger');\n\nlet relativeModules = {};\nlet requiredModules = {};\n\nlet loadedPlugins = [];\n\nclass PluginHelper {\n  constructor(plugins, op) {\n    this.applyPlugin(0, op);\n    return true;\n  }\n  applyPlugin(index, op) {\n    let plg = loadedPlugins[index];\n\n    if (!plg) {\n      op.done && op.done(op);\n    } else {\n      op.next = () => {\n        this.applyPlugin(index + 1, op);\n      };\n      op.catch = () => {\n        op.error && op.error(op);\n      };\n      if (plg) plg.apply(op);\n    }\n  }\n}\n\nexports = module.exports = {\n  attach(resolve) {\n    this.resolve = resolve;\n  },\n  loadCompiler(lang) {\n    if (['wxml', 'xml', 'css', 'js'].indexOf(lang) > -1) {\n      return c => {\n        return Promise.resolve(c);\n      };\n    }\n\n    let name = 'wepy-compiler-' + lang;\n    let compiler = this.load(name);\n\n    if (!compiler) {\n      this.missingNPM = name;\n      logger.warn('loader', `Missing compiler: ${name}.`);\n    }\n    return compiler;\n  },\n\n  getNodeModulePath(loc, relative) {\n    relative = relative || process.cwd();\n    if (typeof Module === 'object') return null;\n\n    let relativeMod = relativeModules[relative];\n    let paths = [];\n\n    if (!relativeMod) {\n      relativeMod = new Module();\n\n      let filename = path.join(relative, './');\n      relativeMod.id = filename;\n      relativeMod.filename = filename;\n      relativeMod.paths = [].concat(this.resolve.modulePaths);\n\n      paths = Module._nodeModulePaths(relative);\n      relativeModules[relative] = relativeMod;\n    }\n    paths.forEach(v => {\n      if (relativeMod.paths.indexOf(v) === -1) {\n        relativeMod.paths.push(v);\n      }\n    });\n    try {\n      return Module._resolveFilename(loc, relativeMod);\n    } catch (err) {\n      return null;\n    }\n  },\n  load(loc, relative) {\n    if (requiredModules[loc]) return requiredModules[loc];\n\n    let modulePath = this.getNodeModulePath(loc, relative);\n    let m = null;\n    try {\n      m = require(modulePath);\n    } catch (e) {\n      // eslint-disable-next-line no-console\n      if (e.message !== 'missing path') console.log(e);\n    }\n    if (m) {\n      m = m.default ? m.default : m;\n      requiredModules[loc] = m;\n    }\n    return m;\n  },\n\n  loadPlugin(plugins) {\n    let plg, plgkey, setting;\n    for (plgkey in plugins) {\n      let name = 'wepy-plugin-' + plgkey;\n      setting = plugins[plgkey];\n      plg = this.load(name);\n\n      if (!plg) {\n        this.missingNPM = name;\n        logger.warn('loader', `Missing plugin: ${name}`);\n        return false;\n      }\n      loadedPlugins.push(new plg(setting));\n    }\n    return true;\n  },\n  PluginHelper: PluginHelper\n};\n"
  },
  {
    "path": "packages/cli/core/moduleSet.js",
    "content": "/**\n * Tencent is pleased to support the open source community by making WePY available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n *\n * Licensed under the MIT License (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n * http://opensource.org/licenses/MIT\n * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n */\n\nclass ModuleSet {\n  constructor() {\n    this._index = -1;\n    this._map = {};\n    this._set = {};\n    this._array = {};\n    this._type = {};\n  }\n\n  add(file, type) {\n    let id = this.get(file);\n\n    if (id === undefined) {\n      this._index++;\n      this.length = this._index + 1;\n      id = this._index;\n      this._map[file] = id;\n      this._array[id] = file;\n      this._type[file] = type;\n    }\n\n    return id;\n  }\n\n  get(file) {\n    return this._map[file];\n  }\n\n  pending(file) {\n    return this.get(file) !== undefined && this._set[file] === undefined;\n  }\n\n  update(file, data, type) {\n    if (!this.get(file)) {\n      this.add(file, type);\n    }\n    this._set[file] = data;\n    this._type[file] = type;\n  }\n\n  data(v) {\n    if (typeof v === 'number') {\n      return this._set[this._array[v]];\n    } else {\n      return this._set[v];\n    }\n  }\n\n  array(type) {\n    if (!type) {\n      this._array.length = this.length;\n      return Array.prototype.slice.apply(this._array);\n    } else {\n      return this.array().filter(file => this._type[file] === type);\n    }\n  }\n\n  type(v) {\n    if (typeof v === 'number') {\n      return this._type[this._array[v]];\n    } else {\n      return this._type[v];\n    }\n  }\n}\n\nexports = module.exports = ModuleSet;\n"
  },
  {
    "path": "packages/cli/core/parseOptions.js",
    "content": "const path = require('path');\nconst fs = require('fs');\n\nconst DEFAULT_OPTIONS = {\n  entry: { type: String, default: 'app' },\n  src: { type: String, default: 'src' },\n  target: { type: String, default: 'weapp' },\n  static: { type: [String, Array], default: 'static' },\n  output: { type: String, default: 'weapp' },\n  platform: { type: String },\n  wpyExt: { type: String, default: '.wpy' },\n  eslint: { type: Boolean, default: true },\n  cliLogs: { type: Boolean, default: false },\n  watch: { type: Boolean, default: false },\n  watchOption: { type: Object },\n  noCache: { type: Boolean, default: false },\n  'build.web': { type: Object },\n  'build.web.htmlTemplate': { type: String },\n  'build.web.htmlOutput': { type: String },\n  'build.web.jsOutput': { type: String },\n  'build.web.resolve': { type: Object, link: 'resolve' },\n  resolve: { type: Object, default: {} },\n  compilers: { type: Object },\n  plugins: { type: Array, default: [] },\n  appConfig: { type: Object },\n  'appConfig.noPromiseAPI': { type: Array, default: [] }\n};\n\nconst DEFAULT_CONFIG = path.resolve('wepy.config.js');\n\nfunction setValue(obj, key, val) {\n  let arr = key.split('.');\n  let left = obj;\n  for (let i = 0, l = arr.length; i < l; i++) {\n    if (i === l - 1) {\n      left[arr[i]] = val;\n    } else {\n      if (typeof left[arr[i]] !== 'object') {\n        left[arr[i]] = {};\n      }\n      left = left[arr[i]];\n    }\n  }\n  return obj;\n}\n\nfunction getValue(obj, key) {\n  let arr = key.split('.');\n  let left = obj;\n  let rst;\n  for (let i = 0, l = arr.length; i < l; i++) {\n    if (i === l - 1) {\n      rst = left[arr[i]];\n    } else {\n      if (typeof left[arr[i]] === 'undefined') {\n        break;\n      }\n      left = left[arr[i]];\n    }\n  }\n  return rst;\n}\n\nfunction check(t, val) {\n  if (Array.isArray(t)) {\n    return t.some(type => check(type, val));\n  }\n  switch (t) {\n    case String:\n      return typeof val === 'string';\n    case Number:\n      return typeof val === 'number';\n    case Boolean:\n      return typeof val === 'boolean';\n    case Function:\n      return typeof val === 'function';\n    case Object:\n      return typeof val === 'object';\n    case Array:\n      return toString.call(val) === '[object Array]';\n    default:\n      return val instanceof t;\n  }\n}\n\nfunction parse(opt = {}, baseOpt = DEFAULT_OPTIONS, fromCommandLine) {\n  let ret = {};\n\n  for (let k in baseOpt) {\n    let defaultItem = baseOpt[k];\n    let val = getValue(opt, k);\n\n    if (val === undefined) {\n      if (defaultItem.default !== undefined && !fromCommandLine) {\n        setValue(ret, k, defaultItem.default);\n      }\n    } else {\n      if (!check(defaultItem.type, val)) {\n        throw new Error(`Unexpected type: ${k} expect a ${defaultItem.type.name}`);\n      }\n      setValue(ret, k, val);\n    }\n  }\n  return ret;\n}\n\nfunction convert(args) {\n  if (!fs.existsSync(DEFAULT_CONFIG)) {\n    throw new Error(`No configuration file found in the current directory.`);\n  }\n\n  let opt = require(DEFAULT_CONFIG);\n  let argOpt = parse(args, DEFAULT_OPTIONS, true);\n\n  return Object.assign({}, parse(opt), argOpt);\n}\n\nexports = module.exports = {\n  setValue: setValue,\n  getValue: getValue,\n  parse: parse,\n  convert: convert\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/build/app.js",
    "content": "const path = require('path');\n\nexports = module.exports = function() {\n  this.register('build-app', function buildApp(app) {\n    this.logger.info('app', 'building App');\n\n    let { script, styles, config } = app.sfc;\n\n    let targetFile = path.join(this.context, this.options.target, 'app');\n\n    config.outputCode = JSON.stringify(config.parsed.output, null, 4);\n\n    this.hook('script-dep-fix', script.parsed);\n    this.hook('script-injection', script.parsed, this.options.appConfig);\n    script.outputCode = script.parsed.source.source();\n\n    let styleCode = '';\n\n    styles.forEach(v => {\n      styleCode += v.parsed.code + '\\n';\n    });\n\n    styles.outputCode = styleCode;\n\n    app.outputFile = targetFile;\n\n    return app;\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/build/assets.js",
    "content": "const path = require('path');\n\nexports = module.exports = function() {\n  this.register('build-assets', function buildAssets() {\n    this.logger.info('assets', 'building assets');\n\n    let result = [];\n\n    this.assets.array().forEach(file => {\n      let t = this.assets.type(file);\n      let d = this.assets.data(file);\n\n      if (t.npm) {\n        if (t.type === 'weapp') {\n          if (!t.wxs && t.component) {\n            // it's a npm weapp component, like vant-weapp.\n            // output-components will generate the code for vant-weapp himself\n            return;\n          } else {\n            // it's in weapp component, maybe they require a lib in the component\n            // this will goes to build asserts.\n          }\n        } else if (!t.wxs && t.dep && !t.component) {\n          // it's a vendor, will go to vendor build\n          return;\n        }\n      } else {\n        // it's a component and it's not a dependences\n        if (!t.wxs && t.component && !t.dep) {\n          return;\n        }\n      }\n      ///////////////////\n      // asserts build\n      //////////////////\n      if (!t.wxs && !t.url) {\n        this.hook('script-dep-fix', d);\n      }\n\n      let filePath = file;\n      let fileObj = path.parse(file);\n\n      // For typescript, it should output .js\n      if (d.outputFileName && d.outputFileName !== fileObj.base) {\n        filePath = path.join(fileObj.dir, d.outputFileName);\n      }\n\n      let targetFile = t.npm ? this.getModuleTarget(filePath) : this.getTarget(filePath);\n      result.push({\n        src: file,\n        targetFile: targetFile,\n        outputCode: d.source.source(),\n        encoding: d.encoding\n      });\n    });\n\n    return result;\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/build/components.js",
    "content": "const path = require('path');\n\nexports = module.exports = function() {\n  this.register('build-components', function buildComponents(comps) {\n    this.logger.info('component', 'building components');\n\n    comps.forEach(comp => {\n      let { script, styles, config, template, wxs } = comp.sfc;\n\n      let styleCode = '';\n      styles.forEach(v => {\n        styleCode += v.parsed.code + '\\n';\n      });\n      config.parsed.output.component = true;\n      const { usingComponents, ...other } = config.parsed.output;\n      let output = {\n        ...other,\n        usingComponents: usingComponents\n      };\n      config.outputCode = JSON.stringify(output, null, 4);\n      this.hook('script-dep-fix', script.parsed);\n      if (!script.empty && !(comp.component && comp.type === 'weapp')) {\n        this.hook('script-injection', script.parsed, template.parsed.rel);\n      }\n      script.outputCode = script.parsed.source.source();\n      styles.outputCode = styleCode;\n      template.outputCode = template.parsed.code;\n\n      if (wxs && wxs.length) {\n        let wxsCode = '';\n        wxs.forEach(item => {\n          wxsCode += item.parsed.output + '\\n';\n        });\n        template.outputCode =\n          '<!----------   wxs start ----------->\\n' +\n          wxsCode +\n          '<!----------   wxs end   ----------->\\n' +\n          template.outputCode;\n      }\n      let targetFile = comp.npm ? this.getModuleTarget(comp.file) : this.getTarget(comp.file);\n      let target = path.parse(targetFile);\n      comp.outputFile = path.join(target.dir, target.name);\n    });\n\n    return comps;\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/build/pages.js",
    "content": "const path = require('path');\n\nexports = module.exports = function() {\n  this.register('build-pages', function buildPages(pages) {\n    this.logger.info('page', 'building pages');\n\n    pages.forEach(page => {\n      let { script, styles, config, template } = page.sfc;\n\n      let styleCode = '';\n      styles.forEach(v => {\n        styleCode += v.parsed.code + '\\n';\n      });\n\n      config.outputCode = JSON.stringify(config.parsed.output, null, 4);\n\n      this.hook('script-dep-fix', script.parsed);\n      this.hook('script-injection', script.parsed, template.parsed.rel);\n\n      script.outputCode = script.parsed.source.source();\n\n      styles.outputCode = styleCode;\n      template.outputCode = template.parsed.code;\n\n      let targetFile = this.getTarget(page.file);\n      let target = path.parse(targetFile);\n      page.outputFile = path.join(target.dir, target.name);\n    });\n\n    return pages;\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/build/vendor.js",
    "content": "const path = require('path');\n\nconst VENDOR_INJECTION = [\n  `\nvar window = { Number: Number, Array: Array, Date: Date, Error: Error, Math: Math, Object: Object, Function: Function, RegExp: RegExp, String: String, TypeError: TypeError, parseInt: parseInt, parseFloat: parseFloat, isNaN: isNaN };\nvar global = window;\nvar process = { env: {} };\n(function(modules) {\n   // The module cache\n   var installedModules = {};\n   // The require function\n   function __wepy_require(moduleId) {\n       // Check if module is in cache\n       if(installedModules[moduleId])\n           return installedModules[moduleId].exports;\n       // Create a new module (and put it into the cache)\n       var module = installedModules[moduleId] = {\n           exports: {},\n           id: moduleId,\n           loaded: false\n       };\n       // Execute the module function\n       modules[moduleId].call(module.exports, module, module.exports, __wepy_require);\n       // Flag the module as loaded\n       module.loaded = true;\n       // Return the exports of the module\n       return module.exports;\n   }\n   // expose the modules object (__webpack_modules__)\n   __wepy_require.m = modules;\n   // expose the module cache\n   __wepy_require.c = installedModules;\n   // __webpack_public_path__\n   __wepy_require.p = \"/\";\n   // Load entry module and return exports\n   module.exports = __wepy_require;\n   return __wepy_require;\n})([\n`,\n  '',\n  ']);'\n];\n\nexports = module.exports = function() {\n  this.register('build-vendor', function buildPages(vendor) {\n    this.logger.info('vendor', 'building vendor');\n\n    let vendorList = this.vendors.array();\n    let code = '';\n\n    vendorList.forEach((item, i) => {\n      let data = this.vendors.data(item);\n\n      this.hook('script-dep-fix', data, true);\n\n      code += '/***** module ' + i + ' start *****/\\n';\n      code += '/***** ' + data.file + ' *****/\\n';\n      code += 'function(module, exports, __wepy_require) {';\n      code += data.source.source() + '\\n';\n      code += '}';\n      if (i !== vendorList.length - 1) {\n        code += ',';\n      }\n      code += '/***** module ' + i + ' end *****/\\n\\n\\n';\n    });\n\n    let template = VENDOR_INJECTION.concat([]);\n    template[1] = code;\n\n    vendor.outputCode = template.join('');\n    vendor.targetFile = path.join(this.context, this.options.target, 'vendor.js');\n\n    return vendor;\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/compiler/before.js",
    "content": "const path = require('path');\nconst CONST = require('../../util/const');\n\nexports = module.exports = function() {\n  const styleHooker = (content, options) => {\n    options.supportObject = true;\n  };\n\n  this.register('before-compiler-less', styleHooker);\n  this.register('before-compiler-sass', styleHooker);\n  this.register('before-compiler-stylus', styleHooker);\n\n  // When file changed in --watch model\n  this.register('before-wepy-watch-file-changed', function beforeWatchFileChanged(buildTask) {\n    const changedFile = buildTask.changed;\n    const parsedPath = path.parse(changedFile);\n    const weappCacheKey = path.join(parsedPath.dir, parsedPath.name) + CONST.WEAPP_EXT;\n\n    const isInvolved = this.fileDep.isInvolved(changedFile);\n    const isWeappInvolved = this.fileDep.isInvolved(weappCacheKey);\n\n    this.fileDep.getSources(changedFile).forEach(depedFile => {\n      if (path.isAbsolute(depedFile)) {\n        // clear the file hash, to remove the file cache\n        this.compiled[depedFile].hash = '';\n      }\n    });\n\n    if (isInvolved) {\n      this.logger.silly('watch', `Watcher triggered by file changes: ${changedFile}`);\n      const isEntry = changedFile === this.options.entry;\n      let ext = path.extname(changedFile);\n      const isWPY = ext === this.options.wpyExt;\n      ext = ext.substring(1);\n\n      if (isEntry) {\n        buildTask.partial = false;\n      } else if (isWPY) {\n        buildTask.partial = true;\n        buildTask.files.push(changedFile);\n      } else {\n        buildTask = this.hookSeq('wepy-watch-file-changed-' + ext, buildTask);\n      }\n    }\n\n    if (isWeappInvolved) {\n      this.logger.silly('watch', `Watcher triggered by file changes: ${changedFile}`);\n      buildTask.changed = weappCacheKey;\n      buildTask = this.hookSeq('wepy-watch-file-changed-weapp', buildTask);\n    }\n\n    return Promise.resolve(buildTask);\n  });\n\n  this.register('wepy-watch-file-changed-weapp', function(buildTask) {\n    buildTask.weapp = true;\n    buildTask.files.push(buildTask.changed);\n\n    return buildTask;\n  });\n\n  // when .wxs file changed\n  this.register('wepy-watch-file-changed-wxs', function(buildTask) {\n    let queue = [];\n    const wpyExtFiles = [];\n\n    // find wpyExtFiles of deped\n    queue = queue.concat(this.fileDep.getSources(buildTask.changed));\n    while (queue.length > 0) {\n      const depedFile = queue.shift();\n      if (path.extname(depedFile) === this.options.wpyExt) {\n        wpyExtFiles.push(depedFile);\n      } else {\n        queue = queue.concat(this.fileDep.getSources(depedFile));\n      }\n    }\n\n    buildTask.files = wpyExtFiles;\n    if (buildTask.files.includes(this.options.entry)) {\n      buildTask.partial = false;\n    }\n\n    return buildTask;\n  });\n\n  // when .js, .ts file changed\n  ['js', 'ts'].forEach(ext => {\n    this.register('wepy-watch-file-changed-' + ext, function(buildTask) {\n      buildTask.outputAssets = true;\n      buildTask.files.push(buildTask.changed);\n      buildTask.assetExt = ext;\n\n      return buildTask;\n    });\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/compiler/common.js",
    "content": "exports = module.exports = function() {\n  ['js', 'json', 'css', 'wxml'].forEach(lang => {\n    this.register('wepy-compiler-' + lang, function(node) {\n      node.compiled = {\n        code: node.content\n      };\n      return Promise.resolve(node);\n    });\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/compiler/index.js",
    "content": "exports = module.exports = function() {\n  require('./common').call(this);\n  require('./wxss').call(this);\n  require('./before').call(this);\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/compiler/wxss.js",
    "content": "const css = require('css');\nconst path = require('path');\nconst fs = require('fs');\nconst RawSource = require('webpack-sources').RawSource;\n\nexports = module.exports = function() {\n  this.register('wepy-compiler-wxss', function(node, ctx) {\n    let code = node.content;\n\n    let ast = css.parse(code);\n\n    ast.stylesheet.rules.forEach(rule => {\n      if (rule.type === 'import') {\n        let importfile = rule.import;\n        // eslint-disable-next-line\n        if (importfile.startsWith('\"') || importfile.startsWith(\"'\")) {\n          importfile = importfile.substring(1, importfile.length - 1);\n        }\n        importfile = path.resolve(ctx.file, '..', importfile);\n\n        let encoding = 'utf-8';\n\n        if (this.assets.get(importfile) === undefined) {\n          let importCode;\n\n          try {\n            importCode = fs.readFileSync(importfile, encoding);\n          } catch (e) {\n            this.logger.warn('compiler', `Can not open file ${importfile} in ${ctx.file}`);\n          }\n\n          if (importCode) {\n            // add assets dependencies\n            this.assets.update(\n              importfile,\n              {\n                encoding: encoding,\n                source: new RawSource(importCode)\n              },\n              { url: true, npm: ctx.npm }\n            );\n\n            this.hookUnique(\n              'wepy-compiler-wxss',\n              {\n                content: importCode\n              },\n              Object.assign({}, ctx, { dep: true })\n            );\n          }\n        }\n      }\n    });\n    node.compiled = {\n      code: node.content\n    };\n    return Promise.resolve(node);\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/helper/errorHandler.js",
    "content": "exports = module.exports = function() {\n  this.register('error-handler', function(handler, errInfo, extra) {\n    if (arguments.length === 1) {\n      if (typeof handler === 'object') {\n        errInfo = handler;\n        let { ctx, message, type, snapshot, file, title } = errInfo;\n        let output = 'Message:\\n  ' + message;\n        if (ctx && ctx.file) {\n          file = ctx.file;\n        }\n        if (file) {\n          output += '\\n' + 'File:\\n  ' + file;\n        }\n        if (snapshot) {\n          output += '\\n' + 'Snapshot:\\n' + snapshot;\n        }\n        this.logger[type](title, output);\n      }\n    } else {\n      return this.hookUnique('error-handler-' + handler, errInfo, extra);\n    }\n  });\n\n  this.register('error-handler-script', function(errInfo, extra) {\n    let { ctx, message, type, title, code, filename } = errInfo;\n    let codeFrame = '';\n\n    if (ctx && ctx.file) {\n      filename = filename || ctx.file;\n    }\n    if (ctx && ctx.sfc && ctx.script && ctx.script.content) {\n      code = ctx.sfc.script.content;\n    }\n\n    if (extra) {\n      extra.type = 'script';\n      codeFrame = 'Snapshot:\\n' + this.hookUnique('gen-code-frame', code, extra, message);\n    }\n\n    let output = 'Message:\\n  ' + message;\n    output += '\\n' + 'File:\\n  ' + filename;\n    output += '\\n' + codeFrame;\n    this.logger[type](title, output);\n  });\n\n  this.register('error-handler-template', function(errInfo, extra) {\n    let { ctx, message, type, title } = errInfo;\n\n    let codeFrame = '';\n\n    if (extra) {\n      extra.type = 'template';\n      codeFrame = 'Snapshot:\\n' + this.hookUnique('gen-code-frame', ctx.sfc.template.content, extra, message);\n    }\n    let output = 'Message:\\n  ' + message;\n    output += '\\n' + 'File:\\n  ' + ctx.file;\n    output += '\\n' + codeFrame;\n    this.logger[type](title, output);\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/helper/generateCodeFrame.js",
    "content": "const codeFrameColumns = require('@babel/code-frame').codeFrameColumns;\nconst SourceMap = require('source-map');\n\nfunction indexToLineColumns(code, index) {\n  let line = 1;\n  let column = 1;\n  let i = 0;\n  let l = code.length;\n  while (i < l) {\n    if (i === index) {\n      break;\n    }\n    if (code[i] === '\\n') {\n      line++;\n      column = 1;\n    } else {\n      column++;\n    }\n    i++;\n  }\n  return { line, column };\n}\n\nexports = module.exports = function() {\n  this.register('gen-code-frame', function(code, pos, msg, options) {\n    if (pos.type === 'template') {\n      if (pos.item) {\n        return this.hookUnique('gen-code-frame-html', code, pos.item, pos.attr, pos.expr, msg, options);\n      }\n    }\n\n    options = Object.assign(\n      {},\n      {\n        highlightCode: true,\n        message: msg || ''\n      },\n      options || {}\n    );\n\n    if (!pos.start) {\n      let newpos = {};\n      if (pos.startIndex) {\n        newpos.start = indexToLineColumns(code, pos.startIndex);\n      }\n      if (pos.endIndex) {\n        newpos.end = indexToLineColumns(code, pos.endIndex);\n      }\n      pos = newpos;\n    } else if (pos.sourcemap) {\n      let consumer = SourceMap.SourceMapConsumer(pos.sourcemap);\n      if (pos.start) {\n        pos.start = consumer.originalPositionFor(pos.start);\n      }\n      if (pos.end) {\n        pos.end = consumer.originalPositionFor(pos.end);\n      }\n    }\n\n    return codeFrameColumns(code, pos, options);\n  });\n\n  this.register('gen-code-frame-html', function(code, item, attr, expr, msg, options) {\n    let node = code.substring(item.startIndex, item.endIndex);\n    let i = 0,\n      l = node.length,\n      quotes = [];\n    let word = '';\n    let inQuoteString = '';\n    let startIndex = 0;\n    let endIndex = 0;\n\n    while (i < l) {\n      let c = node[i++];\n      // eslint-disable-next-line\n      if (c === '\"' || c === \"'\") {\n        if (quotes[quotes.length - 1] === c) {\n          quotes.pop();\n        } else {\n          quotes.push(c);\n        }\n        continue;\n      }\n      if (quotes.length === 0) {\n        inQuoteString = '';\n        if (c === ' ') {\n          word = '';\n        } else {\n          word += c;\n        }\n      } else {\n        inQuoteString += c;\n      }\n\n      if (word === attr) {\n        startIndex = i - word.length;\n      }\n      if (inQuoteString === expr) {\n        endIndex = i;\n      }\n    }\n    return this.hookUnique(\n      'gen-code-frame',\n      code,\n      { startIndex: item.startIndex + startIndex, endIndex: item.startIndex + endIndex + 1 },\n      msg,\n      options\n    );\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/helper/sfcCustomBlock.js",
    "content": "exports = module.exports = function() {\n  this.register('sfc-custom-block', function(sfc) {\n    if (!sfc.customBlocks || sfc.customBlocks.length === 0) return sfc;\n\n    sfc.customBlocks = sfc.customBlocks.filter(block => {\n      if (block.attrs && block.attrs.src) {\n        block.src = block.attrs.src;\n      }\n      let hookKey = 'sfc-custom-block-' + block.type;\n      let has = this.hasHook(hookKey);\n      if (has) {\n        ({ sfc, block } = this.hookSeq(hookKey, { sfc, block }));\n      }\n      return !has;\n    });\n\n    return sfc;\n  });\n\n  this.register('sfc-custom-block-config', function({ sfc, block }) {\n    if (!sfc.config) {\n      sfc.config = block;\n      sfc.config.lang = block.attrs.lang || 'json';\n      sfc.config.type = 'config';\n    } else {\n      this.logger.warn('config', 'mutiple config is defined');\n    }\n    return { sfc, block };\n  });\n\n  this.register('sfc-custom-block-wxs', function({ sfc, block }) {\n    if (!sfc.wxs) sfc.wxs = [];\n    block.lang = block.attrs.lang || 'js';\n    block.type = 'wxs';\n    sfc.wxs.push(block);\n    return { sfc, block };\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/helper/supportSrc.js",
    "content": "const path = require('path');\nconst fs = require('fs');\nconst loaderUtils = require('loader-utils');\n\nconst trailingSlash = /[/\\\\]$/;\n\nexports = module.exports = function() {\n  this.register('pre-check-sfc', function(ctx) {\n    let node = ctx.node;\n    let file = ctx.file;\n    let dir = path.parse(file).dir;\n\n    if (node && node.src) {\n      let src = node.src;\n      const request = loaderUtils.urlToRequest(src, src.charAt(0) === '/' ? '' : null);\n      dir = dir.replace(trailingSlash, '');\n      return this.resolvers.normal.resolve({}, dir, request, {}).then(rst => {\n        node.content = fs.readFileSync(rst.path, 'utf-8');\n        node.dirty = true;\n        return {\n          node: node,\n          file: file\n        };\n      });\n    } else {\n      return Promise.resolve({\n        node: node,\n        file: file\n      });\n    }\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/parser/component.js",
    "content": "/**\n * Tencent is pleased to support the open source community by making WePY available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n *\n * Licensed under the MIT License (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n * http://opensource.org/licenses/MIT\n * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n */\nconst fs = require('fs');\nconst path = require('path');\nconst CONST = require('../../util/const');\n\nconst wxmlAst = require('../../ast/wxml');\n\nconst readFile = (file, defaultValue = '') => {\n  if (fs.existsSync(file)) {\n    return fs.readFileSync(file, 'utf-8');\n  }\n  return defaultValue;\n};\n\nexports = module.exports = function() {\n  this.register('wepy-parser-component', function(comp) {\n    let parsedPath = path.parse(comp.path);\n    let file = path.join(parsedPath.dir, parsedPath.name);\n    let sfc = {\n      styles: [],\n      script: {},\n      template: {}\n    };\n    let context = {\n      sfc: sfc,\n      file: file,\n      npm: comp.npm,\n      component: true,\n      type: 'weapp' // This is a weapp original component\n    };\n    let weappCacheKey = file + CONST.WEAPP_EXT;\n\n    if (!this.compiled[weappCacheKey]) {\n      this.compiled[weappCacheKey] = comp;\n    }\n\n    this.fileDep.addDeps(weappCacheKey);\n\n    sfc.styles[0] = {\n      content: readFile(file + '.wxss'),\n      type: 'style',\n      lang: 'wxss'\n    };\n\n    sfc.template = {\n      content: readFile(file + '.wxml'),\n      type: 'template',\n      lang: 'wxml'\n    };\n\n    // JS file should be there.\n    sfc.script = {\n      content: readFile(file + '.js', 'Page({})'),\n      type: 'script',\n      lang: 'babel'\n    };\n\n    sfc.config = {\n      content: readFile(file + '.json', '{}'),\n      type: 'config',\n      lang: 'json'\n    };\n\n    let flow = Promise.resolve(true);\n    let templateContent = sfc.template.content;\n\n    if (templateContent.indexOf('<wxs ') > -1) {\n      // wxs tag inside\n      let templateAst = wxmlAst(sfc.template.content);\n\n      sfc.wxs = [];\n\n      flow = templateAst.then(ast => {\n        let checkSrc = false;\n        wxmlAst.walk(ast, {\n          name: {\n            wxs(item) {\n              if (item.type === 'tag' && item.name === 'wxs') {\n                if (item.attribs.src) {\n                  checkSrc = true;\n                }\n                sfc.wxs.push({\n                  attrs: item.attribs,\n                  src: checkSrc ? item.attribs.src : '',\n                  lang: 'js',\n                  type: 'wxs',\n                  content: wxmlAst.generate(item.children)\n                });\n                // Remove node;\n                item.data = '';\n                item.children = [];\n                item.type = 'text';\n              }\n            }\n          }\n        });\n        if (checkSrc) {\n          // has wxs with src, reset wxml\n          sfc.template.content = wxmlAst.generate(ast);\n        }\n        return checkSrc ? this.hookAsyncSeq('parse-sfc-src', context) : true;\n      });\n    }\n\n    return flow\n      .then(() => {\n        if (sfc.wxs) {\n          return Promise.all(\n            sfc.wxs.map(wxs => {\n              return this.applyCompiler(wxs, context);\n            })\n          );\n        }\n      })\n      .then(() => {\n        return this.applyCompiler(sfc.config, context);\n      })\n      .then(() => {\n        return this.applyCompiler(sfc.template, context);\n      })\n      .then(() => {\n        return this.applyCompiler(sfc.script, context);\n      })\n      .then(parsed => {\n        sfc.script.parsed = parsed;\n        return this.applyCompiler(sfc.styles[0], context);\n      })\n      .then(() => context);\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/parser/config.js",
    "content": "const path = require('path');\nconst loaderUtils = require('loader-utils');\nconst slash = require('slash');\n\nlet appUsingComponents = null;\n\nexports = module.exports = function() {\n  this.register('wepy-parser-config', function(rst, ctx) {\n    // If file is not changed, then use cache.\n    if (ctx.useCache && ctx.sfc.config.parsed) {\n      return Promise.resolve(true);\n    }\n\n    if (!rst) {\n      if (!appUsingComponents) {\n        return Promise.resolve(true);\n      } else {\n        rst.content = JSON.stringify({});\n      }\n    }\n\n    let configString = rst.content.replace(/^\\n*/, '').replace(/\\n*$/, '');\n    configString = (configString || '{}').trim();\n    let config = null;\n    try {\n      let fn = new Function('return ' + configString);\n      config = fn();\n    } catch (e) {\n      // TODO: added error handler code\n      return Promise.reject(`invalid json: ${configString}`);\n    }\n    if (ctx.type !== 'app') {\n      // app.json does not need it\n      config.component = true;\n    }\n    if (!config.usingComponents) {\n      config.usingComponents = {};\n    }\n\n    let userDefineComponents = config.usingComponents || {};\n    let componentKeys = Object.keys(config.usingComponents);\n\n    if (!appUsingComponents && componentKeys.length === 0) {\n      ctx.sfc.config.parsed = {\n        output: config\n      };\n      return Promise.resolve(true);\n    }\n\n    // page Components will inherit app using components\n    if (appUsingComponents && ctx.type === 'page') {\n      appUsingComponents.forEach(comp => {\n        // Existing in page components, then ignore\n        // Resolve path for page components\n        if (!userDefineComponents[comp.name]) {\n          let targetPath = comp.resolved.path;\n          if (comp.prefix === 'module') {\n            targetPath = comp.target;\n          }\n        }\n      });\n    }\n\n    let resolvedUsingComponents = {};\n    let parseComponents = [];\n    let plist = componentKeys.map(name => {\n      const url = userDefineComponents[name];\n\n      let prefix = 'path';\n      // e.g.\n      // plugins://appid/xxxdfdf\n      // module:some-3rd-party-component\n      let matchs = url.match(/([^:]+):(.+)/);\n      let request = url;\n\n      if (matchs) {\n        prefix = matchs[1];\n        request = matchs[2];\n      }\n\n      let target = request;\n      let source = request;\n\n      let hookPrefix = 'wepy-parser-config-component-';\n      let hookName = prefix;\n\n      if (!this.hasHook(hookPrefix + hookName)) {\n        hookName = 'raw';\n      }\n\n      return this.hookUnique(hookPrefix + hookName, name, prefix, source, target, ctx).then(\n        ({ name, prefix, resolved, target, npm }) => {\n          if (hookName === 'raw') {\n            if (request.indexOf(\"weui-miniprogram\") === 0) {\n              resolvedUsingComponents[name] = request;\n            }else{\n              resolvedUsingComponents[name] = url;\n            }\n            parseComponents.push({\n              name,\n              prefix,\n              url\n            });\n          } else {\n            let relativePath = path.relative(path.dirname(ctx.file), target);\n            let parsedPath = path.parse(relativePath);\n            // Windows may got windows path, covert to use posix path\n            resolvedUsingComponents[name] = './' + slash(path.join(parsedPath.dir, parsedPath.name));\n            parseComponents.push({\n              name,\n              prefix,\n              resolved,\n              path: resolved.path,\n              target,\n              npm,\n              request: relativePath,\n              type: parsedPath.ext === this.options.wpyExt ? 'wepy' : 'weapp'\n            });\n          }\n        }\n      );\n    });\n\n    return Promise.all(plist).then(() => {\n      if (ctx.type === 'app') {\n        appUsingComponents = parseComponents;\n      } else {\n        config.usingComponents = Object.assign({}, resolvedUsingComponents);\n      }\n\n      ctx.sfc.config.parsed = {\n        output: config,\n        components: parseComponents\n      };\n      return true;\n    });\n  });\n\n  // raw and plugin do nothing\n  // eslint-disable-next-line\n  this.register('wepy-parser-config-component-raw', function(name, prefix, source, target, ctx) {\n    return Promise.resolve({\n      name,\n      prefix\n    });\n  });\n\n  this.register('wepy-parser-config-component-module', function(name, prefix, source, target, ctx) {\n    let contextDir = path.dirname(ctx.file);\n    return this.resolvers.normal.resolve({}, contextDir, source, {}).then(resolved => {\n      return {\n        name: name,\n        prefix: prefix,\n        resolved: resolved,\n        target: this.getModuleTarget(resolved.path, this.options.src),\n        npm: resolved.meta.descriptionFileRoot !== this.context\n      };\n    });\n  });\n\n  this.register('wepy-parser-config-component-path', function(name, prefix, source, target, ctx) {\n    const moduleRequest = loaderUtils.urlToRequest(source, source.charAt(0) === '/' ? '' : null);\n\n    let contextDir = path.dirname(ctx.file);\n\n    return this.resolvers.normal.resolve({}, contextDir, moduleRequest, {}).then(resolved => {\n      return {\n        name: name,\n        prefix: prefix,\n        resolved: resolved,\n        target: resolved.path,\n        npm: resolved.meta.descriptionFileRoot !== this.context\n      };\n    });\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/parser/file.js",
    "content": "/**\n * Tencent is pleased to support the open source community by making WePY available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n *\n * Licensed under the MIT License (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n * http://opensource.org/licenses/MIT\n * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n */\nconst fs = require('fs');\nconst path = require('path');\n\nconst hashUtil = require('../../util/hash');\n\nexports = module.exports = function() {\n  this.register('wepy-parser-file', function(node, depFileCtx) {\n    let file = depFileCtx.file;\n    let fileContent = fs.readFileSync(file, 'utf-8');\n    let fileHash = hashUtil.hash(fileContent);\n\n    if (this.compiled[file] && fileHash === this.compiled[file].hash) {\n      // 文件 hash 一致，说明文件无修改\n      depFileCtx = this.compiled[file];\n      depFileCtx.useCache = true;\n\n      return Promise.resolve(depFileCtx);\n    } else {\n      this.compiled[file] = depFileCtx;\n      depFileCtx.hash = fileHash;\n      this.fileDep.cleanDeps(file);\n\n      let ext = path.extname(file);\n\n      let componentValue = ext === this.options.wpyExt;\n      if (ext === '.js') {\n        // if it is a weapp component, it must has a .wxml file\n        const dirName = path.dirname(file);\n        const baseName = path.basename(file, '.js');\n        const wxmlFile = path.format({\n          dir: dirName,\n          base: baseName + '.wxml'\n        });\n        componentValue = fs.existsSync(wxmlFile);\n      }\n\n      this.assets.add(depFileCtx.file, {\n        npm: depFileCtx.npm,\n        dep: true,\n        component: componentValue,\n        type: depFileCtx.type,\n        wxs: depFileCtx.wxs\n      });\n\n      if (ext === '.js' || ext === '.ts' || ext === '.wxs') {\n        if (depFileCtx.npm && depFileCtx.type !== 'weapp') {\n          // weapp component npm may have import in it.\n          return this.applyCompiler({ type: 'script', lang: 'js', content: fileContent }, depFileCtx);\n        } else {\n          return this.applyCompiler({ type: 'script', lang: node.lang || 'babel', content: fileContent }, depFileCtx);\n        }\n      } else {\n        if (ext === this.options.wpyExt) {\n          // TODO: why they import a wpy file.\n          this.hookUnique(\n            'error-handler',\n            'script',\n            {\n              code: node.compiled.code,\n              ctx: depFileCtx,\n              type: 'error',\n              message: 'Can not import a wepy component, please use \"usingComponents\" to declear a component',\n              title: 'dependence'\n            },\n            node.compiled.map\n              ? {\n                  sourcemap: node.compiled.map,\n                  start: depFileCtx.dep.loc.start,\n                  end: depFileCtx.dep.loc.end\n                }\n              : depFileCtx.dep.loc\n          );\n          throw new Error('EXIT');\n        } else {\n          this.hookUnique(\n            'error-handler',\n            'script',\n            {\n              code: node.compiled ? node.compiled.code : '',\n              ctx: depFileCtx,\n              type: 'error',\n              message: `Unrecognized import extension: ${depFileCtx.file}`,\n              title: 'dependence'\n            },\n            node.compiled && node.compiled.map\n              ? {\n                  sourcemap: node.compiled.map,\n                  start: depFileCtx.dep.loc.start,\n                  end: depFileCtx.dep.loc.end\n                }\n              : depFileCtx.dep.loc\n          );\n          throw new Error('EXIT');\n        }\n      }\n    }\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/parser/script.js",
    "content": "/**\n * Tencent is pleased to support the open source community by making WePY available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n *\n * Licensed under the MIT License (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n * http://opensource.org/licenses/MIT\n * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n */\nconst fs = require('fs');\nconst path = require('path');\n\nconst hashUtil = require('../../util/hash');\nconst Walker = require('../../ast/walker');\nconst toAst = require('../../ast/toAST');\nconst ReplaceSource = require('webpack-sources').ReplaceSource;\nconst RawSource = require('webpack-sources').RawSource;\n\n// 记录 npm 文件是否已经遍历过\nconst npmTraverseFileMap = {};\n\nexports = module.exports = function() {\n  this.register('wepy-parser-dep', function(node, ctx, dep) {\n    const file = dep.module;\n    if (file.endsWith('.json')) {\n      return Promise.resolve(fs.readFileSync(path.resolve(path.dirname(ctx.file), file), 'utf8'));\n    }\n    return this.resolvers.normal.resolve({ issuer: ctx.file }, path.dirname(ctx.file), dep.module, {}).then(rst => {\n      let npm = rst.meta.descriptionFileRoot !== this.context;\n\n      let assets = this.assets;\n      let file = rst.path;\n\n      if (!file) {\n        // TODO: resovle fail ?\n        return rst.path;\n      }\n\n      let data = assets.data(file);\n      if (data !== undefined && this.compiled[file] && this.compiled[file].hash) {\n        let fileContent = fs.readFileSync(file, 'utf-8');\n        let fileHash = hashUtil.hash(fileContent);\n        if (fileHash === this.compiled[file].hash) {\n          // File is not changed, do not compile again\n          if (\n            data.parser &&\n            !data.depModules && // Ignore if deps modules are resolved, otherwise there will be a dead loop\n            data.parser.deps &&\n            data.parser.deps.length &&\n            !npmTraverseFileMap[file]\n          ) {\n            // If it has dependences, walk throguh all dependences\n            npmTraverseFileMap[file] = npm;\n            let depTasks = data.parser.deps.map(dep =>\n              this.hookUnique('wepy-parser-dep', data, this.compiled[file], dep)\n            );\n            return Promise.all(depTasks).then(rst => {\n              data.depModules = rst;\n              return data;\n            });\n          } else {\n            return data;\n          }\n        } else {\n          npmTraverseFileMap[file] = false;\n        }\n      }\n\n      return this.hookUnique('wepy-parser-file', node, {\n        file: file,\n        npm: npm,\n        component: ctx.component,\n        type: ctx.type,\n        dep,\n        wxs: !!ctx.wxs\n      });\n    });\n  });\n\n  this.register('wepy-parser-script', function(node, ctx) {\n    let assets = this.assets;\n    if (ctx.npm && !ctx.component && !ctx.wxs) {\n      if (this.vendors.pending(ctx.file)) {\n        // file compile is pending\n        let moduleId = this.vendors.get(ctx.file);\n        return Promise.resolve(moduleId);\n      }\n      ctx.vendorId = this.vendors.add(ctx.file, 'npm');\n    }\n\n    if (ctx.useCache && node.parsed) {\n      // File is not changed\n      let walker = node.parsed.parser;\n\n      let depTasks = walker.deps.map(dep => this.hookUnique('wepy-parser-dep', node, ctx, dep));\n\n      return Promise.all(depTasks).then(() => {\n        return node.parsed;\n      });\n    } else {\n      let source = new ReplaceSource(new RawSource(node.compiled.code));\n      let astData = toAst(node.compiled.code);\n\n      let walker = new Walker(this, astData, node.lang);\n      walker.run();\n\n      let depTasks = walker.deps.map(dep => this.hookUnique('wepy-parser-dep', node, ctx, dep));\n      return Promise.all(depTasks).then(rst => {\n        let obj = {\n          file: ctx.file,\n          parser: walker,\n          code: node.compiled.code,\n          encoding: node.compiled.encoding || 'utf-8',\n          outputFileName: node.compiled.outputFileName,\n          source: source,\n          depModules: rst,\n          npm: !!ctx.npm,\n          type: ctx.type,\n          component: ctx.component\n        };\n\n        this.fileDep.addDeps(ctx.file, obj.depModules.map(d => d.file));\n\n        let componentValue = ctx.component;\n        const t = this.assets.type(ctx.file);\n        if (t !== undefined) {\n          // if it has type in this.assets\n          componentValue = t.component;\n        }\n        let types = {\n          component: componentValue,\n          npm: ctx.npm,\n          dep: ctx.dep,\n          type: ctx.type,\n          wxs: ctx.wxs\n        };\n\n        this.assets.update(ctx.file, obj, types);\n        obj.id = assets.get(ctx.file);\n        if (ctx.npm && !(ctx.component && ctx.type === 'weapp') && !ctx.wxs) {\n          this.vendors.update(ctx.file, obj, types);\n          obj.vendorId = this.vendors.get(ctx.file);\n        }\n        return obj;\n      });\n    }\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/parser/style.js",
    "content": "exports = module.exports = function() {\n  this.register('wepy-parser-style', function(node, ctx) {\n    // If this file have dependences, then ignore cache for it.\n    if (ctx.useCache && node.parsed && (node.parsed.dep || []).length === 0) {\n      return Promise.resolve(true);\n    }\n    node.parsed = node.compiled;\n\n    return Promise.resolve(true);\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/parser/template.js",
    "content": "const xmllint = require('../../util/xmllint');\n\nexports = module.exports = function() {\n  this.register('wepy-parser-template', function(node, ctx) {\n    if (ctx.useCache && ctx.sfc.template.parsed) {\n      return Promise.resolve(true);\n    }\n\n    // If it's weapp, do not compile it.\n    if (ctx.type === 'weapp') {\n      ctx.sfc.template.parsed = {\n        code: node.content,\n        rel: {}\n      };\n      return Promise.resolve(true);\n    }\n\n    let code = node.content;\n    let msg = xmllint.verify(code);\n    msg.forEach(item => {\n      let type = item.type === 'warning' ? 'warn' : 'error';\n      this.hookUnique(\n        'error-handler',\n        'template',\n        {\n          ctx: ctx,\n          message: item.message,\n          type: type,\n          title: 'verify'\n        },\n        {\n          start: { line: item.line, column: item.col }\n        }\n      );\n      //errorHandler[type](item.message, ctx.file, code, { start: {line: item.line, column: item.col}});\n    });\n\n    let components = {};\n    let sfcConfig = ctx.sfc.config;\n\n    let usingComponents = sfcConfig && sfcConfig.parsed.output ? sfcConfig.parsed.output.usingComponents : {};\n\n    for (let k in usingComponents) {\n      components[k] = {\n        path: usingComponents[k]\n      };\n    }\n\n    return this.hookUnique('template-parse', node.content, components, ctx).then(rst => {\n      ctx.sfc.template.parsed = {\n        code: rst.code,\n        rel: rst.rel\n      };\n      return Promise.resolve(true);\n    });\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/parser/wpy.js",
    "content": "/**\n * Tencent is pleased to support the open source community by making WePY available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n *\n * Licensed under the MIT License (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n * http://opensource.org/licenses/MIT\n * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n */\nconst sfcCompiler = require('vue-template-compiler');\nconst fs = require('fs');\nconst path = require('path');\nconst loaderUtils = require('loader-utils');\n\nconst hashUtil = require('../../util/hash');\n\nexports = module.exports = function() {\n  this.register('wepy-parser-wpy', function(comp) {\n    let sfc, flow;\n    let file = comp.path;\n    let type = comp.type;\n\n    let context = {\n      file,\n      type,\n      npm: type === 'module',\n      component: true\n    };\n\n    let fileContent = fs.readFileSync(file, 'utf-8');\n    let fileHash = hashUtil.hash(fileContent);\n\n    if (this.compiled[file] && fileHash === this.compiled[file].hash) {\n      // 文件 hash 一致，说明文件无修改\n      context = this.compiled[file];\n      context.useCache = true;\n      sfc = context.sfc;\n\n      if (context.done) {\n        flow = Promise.resolve(true); // For file watch, still need to go throught all the dependences\n      } else {\n        flow = context.promise;\n      }\n    } else {\n      this.compiled[file] = context;\n      context.useCache = false;\n      context.hash = fileHash;\n      this.fileDep.cleanDeps(file);\n\n      context.sfc = sfcCompiler.parseComponent(fileContent, { pad: 'space' });\n\n      sfc = context.sfc;\n      // deal with the custom block, like config, wxs. etc.\n      sfc = this.hookSeq('sfc-custom-block', sfc);\n\n      if (!sfc.script) {\n        sfc.script = {\n          attrs: {},\n          type: 'script',\n          empty: true,\n          lang: 'js',\n          content: 'Component({})'\n        };\n      }\n\n      if (!sfc.config) {\n        sfc.config = { type: 'config', empty: true, content: '{}', lang: 'json' };\n      }\n\n      flow = this.hookAsyncSeq('parse-sfc-src', context);\n    }\n\n    this.fileDep.addDeps(file);\n\n    context.promise = flow\n      .then(() => {\n        return this.applyCompiler(context.sfc.config, context);\n      })\n      .then(() => {\n        if (sfc.wxs) {\n          return Promise.all(\n            sfc.wxs.map(wxs => {\n              return this.applyCompiler(wxs, context);\n            })\n          );\n        }\n      })\n      .then(() => {\n        if (sfc.template && type !== 'app') {\n          sfc.template.lang = sfc.template.lang || 'wxml';\n          return this.applyCompiler(context.sfc.template, context);\n        }\n      })\n      .then(() => {\n        if (sfc.script) {\n          sfc.script.lang = sfc.script.lang || 'babel';\n          return this.applyCompiler(context.sfc.script, context);\n        }\n      })\n      .then(parsed => {\n        sfc.script && parsed && (sfc.script.parsed = parsed);\n        if (sfc.styles) {\n          return Promise.all(\n            sfc.styles.map(style => {\n              style.lang = style.lang || 'css';\n              return this.applyCompiler(style, context);\n            })\n          );\n        }\n      })\n      .then(() => {\n        context.done = true;\n        return context;\n      });\n\n    return context.promise;\n  });\n\n  const trailingSlash = /[/\\\\]$/;\n\n  this.register('parse-sfc-src', function(context) {\n    let sfc = context.sfc;\n\n    let tasks = [];\n    let dir = path.parse(context.file).dir;\n    dir = dir.replace(trailingSlash, '');\n\n    for (let type in sfc) {\n      // wxs is an array.\n      let nodes = [].concat(sfc[type]);\n      nodes.forEach(node => {\n        const src = node ? node.src : '';\n        if (src) {\n          const request = loaderUtils.urlToRequest(src, src.charAt(0) === '/' ? '' : null);\n          tasks.push(\n            this.resolvers.normal.resolve({}, dir, request, {}).then(rst => {\n              node.content = fs.readFileSync(rst.path, 'utf-8');\n              this.fileDep.addDeps(context.file, [rst.path]);\n              node.dirty = true;\n            })\n          );\n        }\n      });\n    }\n    return Promise.all(tasks);\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/parser/wxs.js",
    "content": "const path = require('path');\nconst hashUtil = require('../../util/hash');\n\nexports = module.exports = function() {\n  this.register('wepy-parser-wxs', function(node, ctx) {\n    if (ctx.useCache && !node.src && ctx.sfc.template.parsed) {\n      return Promise.resolve(true);\n    }\n    let moduleId = node.attrs.module;\n    let code = node.compiled.code.trim();\n    let output = `<wxs module=\"${moduleId}\"${node.src ? ' src=\"' + node.src + '\"' : ''}>${\n      !node.src ? '\\n' + code + '\\n' : ''\n    }</wxs>`;\n    node.parsed = {\n      output\n    };\n    const fileHash = node.src ? hashUtil.hash(code) : ctx.hash;\n    // If have src attribute, then use src.wxs as ctx key\n    // If do not have src, then create a fake xxx.wpy_wxs as ctx key.\n    // Can not use wpy ctx, because it's generated in wpy parse.\n    const cacheKey = node.src ? path.resolve(path.dirname(ctx.file), node.src) : ctx.file + '_wxs';\n    const isHashEqual = !!this.compiled[cacheKey] && fileHash === this.compiled[cacheKey].hash;\n    let wxsCtx = null;\n\n    if (node.src && isHashEqual) {\n      // If node has src, then use src file cache\n      wxsCtx = this.compiled[cacheKey];\n      wxsCtx.useCache = true;\n      return Promise.resolve(wxsCtx);\n    } else {\n      wxsCtx = Object.assign({}, ctx, {\n        // If node have a src, then ctx.file has to be node.src related, otherwise, there will be an error while require a wxs file in the wxs file\n        file: node.src ? cacheKey : ctx.file,\n        wxs: true,\n        hash: fileHash\n      });\n      this.compiled[cacheKey] = wxsCtx;\n\n      // If sfc file hash is equal\n      if (isHashEqual) {\n        return Promise.resolve(wxsCtx);\n      }\n      if (node.src) {\n        this.assets.add(cacheKey, {\n          npm: wxsCtx.npm,\n          wxs: true,\n          dep: true,\n          component: wxsCtx.component,\n          type: wxsCtx.type\n        });\n      }\n    }\n\n    node = {\n      type: 'script',\n      lang: node.lang,\n      content: code,\n      src: node.src\n    };\n    return this.applyCompiler(node, wxsCtx);\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/scriptDepFix.js",
    "content": "const path = require('path');\nconst slash = require('slash');\n\nexports = module.exports = function() {\n  /*\n   * S1: __wepy_require(n);\n   * S2: require('./lib/sth');\n   * S3: require('/vendor.js')(n);\n   * S4: import 'xxxx' from 'xxx';j\n   */\n  this.register('script-dep-fix', function scriptDepFix(parsed, isNPM) {\n    if (!parsed.fixedDeps) {\n      parsed.fixedDeps = [];\n    }\n    if (!parsed.fixedReplacement && parsed.parser.replacements) {\n      parsed.parser.replacements.forEach(item => {\n        parsed.source.replace(item.expr.start, item.expr.end - 1, item.value);\n      });\n      parsed.fixedReplacement = true;\n    }\n    parsed.parser.deps.forEach((dep, i) => {\n      if (!parsed.fixedDeps[i]) {\n        let depMod = parsed.depModules[i];\n        if (typeof depMod === 'string') {\n          parsed.source.replace(dep.expr.start, dep.expr.end - 1, depMod);\n          parsed.fixedDeps[i] = true;\n          return;\n        }\n        if (typeof depMod === 'number') {\n          depMod = this.vendors.data(depMod);\n        }\n        // TODO: optimize\n        // compiled info is not equal asserts, vendorId is missing sometime\n        // always use assets data instead of compiled info.\n        depMod = this.assets.data(depMod.file) || depMod;\n\n        let modFilePath = depMod.file;\n        let modFilePathObj = path.parse(modFilePath);\n        if (depMod.outputFileName && modFilePathObj.base !== depMod.outputFileName) {\n          modFilePath = path.join(modFilePathObj.dir, depMod.outputFileName);\n        }\n        if (path.extname(modFilePath) === '.ts') {\n          modFilePath = modFilePath.slice(0, -2) + 'js';\n        }\n        let replaceMent = '';\n        if (isNPM) {\n          if (depMod.vendorId === undefined) {\n            depMod = this.vendors.data(depMod.file);\n          }\n          replaceMent = `__wepy_require(${depMod.vendorId})`;\n        } else {\n          if (depMod === false) {\n            replaceMent = '{}';\n          } else if (!depMod.npm || (depMod.component && depMod.type === 'weapp')) {\n            //depMod dep is not a npm package, and it's not a component\n            let relativePath = path.relative(path.dirname(parsed.file), modFilePath).replace(/\\\\/g, '/');\n            if (dep.statement && dep.statement.type === 'ImportDeclaration') {\n              // import 'xxxxx' from 'xxxxx';\n              replaceMent = `'${relativePath}'`;\n            } else {\n              replaceMent = `require('./${relativePath}')`;\n            }\n          } else if (!depMod.npm && depMod.component) {\n            let relativePath = path.relative(path.dirname(parsed.file), modFilePath);\n            let reg = new RegExp('\\\\' + this.options.wpyExt + '$', 'i');\n            relativePath = slash(relativePath.replace(reg, '.js'));\n            replaceMent = `require('./${relativePath}')`;\n          } else {\n            if (typeof depMod.vendorId === 'number') {\n              let relativePath;\n              let npmfile = path.join(this.context, this.options.src, 'vendor.js');\n              if (parsed.npm) {\n                // This is a npm package\n                relativePath = path.relative(\n                  path.dirname(this.getModuleTarget(parsed.file, this.options.src)),\n                  npmfile\n                );\n              } else {\n                relativePath = path.relative(path.dirname(parsed.file), npmfile);\n              }\n              relativePath = slash(relativePath);\n              replaceMent = `require('./${relativePath}')(${depMod.vendorId})`;\n            } else {\n              replaceMent = `require('./${dep.module}')`;\n            }\n          }\n        }\n        parsed.source.replace(dep.expr.start, dep.expr.end - 1, replaceMent);\n        parsed.fixedDeps[i] = true;\n      }\n    });\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/scriptInjection.js",
    "content": "const genRel = rel => {\n  if (typeof rel === 'string') return rel;\n\n  let handlerStr = '{';\n  for (let h in rel.handlers) {\n    let handler = rel.handlers[h];\n    handlerStr += `'${h}': {`;\n    if (typeof handler === 'object') {\n      let events = Object.keys(handler);\n      events.forEach((e, p) => {\n        handlerStr += `${JSON.stringify(e)}: ${handler[e]}`;\n        if (p !== events.length - 1) {\n          handlerStr += ', ';\n        }\n      });\n    }\n    handlerStr += '},';\n  }\n  if (handlerStr.length > 2) {\n    handlerStr = handlerStr.substring(0, handlerStr.length - 1);\n  }\n  handlerStr += '}';\n\n  let modelStr = '';\n  for (let i in rel.models) {\n    modelStr += `'${i}': {\n      type: ${JSON.stringify(rel.models[i].type)},\n      expr: ${JSON.stringify(rel.models[i].expr)},\n      handler: ${rel.models[i].handler}\n    },`;\n  }\n  modelStr = '{' + modelStr.substring(0, modelStr.length - 1) + '}';\n\n  let copy = Object.assign({}, rel);\n  delete copy.handlers;\n  delete copy.models;\n\n  return `{info: ${JSON.stringify(copy || {})}, handlers: ${handlerStr}, models: ${modelStr}, refs: ${JSON.stringify(\n    rel.refs\n  )} }`;\n};\n\nexports = module.exports = function() {\n  this.register('script-injection', function scriptInjection(parsed, ref) {\n    let relStr = genRel(ref);\n    const { source } = parsed;\n    let entry = parsed.parser.entry;\n    if (!entry) {\n      this.hookUnique('error-handler', {\n        type: 'warn',\n        message: `Missing wepy entry. A .wpy file should have \"wepy.app\", \"wepy.page\" or \"wepy.component\"`,\n        ctx: {\n          file: parsed.file\n        }\n      });\n      return;\n    }\n    let args = entry.arguments;\n    let pos = 0;\n    if (args === 0) {\n      pos = entry.callee.end + 1;\n    } else {\n      pos = args[args.length - 1].end;\n      relStr = ', ' + relStr;\n    }\n\n    // avoid to import duplicated\n    // eslint-disable-next-line\n    if (source.relIndex != null) {\n      const idx = source.replacements.findIndex(arr => {\n        return arr[arr.length - 1] === source.relIndex;\n      });\n      if (idx !== -1) {\n        source.replacements.splice(idx, 1);\n      }\n    }\n    source.insert(pos, relStr);\n    source.relIndex = source.replacements.length - 1;\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/template/attrs/bindClass.js",
    "content": "const parseClass = require('../../../ast/parseClass');\n\nexports = module.exports = function() {\n  this.register('template-parse-ast-attr-:class', function parseBindClass({ item, expr, ctx }) {\n    let exprArray = [];\n    try {\n      exprArray = parseClass(expr);\n    } catch (e) {\n      this.hookUnique(\n        'error-handler',\n        'template',\n        {\n          code: expr,\n          ctx,\n          type: 'error',\n          message: 'Can not parse \":class\" expression',\n          title: ':class'\n        },\n        { item }\n      );\n      throw new Error('EXIT');\n    }\n    let bindClass = [];\n    exprArray.forEach(item => {\n      if (typeof item === 'string') {\n        bindClass.push(`${item}`);\n      } else {\n        Object.keys(item).forEach(name => {\n          // eslint-disable-next-line\n          let exp = item[name].replace(/\\'/gi, '\\\\\\'').replace(/\\\"/gi, '\\\\\"');\n          // eslint-disable-next-line\n          name = name.replace(/\\'/gi, '\\\\\\'').replace(/\\\"/gi, '\\\\\"');\n          bindClass.push(`${exp} ? '${name}' : ''`);\n        });\n      }\n    });\n    item.bindClass = bindClass;\n\n    return { attrs: {} };\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/template/attrs/bindStyle.js",
    "content": "const exprParser = require('../../../util/exprParser');\n\nexports = module.exports = function() {\n  this.register('template-parse-ast-attr-:style', function parseBindStyle({ item, expr }) {\n    let exprObj = exprParser.str2obj(expr);\n    item.bindStyle = Object.keys(exprObj).map(name => {\n      // eslint-disable-next-line\n      let exp = exprObj[name].replace(/\\'/gi, '\\\\\\'').replace(/\\\"/gi, '\\\\\"');\n\n      // add brackets to fix priority of \"+\" operator.\n      if (/^\\(.*\\)$/.test(exp) === false) {\n        exp = `(${exp})`;\n      }\n      // eslint-disable-next-line\n      name = name.replace(/\\'/gi, '\\\\\\'').replace(/\\\"/gi, '\\\\\"');\n      name = exprParser.hyphenate(name);\n      return `'${name}:' + ${exp} + ';'`;\n    });\n    // return {} means remove :class\n    return { attrs: {} };\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/template/attrs/index.js",
    "content": "exports = module.exports = function parseAttrs() {\n  ['./bindClass', './bindStyle', './src', './ref'].map(v => require(v).call(this));\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/template/attrs/ref.js",
    "content": "exports = module.exports = function() {\n  let totalRefCache = {};\n\n  function getParseRefFunc(hasBindAttrRef = false) {\n    return function({ item, ctx, expr, rel }) {\n      let attrs = item.attribs;\n      let parsedRef = {};\n      let assetsId = this.assets.get(ctx.file);\n      let refCache;\n      let elemId;\n\n      let components = rel.components;\n      let hasAttrId = attrs.hasOwnProperty('id');\n      let hasBindAttrId = attrs.hasOwnProperty(':id');\n\n      if (!totalRefCache[assetsId]) {\n        totalRefCache[assetsId] = {\n          increaseId: 0\n        };\n      }\n      refCache = totalRefCache[assetsId];\n\n      if (!rel.refs) {\n        rel.refs = [];\n      }\n\n      parsedRef.rel = rel || {};\n      parsedRef.attrs = parsedRef.attrs || {};\n\n      if (!components[item.name]) {\n        if (hasAttrId || hasBindAttrId) {\n          elemId = hasAttrId ? attrs['id'] : attrs[':id'];\n        } else {\n          elemId = `ref-${assetsId}-${refCache.increaseId}`;\n          parsedRef.attrs['id'] = elemId;\n          refCache.increaseId++;\n        }\n        rel.refs.push({\n          id: {\n            name: `${elemId}`,\n            bind: hasBindAttrId\n          },\n          ref: {\n            name: `${expr}`,\n            bind: hasBindAttrRef\n          }\n        });\n      } else {\n        parsedRef.attrs['data-ref'] = hasBindAttrRef ? `{{ ${expr} }}` : `${expr}`;\n      }\n      return parsedRef;\n    };\n  }\n\n  this.register('template-parse-ast-attr-ref', getParseRefFunc().bind(this));\n  this.register('template-parse-ast-attr-:ref', getParseRefFunc(true).bind(this));\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/template/attrs/src.js",
    "content": "const fs = require('fs-extra');\nconst path = require('path');\nconst ReplaceSource = require('webpack-sources').ReplaceSource;\nconst RawSource = require('webpack-sources').RawSource;\nconst slash = require('slash');\n\nexports = module.exports = function() {\n  this.register('url-to-module', function urlToModule(url) {\n    const parsed = {};\n    const firstChar = url.charAt(0);\n    // if first char eqs `.` `~` or `@`, It will be treated as module processing\n    if ((firstChar === '.' || firstChar === '~' || firstChar === '@') && !(url.includes('{{') || url.includes('}}'))) {\n      if (firstChar === '~') {\n        const secondChar = url.charAt(1);\n        url = url.slice(secondChar === '/' ? 2 : 1);\n      }\n      parsed.isModule = true;\n    } else {\n      parsed.isModule = false;\n    }\n    parsed.url = url;\n    return parsed;\n  });\n\n  this.register('template-parse-ast-attr-src', function parseAssetUrl({ expr, ctx }) {\n    let parsed = this.hookUnique('url-to-module', expr);\n\n    if (parsed.isModule) {\n      const context = path.dirname(ctx.file);\n      const assets = this.assets;\n      const type = 'url';\n      const encoding = 'base64';\n\n      parsed.file = this.resolvers.normal.resolveSync({}, context, parsed.url, {});\n      parsed.url = path.relative(path.dirname(ctx.file), parsed.file);\n\n      if (path.sep === '\\\\') {\n        // It's Win, change path to posix path\n        parsed.url = slash(parsed.url);\n      }\n\n      const code = fs.readFileSync(parsed.file, encoding);\n      const source = new ReplaceSource(new RawSource(code));\n\n      // add assets dependencies\n      let obj = {\n        file: ctx.file,\n        parser: {},\n        code: code,\n        encoding,\n        source: source,\n        depModules: null,\n        type: type\n      };\n      assets.update(parsed.file, obj, { url: true });\n    }\n    parsed.attr = { attrs: { src: parsed.url } };\n    return parsed.attr;\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/template/directives/bind.js",
    "content": "const bindRE = /^:|^v-bind:/;\n\nexports = module.exports = function() {\n  // eslint-disable-next-line no-unused-vars\n  this.register('template-parse-ast-attr-v-bind', function parseAstBind({ item, name, expr, modifiers, scope, ctx }) {\n    let prop = name.replace(bindRE, '');\n    let value = expr;\n    expr = `{{ ${expr} }}`;\n    return {\n      bind: {\n        name,\n        prop,\n        value,\n        expr\n      },\n      attrs: {\n        [prop]: expr\n      }\n    };\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/template/directives/condition.js",
    "content": "const ADDITIONS_DIRECTIVES_HANDLES = {\n  /* eslint-disable no-unused-vars */\n  'v-show': ({ item, name, expr }) => ({ attrs: { hidden: `{{ !(${expr}) }}` } }),\n  'v-if': ({ item, name, expr }) => ({ attrs: { 'wx:if': `{{ ${expr} }}` } }),\n  'v-else-if': ({ item, name, expr }) => ({ attrs: { 'wx:elif': `{{ ${expr} }}` } }),\n  'v-else': ({ item, name, expr }) => ({ attrs: { 'wx:else': true } })\n  /* eslint-enable no-unused-vars */\n};\n\nexports = module.exports = function() {\n  Object.keys(ADDITIONS_DIRECTIVES_HANDLES).forEach(directives => {\n    this.register('template-parse-ast-attr-' + directives, ADDITIONS_DIRECTIVES_HANDLES[directives]);\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/template/directives/for.js",
    "content": "const forAliasRE = /([^]*?)\\s+(?:in|of)\\s+([^]*)/;\nconst forIteratorRE = /,([^,}\\]]*)(?:,([^,}\\]]*))?$/;\nconst stripParensRE = /^\\(|\\)$/g;\nconst variableRE = /^\\s*[a-zA-Z$_][a-zA-Z\\d_]*\\s*$/;\nconst Check = require('../util/check');\n\nexports = module.exports = function() {\n  this.register('template-parse-ast-pre-attr-v-for', function preParseDirectivesFor({\n    item,\n    name,\n    expr,\n    modifiers,\n    scope,\n    ctx\n  }) {\n    let res = {};\n    let currentScope = {};\n    let inMatch = expr.match(forAliasRE);\n    let variableMatch = expr.match(variableRE);\n    if (variableMatch) {\n      // e.g: v-for=\"items\"\n      res.alias = 'item';\n      res.for = variableMatch[0].trim();\n      currentScope.for = res.for;\n      currentScope.declared = [];\n    }\n\n    if (inMatch) {\n      currentScope.declared = currentScope.declared || [];\n      res.for = inMatch[2].trim();\n      currentScope.for = res.for;\n      let alias = inMatch[1].trim().replace(stripParensRE, '');\n      let iteratorMatch = alias.match(forIteratorRE);\n      if (iteratorMatch) {\n        res.alias = alias.replace(forIteratorRE, '').trim();\n        currentScope.declared.push(res.alias);\n        currentScope.alias = res.alias;\n        res.iterator1 = iteratorMatch[1].trim();\n        currentScope.iterator1 = res.iterator1;\n        currentScope.declared.push(res.iterator1);\n        if (iteratorMatch[2]) {\n          res.iterator2 = iteratorMatch[2].trim();\n          currentScope.iterator2 = res.iterator2;\n          currentScope.declared.push(res.iterator2);\n        }\n      } else {\n        res.alias = alias;\n        currentScope.alias = alias;\n        currentScope.declared.push(alias);\n      }\n    }\n    if (scope) {\n      currentScope.parent = scope;\n    }\n\n    let err = Check.checkExpression(res.for, `v-for=\"${expr}\"`);\n    if (err) {\n      this.hookUnique(\n        'error-handler',\n        'template',\n        {\n          ctx: ctx,\n          message: err,\n          type: 'error',\n          title: 'v-for'\n        },\n        {\n          item: item,\n          attr: name,\n          expr: expr\n        }\n      );\n    }\n\n    item['v-for'] = {\n      'wx:for': `{{ ${res.for} }}`,\n      'wx:for-index': `${res.iterator1 || 'index'}`,\n      'wx:for-item': `${res.alias || 'item'}`,\n      'wx:key': `${res.iterator2 || res.iterator1 || 'index'}`\n    };\n\n    return {\n      item,\n      name,\n      expr,\n      modifiers,\n      scope: currentScope,\n      ctx\n    };\n  });\n\n  this.register('template-parse-ast-attr-v-for', function parseDirectivesFor({\n    /* eslint-disable no-unused-vars */\n    item,\n    name,\n    expr,\n    modifiers,\n    scope,\n    ctx\n    /* eslint-enable no-unused-vars */\n  }) {\n    let attrs = item['v-for'];\n    delete item['v-for'];\n    return {\n      attrs: attrs\n    };\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/template/directives/index.js",
    "content": "exports = module.exports = function parseDirectives() {\n  ['./condition', './bind', './for', './model', './other', './v-on'].map(v => require(v).call(this));\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/template/directives/model.js",
    "content": "const CONST = require('../../../util/const');\nconst vueWithTransform = require('vue-template-es2015-compiler');\n\nconst MODEL_MAP = {\n  input: {\n    type: 'input',\n    value: 'value'\n  },\n  textarea: {\n    type: 'input',\n    value: 'value'\n  },\n  picker: {\n    type: 'change',\n    value: 'value'\n  },\n  switch: {\n    type: 'change',\n    value: 'checked'\n  },\n  'checkbox-group': {\n    // TODO: Can not set data for checkbox-group\n    type: 'change',\n    value: null\n  },\n  'radio-group': {\n    type: 'change',\n    value: null\n  }\n};\n\n/**\n * Parse a v-model expression into a base path and a final key segment.\n * Handles both dot-path and possible square brackets.\n *\n * Possible cases:\n *\n * - test\n * - test[key]\n * - test[test1[key]]\n * - test[\"a\"][key]\n * - xxx.test[a[a].test1[key]]\n * - test.xxx.a[\"asa\"][test1[key]]\n *\n */\nfunction parseModel(str) {\n  str = str.trim();\n  let len = str.length;\n\n  // e.g.\n  // test[0].a\n  // test.a.b\n  if (str.indexOf('[') < 0 || str.lastIndexOf(']') < len - 1) {\n    let dot = str.lastIndexOf('.');\n    if (dot > -1) {\n      return {\n        expr: str.slice(0, dot),\n        key: `${str.slice(dot + 1)}`\n      };\n    } else {\n      return {\n        expr: str,\n        key: null\n      };\n    }\n  }\n\n  /*\n   * e.g.\n   * test[a[b]]\n   */\n\n  let index = 0;\n  let exprStart = 0;\n  let exprEnd = 0;\n\n  let isQuoteStart = function(chr) {\n    return chr === 0x22 || chr === 0x27;\n  };\n\n  let parseString = function(chr) {\n    while (index < len && str.charCodeAt(++index) !== chr) {}\n  };\n\n  let parseBracket = function(chr) {\n    let inBracket = 1;\n    exprStart = index;\n    while (index < len) {\n      chr = str.charCodeAt(++index);\n      if (isQuoteStart(chr)) {\n        parseString(chr);\n        continue;\n      }\n      if (chr === 0x5b) inBracket++;\n      if (chr === 0x5d) inBracket--;\n\n      if (inBracket === 0) {\n        exprEnd = index;\n        break;\n      }\n    }\n  };\n\n  while (index < len) {\n    let chr = str.charCodeAt(++index);\n    if (isQuoteStart(chr)) {\n      parseString(chr);\n    } else if (chr === 0x5b) {\n      parseBracket(chr);\n    }\n  }\n\n  return {\n    expr: str.slice(0, exprStart),\n    key: str.slice(exprStart + 1, exprEnd)\n  };\n}\n\nfunction generateModelFunction(expr) {\n  let func = '';\n  let parsed = parseModel(expr);\n  if (parsed.key === null) {\n    // it has to be  \" something = $v \"\n    // cannot be  ['something'] = $v\n    func = `function set ($v) {\n      with (this) {\n        ${expr} = $v;\n      }\n    }`;\n  } else {\n    func = `function set ($v) {\n      with (this) {\n        $set(${parsed.expr}, \"${parsed.key}\", $v);\n      }\n    }`;\n  }\n  func = vueWithTransform(func);\n  func = func.replace('var _h=_vm.$createElement;var _c=_vm._self._c||_h;', ''); // removed unused vue code;\n  return func;\n}\n\nfunction generateModelFunctionInScope(scope, iterators, expr) {\n  let l = iterators.length;\n  let i = 0;\n  let func = [];\n\n  let fetch = scope;\n  let lastFor = scope.for;\n\n  let parsed = parseModel(expr);\n\n  while (fetch) {\n    if (i === 0) {\n      if (parsed.key === null) {\n        func.push(`function fn${l - i}(${fetch.alias}) {\n          ${expr} = $v;\n        }`);\n      } else {\n        func.push(`function fn${l - i}(${fetch.alias}) {\n          $set(${parsed.expr}, \"${parsed.key}\", $v);\n        }`);\n      }\n    } else {\n      func.push(`function fn${l - i}(${fetch.alias}) {\n        return fn${l - i + 1}((${lastFor})[$p[${l - i}]]);\n      }`);\n    }\n    i++;\n    lastFor = fetch.for;\n    fetch = fetch.parent;\n  }\n\n  // Use a special param, if user define the reserve param, then it will have an error.\n  func = `function set ($v, $p) {\n    with (this) {\n      ${func.join('\\n')}\n      return fn1((${lastFor})[$p[0]]);\n    }\n  }`;\n\n  func = vueWithTransform(func);\n  func = func.replace('var _h=_vm.$createElement;var _c=_vm._self._c||_h;', ''); // removed unused vue code;\n\n  return func;\n}\n\nexports = module.exports = function() {\n  let modelid = 0;\n\n  this.register('template-parse-ast-attr-v-model', function parseVModel({ item, expr, scope }) {\n    let attrs = item.attribs;\n\n    let conflicts = ['value', 'v-bind', ':value'].filter(v => !!attrs[v]);\n\n    conflicts.forEach(c => {\n      this.logger.warn('v-model', `${c}=\"${attrs[c]}\" conflicts with v-model on element <${item.name}>`);\n      delete attrs[c];\n    });\n\n    expr = expr.trim();\n\n    let param = '',\n      i = 0;\n    while (i < expr.length && expr[i] !== '.' && expr[i] !== '[') {\n      // get v-model param, like item.checked or item[0]\n      param += expr[i++];\n    }\n\n    let rst = {\n      attrs: {},\n      model: {\n        id: modelid++,\n        tag: item.name,\n        expr: expr\n      }\n    };\n    if (scope) {\n      let iterators = [];\n      let fetchScope = scope;\n      let level = 0;\n      let referScope = null;\n      while (fetchScope) {\n        level++;\n\n        // Get all iterators from parent scopes\n        if (!referScope && fetchScope.declared.indexOf(param) > -1) {\n          referScope = fetchScope;\n          iterators = [];\n        }\n        if (referScope) {\n          if (!fetchScope.iterator1) {\n            this.logger.error(\n              'v-for',\n              `Missing iterator index in \"${fetchScope.expr}\". If you want to use v-model inside a v-for. then you have to declare a iterator index, like \"(item, index) in list\".`\n            );\n          } else {\n            if (iterators.indexOf(fetchScope.iterator1) > -1) {\n              // index exists\n              this.logger.warn('v-for', `Duplicated iterator in \"${fetchScope.expr}\"`);\n            }\n            iterators.push(fetchScope.iterator1);\n          }\n        }\n        fetchScope = fetchScope.parent;\n      }\n\n      if (iterators && iterators.length) {\n        rst.model.scopeInfo = {\n          referScope: referScope,\n          scope: scope,\n          param: param,\n          level: level,\n          iterators: iterators\n        };\n      }\n    }\n    return rst;\n  });\n\n  this.register('template-parse-ast-attr-v-model-apply', function parseVModelApply({ parsed, rel }) {\n    let model = parsed.model;\n    let expr = model.expr.trim();\n    let attrs = parsed.attrs;\n\n    if (rel.model) {\n      return;\n    }\n\n    if (model.tag === 'radio' || model.tag === 'checkbox') {\n      // checkbox and radio do not have bindchange event.\n      this.logger.warn(\n        'v-model',\n        `<${model.tag} /> do not support v-model, please use <${model.tag}-group /> instead.`\n      );\n    }\n\n    let map = MODEL_MAP[model.tag];\n    if (map) {\n      if (map.value) {\n        attrs[map.value] = `{{ ${expr} }}`;\n      }\n\n      if (!attrs[`bind${map.type}`]) {\n        attrs[`bind${map.type}`] = CONST.EVENT_DISPATCHER;\n      }\n\n      if (!rel.models) {\n        rel.models = [];\n      }\n      rel.models[model.id] = {\n        type: map.type,\n        expr: expr\n      };\n\n      if (model.id !== undefined) {\n        attrs['data-model-id'] = model.id;\n      }\n\n      if (model.scopeInfo) {\n        // v-model in v-for\n        let iterators = model.scopeInfo.iterators;\n        let i = iterators.length;\n        let p = 0;\n        if (i > 26) {\n          this.logger.error('v-model', 'Too deep in v-for');\n        }\n        while (--i >= 0) {\n          let attr = `data-model-` + String.fromCharCode(97 + p++);\n          attrs[attr] = `{{ ${iterators[i]} }}`;\n        }\n\n        rel.models[model.id].handler = generateModelFunctionInScope(model.scopeInfo.referScope, iterators, expr);\n      } else {\n        rel.models[model.id].handler = generateModelFunction(expr);\n      }\n    }\n\n    return { parsed, rel };\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/template/directives/other.js",
    "content": "const onRE = /^@|^v-on:/;\nconst bindRE = /^:|^v-bind:/;\nconst nativeBindRE = /^bind:?|^catch:?|^capture-bind:?|^capture-catch:?/;\n\nexports = module.exports = function() {\n  /*\n  this.register('template-parse-ast-pre-attr-[other]', function preParseDirectivesFor ({item, name, expr, modifiers, scope, ctx}) {\n  });\n  */\n\n  this.register('template-parse-ast-attr-[other]', function parseDirectivesFor({\n    item,\n    name,\n    expr,\n    modifiers,\n    scope,\n    ctx\n  }) {\n    if (nativeBindRE.test(name)) {\n      let bindType = name.match(nativeBindRE)[0];\n      name = name.replace(bindType, '');\n      modifiers = {};\n      if (bindType[bindType.length - 1] === ':') {\n        bindType = bindType.substring(0, bindType.length - 1);\n      }\n      switch (bindType) {\n        case 'bind':\n          break;\n        case 'catch':\n          modifiers.stop = true;\n          break;\n        case 'capture-bind':\n          modifiers.capture = true;\n          break;\n        case 'capture-catch':\n          modifiers.stop = true;\n          modifiers.capture = true;\n          break;\n      }\n      return this.hookUnique('template-parse-ast-attr-v-on', { item, name, expr, modifiers, scope, ctx });\n    }\n\n    if (bindRE.test(name)) {\n      // :prop or v-bind:prop;\n\n      return this.hookUnique('template-parse-ast-attr-v-bind', { item, name, expr, modifiers, scope, ctx });\n    } else if (onRE.test(name)) {\n      // @ or v-on:\n      name = name.replace(onRE, '');\n      return this.hookUnique('template-parse-ast-attr-v-on', { item, name, expr, modifiers, scope, ctx });\n    }\n\n    return {\n      attrs: {\n        [name]: expr\n      }\n    };\n  });\n\n  this.register('template-parse-ast-attr-[other]-apply', function applyDirective({ parsed, rel }) {\n    return {\n      parsed,\n      rel\n    };\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/template/directives/v-on.js",
    "content": "const vueWithTransform = require('vue-template-es2015-compiler');\nconst paramsDetect = require('./../../../ast/paramsDetect');\nconst CONST = require('./../../../util/const');\n\n/**\n * parsse handler AST\n * @param {String} expr   function expression, e.g. doSomething(a,b,c); item++;\n * @return {Object}       AST result\n */\nconst parseHandlerProxy = (expr, scope) => {\n  let injectParams = [];\n  let handlerExpr = expr;\n  let eventInArg = false;\n  let needDeclareWx = false;\n  let argumentsInArg = false;\n\n  let parsedHandler;\n  // eslint-disable-next-line\n  if (/^[\\w\\.]+$/.test(expr)) {\n    //   @tap=\"doSomething\" or @tap=\"m.doSomething\"\n    needDeclareWx = true;\n    argumentsInArg = true;\n    eventInArg = true;\n\n    parsedHandler = {\n      callee: { name: handlerExpr },\n      params: []\n    };\n    handlerExpr = `${expr}.apply(_vm, $args || [$event])`;\n  } else {\n    try {\n      parsedHandler = paramsDetect(handlerExpr);\n    } catch (e) {\n      throw new Error(`Can not parse \"${handlerExpr}\"`);\n    }\n\n    for (let id in parsedHandler.identifiers) {\n      let fetch = scope;\n      while (fetch) {\n        if (!parsedHandler.identifiers[id].callable && fetch.declared.indexOf(id) !== -1) {\n          injectParams.push(id);\n          break;\n        }\n        fetch = fetch.parent;\n      }\n    }\n\n    if (parsedHandler.identifiers.$event) {\n      needDeclareWx = true;\n      eventInArg = true;\n    }\n\n    if (parsedHandler.identifiers.$wx) {\n      needDeclareWx = true;\n    }\n\n    if (parsedHandler.identifiers.arguments) {\n      needDeclareWx = true;\n      argumentsInArg = true;\n      handlerExpr = handlerExpr.replace('arguments', '$args');\n    }\n  }\n\n  const functionCode = handlerExpr;\n\n  let declaredCodes = [];\n\n  declaredCodes.push('const _vm=this;');\n  if (needDeclareWx) {\n    declaredCodes.push('const $wx = arguments[arguments.length - 1].$wx;');\n  }\n  if (eventInArg) {\n    declaredCodes.push(\n      '  const $event = ($wx.detail && $wx.detail.arguments) ? $wx.detail.arguments[0] : arguments[arguments.length -1];'\n    );\n  }\n  if (argumentsInArg) {\n    declaredCodes.push('  const $args = $wx.detail && $wx.detail.arguments;');\n  }\n\n  let proxy = `function proxy (${injectParams.join(', ')}) {\n  ${declaredCodes.join('\\n')}\n  with (this) {\n  return (function () {\n    ${functionCode};\n  })();}\n}`;\n\n  proxy = vueWithTransform(proxy); // transform this\n  proxy = proxy.replace('var _h=_vm.$createElement;var _c=_vm._self._c||_h;', ''); // removed unused vue code;\n  if (proxy.indexOf('_vm=this') !== proxy.lastIndexOf('_vm=this')) {\n    proxy = proxy.replace('var _vm=this;\\n', ''); // _vm will decalred twice;\n  }\n  return {\n    proxy: proxy,\n    params: injectParams,\n    parsed: parsedHandler\n  };\n};\n\n/**\n * parse event handler\n * @param  {String} key   event key, e.g. tap\n * @param  {String} value event value, e.g. doSomething(item)\n * @return {Object}       parse result, e.g. {type: \"bind:tap\", name: \"doSomething\", params: [\"item\"]}\n */\nconst parseHandler = (name = '', value = '', scope) => {\n  let type = '';\n  let info;\n  info = parseHandlerProxy(value, scope);\n\n  if (name === 'click') name = 'tap';\n  type = 'bind:' + name;\n  return {\n    event: name,\n    type: type,\n    params: info.params,\n    proxy: info.proxy,\n    parsed: info.parsed,\n    expr: CONST.EVENT_DISPATCHER\n  };\n};\n/*\n * parse @tap=\"click\", v-on:tap=\"click\"\n */\nexports = module.exports = function() {\n  let totalEvtCache = {}; // Global event cache\n\n  this.register('template-parse-ast-attr-v-on.capture', function({ item, name, expr, event, scope, ctx }) {\n    // bind:tap=\"xxx\" or catch:tap=\"xxx\"\n    event.type = event.type.replace(/^bind/, 'bind').replace(/^catch/, 'catch');\n    event.type = 'capture-' + event.type;\n    return { item, name, expr, event, scope, ctx };\n  });\n\n  this.register('template-parse-ast-attr-v-on.stop', function({ item, name, expr, event, scope, ctx }) {\n    if (event.type.startsWith('bind')) {\n      // bindtap=\"xxx\"\n      event.type = event.type.replace(/^bind/, 'catch');\n    } else if (event.type.indexOf('-bind') > -1) {\n      // capture-bindtap=\"xxx\"\n      event.type = event.type.replace(/-bind/, '-catch');\n    }\n    return { item, name, expr, event, scope, ctx };\n  });\n\n  this.register('template-parse-ast-attr-v-on.wxs', function({ item, name, expr, event, scope, ctx }) {\n    event.expr = `{{ ${event.parsed.callee.name} }}`;\n    event.proxy = false;\n    event.params = event.parsed.params.map(p => {\n      if (p.type === 'Literal') {\n        return p.name;\n      } else {\n        return `{{ ${p.name} }}`;\n      }\n    });\n    return { item, name, expr, event, scope, ctx };\n  });\n\n  this.register('template-parse-ast-attr-v-on', function parseAstOn({ item, name, expr, modifiers, scope, ctx }) {\n    let handler = expr.trim();\n\n    let parsedEvent;\n\n    try {\n      parsedEvent = parseHandler(name, handler, scope);\n    } catch (e) {\n      this.hookUnique(\n        'error-handler',\n        'template',\n        {\n          code: expr,\n          ctx,\n          type: 'error',\n          message: 'Can not parse \"v-on\" expression',\n          title: 'v-on'\n        },\n        { item }\n      );\n      throw new Error('EXIT');\n    }\n\n    /**\n     * we can recognition wxs dynamically\n     * e.g:\n     *\n     *  <wxs module=\"m\" lang=\"babel\">\n     *  const touchmove = (event) => {\n     *    console.log('log event', JSON.stringify(event))\n     *  }\n     *  module.exports.touchmove = touchmove;\n     *  </wxs>\n     *  <template>\n     *    <div class=\"container\">\n     *      <div class=\"userinfo\" @touchmove=\"m.touchmove\">\n     *    </div>\n     *    </div>\n     *  </template>\n     */\n    const eventCallee = parsedEvent.parsed.callee;\n    if (!modifiers.wxs && eventCallee && eventCallee.name) {\n      const calleeChunks = eventCallee.name.split('.');\n      const wxsBlock = ctx.sfc.wxs;\n\n      if (\n        calleeChunks.length > 1 &&\n        wxsBlock &&\n        Array.isArray(wxsBlock) &&\n        wxsBlock.find(item => item.attrs.module === calleeChunks[0])\n      ) {\n        modifiers.wxs = true;\n        this.hookUnique(\n          'error-handler',\n          'template',\n          {\n            ctx: ctx,\n            message: `seems '${calleeChunks[0]}' is a wxs module, please manully add a  .wxs modifier for the event.`,\n            type: 'warn',\n            title: 'v-on'\n          },\n          {\n            item: item,\n            attr: name,\n            expr: expr\n          }\n        );\n      }\n    }\n\n    for (let k in modifiers) {\n      let hookName = 'template-parse-ast-attr-v-on.' + k;\n      if (this.hasHook(hookName)) {\n        this.hook(hookName, { item, name, expr, event: parsedEvent, scope, ctx });\n      }\n    }\n    parsedEvent.params.forEach((p, i) => {\n      let paramAttr = 'data-wpy' + parsedEvent.event.toLowerCase() + '-' + String.fromCharCode(97 + i);\n      if (paramAttr.length > 31) {\n        this.logger.warn(`Function name is too long, it may cause an Error. \"${parsedEvent.handler}\"`);\n      }\n    });\n    parsedEvent.tag = item.name;\n    if (parsedEvent.proxy) {\n      let assetsId = this.assets.get(ctx.file);\n      let evtCache;\n\n      if (!totalEvtCache[assetsId]) {\n        totalEvtCache[assetsId] = {\n          increaseId: 0\n        };\n      }\n      evtCache = totalEvtCache[assetsId];\n\n      if (!item.events) {\n        item.events = [];\n        parsedEvent.id = `${assetsId}-${evtCache.increaseId}`;\n      } else {\n        parsedEvent.id = item.events[item.events.length - 1].id;\n      }\n      if (!ctx.events) {\n        // generate rel\n        ctx.events = [];\n        ctx.events.push(parsedEvent);\n      }\n      evtCache.increaseId++;\n      parsedEvent.params = parsedEvent.params.map(p => `{{ ${p} }}`);\n    }\n    if (!item.events) {\n      item.events = [];\n    }\n    item.events.push(parsedEvent);\n\n    return {\n      hook: 'template-parse-ast-attr-v-on-apply',\n      'v-on': parsedEvent,\n      attrs: {}\n    };\n  });\n\n  this.register('template-parse-ast-attr-v-on-apply', function parseBindClass({ parsed, rel }) {\n    let vOn = parsed['v-on'];\n\n    if (!vOn.proxy) {\n      return { parsed, rel };\n    }\n\n    let isComponent = !!rel.components[vOn.tag];\n\n    if (isComponent) {\n      // it is a custom defined component\n      rel.on[vOn.id] = rel.on[vOn.id] || [];\n\n      if (rel.on[vOn.id].includes(vOn.event)) {\n        // Todo: repeat event\n        // this.logger.warn('v-on', ``);\n      } else {\n        rel.on[vOn.id].push(vOn.event);\n      }\n    }\n    if (!rel.handlers[vOn.id]) rel.handlers[vOn.id] = {};\n\n    rel.handlers[vOn.id][vOn.event] = vOn.proxy;\n\n    return { parsed, rel };\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/template/parse.js",
    "content": "const htmlparser = require('htmlparser2');\nconst tools = require('../../util/tools');\nconst modifierRE = /\\.[^.]+/g;\n\nconst toAST = html => {\n  return new Promise((resolve, reject) => {\n    const handler = new htmlparser.DomHandler(\n      function(error, dom) {\n        if (error) {\n          reject(error);\n        } else {\n          resolve(dom);\n        }\n      },\n      { withStartIndices: true, withEndIndices: true }\n    );\n    const parser = new htmlparser.Parser(handler, { xmlMode: true });\n    parser.write(html);\n    parser.end();\n  });\n};\n/**\n * parse modifiers\n * @param  {String} name e.g. tap.stop.other\n * @return {Object}      e.g. {stop: true, other: true}\n */\nconst parseModifiers = (name = '') => {\n  let ret = {};\n  let match = name.match(modifierRE);\n  if (match) {\n    match.forEach(function(m) {\n      ret[m.slice(1)] = true;\n    });\n  }\n  return ret;\n};\n\nconst decodingMap = {\n  '&lt;': '<',\n  '&gt;': '>',\n  '&amp;': '&'\n};\n\nfunction decodeAttr(value) {\n  return value.replace(/&(?:lt|gt|amp);/g, function(match) {\n    return decodingMap[match];\n  });\n}\n\nexports = module.exports = function() {\n  this.register('template-parse-ast-attr', function parseAstAttr(item, scope, rel, ctx) {\n    let attrs = item.attribs;\n    let parsedAttr = item.parsedAttr || {};\n    let parsed = null;\n\n    let cleanAttrs = [];\n\n    // Pre walk attributes\n    for (let name in attrs) {\n      let expr = attrs[name];\n\n      expr = decodeAttr(expr);\n\n      ({ item, name, expr } = this.hookUniqueReturnArg('template-parse-ast-pre-attr-' + name, { item, name, expr }));\n\n      let modifiers = parseModifiers(name);\n\n      if (modifiers) {\n        name = name.replace(modifierRE, '');\n      }\n\n      let hook = 'template-parse-ast-pre-attr-' + name;\n\n      if (!this.hasHook(hook)) {\n        hook = 'template-parse-ast-pre-attr-[other]';\n      }\n\n      ({ item, name, expr, modifiers, scope, ctx } = this.hookUniqueReturnArg(hook, {\n        item,\n        name,\n        expr,\n        modifiers,\n        scope,\n        ctx\n      }));\n\n      cleanAttrs.push({\n        item: item,\n        name: name,\n        expr: expr,\n        modifiers: modifiers\n      });\n    }\n\n    // Apply walk attributes\n    cleanAttrs.forEach(({ item, name, expr, modifiers }) => {\n      let hook = 'template-parse-ast-attr-' + name;\n      if (!this.hasHook(hook)) {\n        hook = 'template-parse-ast-attr-[other]';\n      }\n\n      parsed = this.hookUnique(hook, { item, name, expr, modifiers, scope, ctx, rel });\n      rel = parsed.rel || rel;\n\n      let applyHook = parsed.hook || `template-parse-ast-attr-${name}-apply`;\n      if (!this.hasHook(applyHook)) {\n        applyHook = `template-parse-ast-attr-[other]-apply`;\n      }\n\n      ({ parsed, rel } = this.hookUniqueReturnArg(applyHook, { parsed, rel }));\n\n      if (parsed && parsed.attrs) {\n        parsedAttr = Object.assign(parsedAttr, parsed.attrs);\n      }\n    });\n\n    item.parsedAttr = parsedAttr;\n\n    return [item, scope, rel, ctx];\n  });\n\n  this.register('template-parse-ast-tag', function parseAstTag(item, rel) {\n    let htmlTags = this.tags.htmlTags;\n    let wxmlTags = this.tags.wxmlTags;\n    let html2wxmlMap = this.tags.html2wxmlMap;\n    let logger = this.logger;\n\n    let components = rel.components;\n    if (components[item.name]) {\n      // It's a user defined component\n      logger.silly('tag', `Found user defined component \"${item.name}\"`);\n      item.parsedAttr = item.parsedAttr || {};\n      item.parsedAttr['bind_init'] = '__initComponent';\n    } else if (html2wxmlMap[item.name]) {\n      // Tag is in the map list\n      logger.silly('html2wxml', `Change \"${item.name}\" to \"${html2wxmlMap[item.name]}\"`);\n      item.name = html2wxmlMap[item.name];\n    } else if (wxmlTags.indexOf(item.name) > -1) {\n      // Tag is a wxml tag\n    } else if (htmlTags.indexOf(item.name) > -1) {\n      // Tag is a html tag\n      logger.silly('html2wxml', `Change \"${item.name}\" is a html tag, changed to \"view\"`);\n      item.name = 'view';\n    } else {\n      // Tag is a unknow tag\n      logger.silly('tag', `Assume \"${item.name}\" is a user defined component`);\n    }\n\n    return [item, rel];\n  });\n\n  this.register('template-parse-ast', function parseAST(ast, scope, rel, ctx) {\n    let currentScope;\n    ast.forEach(item => {\n      if (item.type === 'tag') {\n        [item, rel] = this.hookSeq('template-parse-ast-tag', item, rel);\n      }\n      if (item.attribs) {\n        [item, currentScope, rel] = this.hookSeq('template-parse-ast-attr', item, scope, rel, ctx);\n      }\n      if (item.children && item.children.length) {\n        [item.childen, currentScope, rel] = this.hookSeq('template-parse-ast', item.children, currentScope, rel, ctx);\n      }\n    });\n    return [ast, scope, rel, ctx];\n  });\n\n  this.register('template-parse-ast-to-str', function astToStr(ast) {\n    let str = '';\n    ast.forEach(item => {\n      if (item.type === 'text') {\n        str += item.data;\n      } else if (item.type === 'tag') {\n        str += '<' + item.name;\n        if (item.events) {\n          item.events.forEach(evt => {\n            if (evt.proxy) item.parsedAttr['data-wpy-evt'] = evt.id;\n            item.parsedAttr[evt.type] = evt.expr;\n            evt.params.forEach((p, i) => {\n              if (i > 26) {\n                // Maxium params.\n                this.logger.warn(`Too many params`);\n              } else {\n                let evtAttr = 'data-wpy' + evt.event.toLowerCase() + '-' + String.fromCharCode(97 + i);\n                if (evtAttr.length > 31) {\n                  this.logger.warn(`Function name is too long, it may cause an Error. \"${evt.handler}\"`);\n                }\n                item.parsedAttr[evtAttr] = `${p}`;\n              }\n            });\n          });\n        }\n        if (item.parsedAttr) {\n          Object.keys(item.parsedAttr).forEach(attr => {\n            if (item.parsedAttr[attr] !== undefined && attr !== 'class' && attr !== 'style')\n              str +=\n                tools.isTrue(item.parsedAttr[attr]) || item.parsedAttr[attr] === ''\n                  ? ` ${attr}`\n                  : ` ${attr}=\"${item.parsedAttr[attr]}\"`;\n          });\n        }\n        if (item.parsedAttr.style || (item.bindStyle && item.bindStyle.length)) {\n          let staticStyle = (item.parsedAttr.style || '').trim();\n          if (staticStyle !== '' && /;$/.test(staticStyle) === false) {\n            staticStyle += ';';\n          }\n          let bindStyle = item.bindStyle && item.bindStyle.length ? ` {{ ${item.bindStyle.join(' + ')} }}` : '';\n          str += ` style=\"${staticStyle + bindStyle}\"`;\n        }\n        if (item.parsedAttr.class || (item.bindClass && item.bindClass.length)) {\n          let staticClass = item.parsedAttr.class || '';\n          let bindClass = item.bindClass && item.bindClass.length ? ` {{ [ ${item.bindClass.join(',')} ] }}` : '';\n          str += ` class=\"${staticClass + bindClass}\"`;\n        }\n        if (this.tags.selfCloseTags.includes(item.name) || (item.name === 'template' && !item.children.length)) {\n          str += ' />';\n        } else {\n          str += '>';\n          if (item.children && item.children.length) {\n            str += this.hookUnique('template-parse-ast-to-str', item.children);\n          }\n          str += `</${item.name}>`;\n        }\n      }\n    });\n    return str;\n  });\n\n  this.register('template-parse', function parse(html, components, ctx) {\n    return toAST(html).then(ast => {\n      let rel = { handlers: {}, components: components, on: {} };\n\n      // eslint-disable-next-line\n      let scope = null;\n      [ast, scope, rel] = this.hookSeq('template-parse-ast', ast, null, rel, ctx);\n\n      let code = this.hookUnique('template-parse-ast-to-str', ast);\n\n      return {\n        code: code,\n        rel: rel,\n        ast: ast\n      };\n    });\n  });\n};\n"
  },
  {
    "path": "packages/cli/core/plugins/template/util/check.js",
    "content": "// strip strings in expressions\nconst stripStringRE = /'(?:[^'\\\\]|\\\\.)*'|\"(?:[^\"\\\\]|\\\\.)*\"|`(?:[^`\\\\]|\\\\.)*\\$\\{|\\}(?:[^`\\\\]|\\\\.)*`|`(?:[^`\\\\]|\\\\.)*`/g;\n\n// these keywords should not appear inside expressions, but operators like\n// typeof, instanceof and in are allowed\nconst prohibitedKeywordRE = new RegExp(\n  '\\\\b' +\n    (\n      'do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +\n      'super,throw,while,yield,delete,export,import,return,switch,default,' +\n      'extends,finally,continue,debugger,function,arguments'\n    )\n      .split(',')\n      .join('\\\\b|\\\\b') +\n    '\\\\b'\n);\n\nexports = module.exports = {\n  checkExpression: function(expr, text) {\n    try {\n      new Function('return ' + expr);\n    } catch (e) {\n      let keywordMatch = expr.replace(stripStringRE, '').match(prohibitedKeywordRE);\n      if (keywordMatch) {\n        return `avoid using Javascript keyword as property name: \"${keywordMatch[0]}\". Raw expression: ${text.trim()}`;\n      } else {\n        return `Invalid expression: ${e.message} in \"${expr}\". Raw Expression: ${text.trim()}`;\n      }\n    }\n  }\n};\n"
  },
  {
    "path": "packages/cli/core/tag.js",
    "content": "const { isArr } = require('./util/tools');\n\n// https://developer.mozilla.org/en-US/docs/Web/HTML/Element\nconst HTML_TAGS = [\n  // Main root\n  'html',\n  // Document metadata\n  'link,meta,style,title',\n  // Sectioning root\n  'body',\n  // Content sectioning\n  'address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section',\n  // Text content\n  'blockquote,dd,dir,div,dl,dt,figcaption,figure,hr,li,main,ol,p,pre,ul',\n  // Inline text semantics\n  'a,abbr,b,bdi,bdo,br,cite,code,data,dfn,em,i,kdb,mark,nobr,q,rp,rt,rtc,ruby,s,samp,small,span,strong,sub,sup,time,tt,u,var,wbr',\n  // Image and multimedia\n  'area,audio,img,map,track,video',\n  // Embedded content\n  'applet,embed,iframe,noembed,object,param,picture,source',\n  // Scripting\n  'canvas,noscript,script',\n  // Demarcating edits\n  'del,ins',\n  // Table content\n  'caption,col,colgroup,table,tbody,td,tfoot,th,thead,tr',\n  // Forms\n  'button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,output,progress,select,textarea',\n  // Interactive elements\n  'details,dialog,menu,menuitem,summary',\n  // Web Components\n  'content,element,shadow,slot,template',\n  // Obsolete and deprecated elements\n  'acronym,applet,basefont,bgsound,big,blink,center,command,content,dir,element,font,frame,frameset,image,isindex,keygen,listing,marquee,menuitem,multicol,nextid,nobr,noembed,noframes,plaintext,shadow,spacer,strike,tt,xmp'\n]\n  .join(',')\n  .split(',');\n\n// https://developers.weixin.qq.com/miniprogram/dev/component/\nconst WXML_TAGS = [\n  // view\n  'block,view,scroll-view,swiper,movable-view,cover-view',\n  // base\n  'icon,text,rich-text,progress',\n  // form\n  'button,checkbox,form,input,label,picker,picker-view,radio,slider,switch,textarea',\n  // navigator\n  'navigator',\n  // audio\n  'image,video,camera,live-player,live-pusher',\n  // map\n  'map',\n  // canvas\n  'canvas',\n  // slot\n  'slot',\n  // ability\n  'open-data,web-view,ad',\n  // reference\n  'template,import,include'\n]\n  .join(',')\n  .split(',');\n\nconst HTML2WXML_MAP = {\n  select: 'picker',\n  datalist: 'picker',\n  img: 'image',\n  source: 'audio',\n  video: 'video',\n  track: 'video',\n  a: 'navigator',\n  span: 'label',\n  'contact-button': 'contact-button',\n  // support template [template](https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/template.html)\n  'wx-template': 'template'\n};\n\nconst SELF_CLOSE_TAGS = [\n  'progress',\n  'checkbox',\n  'input',\n  'radio',\n  'slider',\n  'switch',\n  'textarea',\n  'navigation-bar',\n  'include',\n  'import'\n];\n\n/**\n * combine two tags array/object\n * @param  {Array} original original tag list\n * @param  {Undefined/String/Array/Object} additional additional list\n * @return {Array} new tag list Array\n */\nconst combineTag = function(original, additional) {\n  if (isArr(additional)) {\n    return original.concat(additional);\n  } else if (typeof additional === 'string') {\n    return original.concat(additional.split(','));\n  } else if (typeof additional !== 'object') {\n    return [].concat(original);\n  }\n\n  let addTags = [];\n  let removeTags = [];\n  for (let k in additional) {\n    if (addTags[k]) {\n      addTags.push(k);\n    } else {\n      removeTags.push(k);\n    }\n  }\n\n  let rst = original.concat(addTags);\n  removeTags.forEach(k => {\n    let index = rst.indexOf(k);\n    while (index !== -1) {\n      rst.splice(index, 1);\n      index = rst.indexOf(k);\n    }\n  });\n};\n\nconst combineTagMap = function(original, additional = {}) {\n  return Object.assign({}, original, additional);\n};\n\nexports = module.exports = {\n  HTML_TAGS,\n  WXML_TAGS,\n  HTML2WXML_MAP,\n  SELF_CLOSE_TAGS,\n  combineTag,\n  combineTagMap\n};\n"
  },
  {
    "path": "packages/cli/core/util/ast.js",
    "content": "const acorn = require('acorn-dynamic-import').default;\n\nconst ECMA_VERSION = 2017;\n\nconst POSSIBLE_AST_OPTIONS = [\n  {\n    ranges: true,\n    locations: true,\n    ecmaVersion: ECMA_VERSION,\n    sourceType: 'module',\n    plugins: {\n      dynamicImport: true\n    }\n  },\n  {\n    ranges: true,\n    locations: true,\n    ecmaVersion: ECMA_VERSION,\n    sourceType: 'script',\n    plugins: {\n      dynamicImport: true\n    }\n  }\n];\n\nexports = module.exports = function ast(source) {\n  let ast;\n  const comments = [];\n  for (let i = 0, len = POSSIBLE_AST_OPTIONS.length; i < len; i++) {\n    if (!ast) {\n      try {\n        comments.length = 0;\n        POSSIBLE_AST_OPTIONS[i].onComment = comments;\n        ast = acorn.parse(source, POSSIBLE_AST_OPTIONS[i]);\n      } catch (e) {\n        // ignore the error\n      }\n    }\n  }\n\n  if (!ast) {\n    ast = acorn.parse(source, {\n      ranges: true,\n      locations: true,\n      ecmaVersion: ECMA_VERSION,\n      sourceType: 'module',\n      plugins: {\n        dynamicImport: true\n      },\n      onComment: comments\n    });\n  }\n\n  if (!ast || typeof ast !== 'object') {\n    throw new Error(`Source could't be parsed`);\n  }\n  return ast;\n};\n"
  },
  {
    "path": "packages/cli/core/util/const.js",
    "content": "exports = module.exports = {\n  EVENT_DISPATCHER: '__dispatcher',\n  VENDOR_DIR: '$vendor',\n  WEAPP_EXT: '.$weapp'\n};\n"
  },
  {
    "path": "packages/cli/core/util/error.js",
    "content": "const codeFrameColumns = require('@babel/code-frame').codeFrameColumns;\nconst logger = require('./logger');\n\nexports = module.exports = {\n  warn(msg, file, codeFrame, location) {\n    logger.warn(msg);\n    logger.warn(file);\n    const result = codeFrameColumns(codeFrame, location, {\n      /* options */\n    });\n    // eslint-disable-next-line\n    console.log(result);\n  },\n  error(msg, file, codeFrame, location) {\n    logger.warn(msg);\n    logger.warn(file);\n    const result = codeFrameColumns(codeFrame, location, {\n      /* options */\n    });\n    // eslint-disable-next-line\n    console.log(result);\n    process.exit();\n  }\n};\n"
  },
  {
    "path": "packages/cli/core/util/exprParser.js",
    "content": "const camelizeRE = /-(\\w)/g;\nconst hyphenateRE = /([^-])([A-Z])/g;\n\nconst cached = fn => {\n  let cache = {};\n  return str => cache[str] || (cache[str] = fn(str));\n};\n\nexports = module.exports = {\n  hyphenate: cached(str => {\n    return str\n      .replace(hyphenateRE, '$1-$2')\n      .replace(hyphenateRE, '$1-$2')\n      .toLowerCase();\n  }),\n  camelize: cached(str => {\n    return str.replace(camelizeRE, function(_, c) {\n      return c ? c.toUpperCase() : '';\n    });\n  }),\n  /**\n   * str2obj   parse a object string to a real object\n   * @param  {String} str \"{someKey: someCondition}\"\n   * @return {Object}     {someKey: someCondition}\n   */\n  str2obj: cached(exp => {\n    exp = exp.replace(/^\\s/gi, '').replace(/\\s$/gi, '');\n    if (exp[0] === '{' && exp[exp.length - 1] === '}') {\n      exp = exp.substring(1, exp.length - 1);\n      let i = 0,\n        len = exp.length;\n      let flagStack = [],\n        flag = 'start';\n      let classNames = [],\n        result = {},\n        str = '';\n      for (i = 0; i < len; i++) {\n        // eslint-disable-next-line\n        if (exp[i] === '\\'' || exp[i] === '\"') {\n          if (flagStack.length && flagStack[0] === exp[i]) {\n            flagStack.pop();\n            if (flag === 'class') {\n              flag = ':';\n              continue;\n            } else if (flag === 'expression') {\n              str += exp[i];\n              continue;\n            }\n          } else {\n            if (flagStack.length === 0) {\n              flagStack.push(exp[i]);\n              if (flag === 'start') {\n                flag = 'class';\n                continue;\n              } else if (flag === 'expression') {\n                str += exp[i];\n                continue;\n              }\n            }\n          }\n        }\n        // {abc: num < 1} or {'abc': num <１}\n        if (exp[i] === ':' && (flag === ':' || flag === 'class') && flagStack.length === 0) {\n          flag = 'expression';\n          classNames.push(str);\n          str = '';\n          continue;\n        }\n        if (exp[i] === ',' && flag === 'expression' && flagStack.length === 0) {\n          result[classNames[classNames.length - 1]] = str.replace(/^\\s/gi, '').replace(/\\s$/gi, '');\n          str = '';\n          flag = 'start';\n          continue;\n        }\n        // get rid of the begining space\n        if (!str.length && exp[i] === ' ') continue;\n\n        // not started with '', like {abc: num < 1}\n        if (flag === 'start') {\n          flag = 'class';\n        }\n\n        if (flag === 'class' || flag === 'expression') {\n          str += exp[i];\n        }\n      }\n      if (str.length) {\n        result[classNames[classNames.length - 1]] = str.replace(/^\\s/gi, '').replace(/\\s$/gi, '');\n      }\n      return result;\n    } else {\n      throw `:class expression is not correct, it has to be {'className': mycondition}`;\n    }\n  })\n};\n"
  },
  {
    "path": "packages/cli/core/util/hash.js",
    "content": "const crypto = require('crypto');\nconst fs = require('fs');\n\nexports = module.exports = {\n  hash(s) {\n    let md5 = crypto.createHash('md5');\n    md5.update(s);\n    return md5.digest('hex');\n  },\n  hashFile(path) {\n    let s = fs.readFileSync(path);\n    return this.hash(s);\n  }\n};\n"
  },
  {
    "path": "packages/cli/core/util/logger.js",
    "content": "const log = require('npmlog');\n\nconst mylog = {};\n\nconst datetime = (date = new Date(), format = 'HH:mm:ss') => {\n  let fn = d => {\n    return ('0' + d).slice(-2);\n  };\n  if (date && typeof date === 'string') {\n    date = new Date(Date.parse(date));\n  }\n  const formats = {\n    YYYY: date.getFullYear(),\n    MM: fn(date.getMonth() + 1),\n    DD: fn(date.getDate()),\n    HH: fn(date.getHours()),\n    mm: fn(date.getMinutes()),\n    ss: fn(date.getSeconds())\n  };\n  return format.replace(/([a-z])\\1+/gi, function(a) {\n    return formats[a] || a;\n  });\n};\n\n['info', 'silly', 'verbose', 'http', 'timing', 'notice', 'silent', 'warn', 'error'].forEach(v => {\n  mylog[v] = (...args) => {\n    log.heading = '[' + datetime() + ']';\n    if (args.length === 1) {\n      args = [''].concat(args);\n    }\n    if (log.level !== 'trace') {\n      args.forEach(\n        (arg, i) =>\n          typeof arg === 'object' && arg instanceof Error && arg.stack && arg.message && (args[i] = arg.message)\n      );\n    }\n    log.log.apply(log, [v].concat(args));\n  };\n});\n\nmylog.level = v => (v ? (log.level = v) : log.level);\n\nexports = module.exports = mylog;\n"
  },
  {
    "path": "packages/cli/core/util/tools.js",
    "content": "/**\n * String type check\n */\nexports.isStr = v => typeof v === 'string';\n/**\n * Number type check\n */\nexports.isNum = v => typeof v === 'number';\n/**\n * Array type check\n */\nexports.isArr = Array.isArray;\n/**\n * undefined type check\n */\nexports.isUndef = v => v === undefined;\n\nexports.isTrue = v => v === true;\n\nexports.isFalse = v => v === false;\n/**\n * Function type check\n */\nexports.isFunc = v => typeof v === 'function';\n/**\n * Quick object check - this is primarily used to tell\n * Objects from primitive values when we know the value\n * is a JSON-compliant type.\n */\nexports.isObj = exports.isObject = obj => {\n  return obj !== null && typeof obj === 'object';\n};\n\n/**\n * Strict object type check. Only returns true\n * for plain JavaScript objects.\n */\nconst _toString = Object.prototype.toString;\nexports.isPlainObject = obj => {\n  return _toString.call(obj) === '[object Object]';\n};\n\n/**\n * Check whether the object has the property.\n */\nconst hasOwnProperty = Object.prototype.hasOwnProperty;\nexports.hasOwn = (obj, key) => {\n  return hasOwnProperty.call(obj, key);\n};\n\n/**\n * Perform no operation.\n * Stubbing args to make Flow happy without leaving useless transpiled code\n * with ...rest (https://flow.org/blog/2017/05/07/Strict-Function-Call-Arity/)\n */\n// eslint-disable-next-line\nexports.noop = (a, b, c) => {};\n\n/**\n * Check if val is a valid array index.\n */\nexports.isValidArrayIndex = val => {\n  const n = parseFloat(String(val));\n  return n >= 0 && Math.floor(n) === n && isFinite(val);\n};\n"
  },
  {
    "path": "packages/cli/core/util/xmllint.js",
    "content": "const HTMLHint = require('htmlhint').default;\n\nconst DEFAULT_RULES = {\n  // Component can be uppercase\n  'tagname-lowercase': false,\n  'attr-lowercase': false,\n  'attr-value-double-quotes': true,\n  'attr-value-not-empty': false,\n  'attr-no-duplication': true,\n  // no need doctype\n  'doctype-first': false,\n  'tag-pair': true,\n  'tag-self-close': false,\n  'spec-char-escape': false,\n  'id-unique': true,\n  'src-not-empty': true,\n  // do not need title\n  'title-require': false,\n  // do not need alt\n  'alt-require': false,\n  'doctype-html5': false,\n  'id-class-value': false,\n  'style-disabled': false,\n  'inline-style-disabled': false,\n  'inline-script-disabled': true,\n  'space-tab-mixed-disabled': 'space',\n  'id-class-ad-disabled': false,\n  'href-abs-or-rel': false,\n  'attr-unsafe-chars': true,\n  'head-script-disabled': true\n};\n\nexports = module.exports = {\n  verify(html, rules) {\n    if (!rules) {\n      rules = DEFAULT_RULES;\n    } else {\n      rules = Object.assign({}, DEFAULT_RULES, rules);\n    }\n    return HTMLHint.verify(html, rules);\n  }\n};\n"
  },
  {
    "path": "packages/cli/index.js",
    "content": "exports = module.exports = require('./core/compile.js');\n"
  },
  {
    "path": "packages/cli/package.json",
    "content": "{\n  \"name\": \"@wepy/cli\",\n  \"version\": \"2.1.0\",\n  \"main\": \"index.js\",\n  \"bin\": {\n    \"wepy\": \"bin/wepy.js\"\n  },\n  \"scripts\": {\n    \"test\": \"mocha ./test/core/**/*.test.js\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+ssh://git@github.com/wepyjs/wepy.git\"\n  },\n  \"author\": {\n    \"name\": \"Gcaufy\"\n  },\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/wepyjs/wepy/issues\"\n  },\n  \"homepage\": \"https://github.com/wepyjs/wepy#readme\",\n  \"devDependencies\": {\n    \"babel\": \"^6.23.0\",\n    \"babel-preset-es2015\": \"^6.18.0\",\n    \"babel-preset-stage-1\": \"^6.16.0\",\n    \"chai\": \"^4.1.2\"\n  },\n  \"dependencies\": {\n    \"@babel/code-frame\": \"^7.0.0\",\n    \"acorn\": \"^5.7.4\",\n    \"acorn-dynamic-import\": \"^3.0.0\",\n    \"async\": \"^2.6.4\",\n    \"chalk\": \"^2.3.0\",\n    \"chokidar\": \"^3.0.1\",\n    \"colors\": \"^1.1.2\",\n    \"commander\": \"^2.9.0\",\n    \"compare-versions\": \"^3.0.0\",\n    \"consolidate\": \"^0.15.0\",\n    \"css\": \"^2.2.4\",\n    \"download\": \"^6.2.5\",\n    \"download-git-repo\": \"^1.0.2\",\n    \"enhanced-resolve\": \"^4.1.0\",\n    \"fs-extra\": \"^8.1.0\",\n    \"handlebars\": \"^4.7.7\",\n    \"hash-sum\": \"^1.0.2\",\n    \"htmlhint\": \"^0.11.0\",\n    \"htmlparser2\": \"^3.9.2\",\n    \"ignore\": \"^3.2.0\",\n    \"inquirer\": \"^5.0.1\",\n    \"js-base64\": \"^2.1.9\",\n    \"loader-utils\": \"^1.1.0\",\n    \"metalsmith\": \"^2.3.0\",\n    \"mkdirp\": \"^0.5.1\",\n    \"multimatch\": \"^2.1.0\",\n    \"ncp\": \"^2.0.0\",\n    \"npmlog\": \"^4.1.2\",\n    \"ora\": \"^1.4.0\",\n    \"postcss\": \"^5.2.16\",\n    \"postcss-selector-parser\": \"^2.2.3\",\n    \"read-metadata\": \"^1.0.0\",\n    \"request\": \"^2.67.0\",\n    \"slash\": \"^3.0.0\",\n    \"throttle-debounce\": \"^2.1.0\",\n    \"tildify\": \"^1.2.0\",\n    \"time-ago\": \"^0.2.1\",\n    \"tty-table\": \"^2.8.0\",\n    \"update-notifier\": \"^1.0.2\",\n    \"user-home\": \"^2.0.0\",\n    \"validate-npm-package-name\": \"^3.0.0\",\n    \"vue-template-compiler\": \"^2.5.16\",\n    \"vue-template-es2015-compiler\": \"^1.6.0\",\n    \"webpack-sources\": \"^1.1.0\"\n  },\n  \"engines\": {\n    \"node\": \">=6\"\n  },\n  \"publishConfig\": {\n    \"access\": \"public\"\n  },\n  \"readme\": \"ERROR: No README data found!\",\n  \"_id\": \"@wepy/cli@2.0.0-alpha.28\",\n  \"_commitid\": \"e714739\",\n  \"gitHead\": \"5a25776457360bbbbc54a4d059f6bc7c032d5df3\"\n}\n"
  },
  {
    "path": "packages/cli/test/config.js",
    "content": "const path = require('path');\n\nconst resolve = dir => path.join(__dirname, '..', dir);\n\nexports.alias = {\n  core: resolve('core'),\n  ast: resolve('core/ast'),\n  init: resolve('core/init'),\n  plugins: resolve('core/plugins'),\n  util: resolve('core/util')\n};\n"
  },
  {
    "path": "packages/cli/test/core/fileDep.test.js",
    "content": "const expect = require('chai').expect;\nconst FileDep = require('../../core/fileDep');\n\ndescribe('FileDep', function() {\n  it('should addDeps, getDeps and getSources', function() {\n    const fileDep = new FileDep();\n\n    fileDep.addDeps('a.wpy', ['b.js', 'c.js']);\n    expect(fileDep.getDeps('a.wpy')).to.eql(['b.js', 'c.js']);\n    expect(fileDep.getSources('b.js')).to.eql(['a.wpy']);\n    expect(fileDep.getSources('c.js')).to.eql(['a.wpy']);\n\n    fileDep.addDeps('b.wpy', ['c.js', 'd.js']);\n    expect(fileDep.getDeps('b.wpy')).to.eql(['c.js', 'd.js']);\n    expect(fileDep.getSources('c.js')).to.eql(['a.wpy', 'b.wpy']);\n  });\n\n  it('should cleanDeps', function() {\n    const fileDep = new FileDep();\n\n    fileDep.addDeps('a.wpy', ['b.js', 'c.js']);\n    fileDep.cleanDeps('a.wpy');\n    expect(fileDep.getDeps('a.wpy')).to.eql([]);\n    expect(fileDep.getSources('b.js')).to.eql([]);\n    expect(fileDep.getSources('c.js')).to.eql([]);\n\n    fileDep.addDeps('a.wpy', ['b.js', 'c.js']);\n    fileDep.addDeps('b.wpy', ['c.js', 'd.js']);\n    fileDep.cleanDeps('a.wpy');\n    expect(fileDep.getDeps('a.wpy')).to.eql([]);\n    expect(fileDep.getDeps('b.wpy')).to.eql(['c.js', 'd.js']);\n    expect(fileDep.getSources('b.js')).to.eql([]);\n    expect(fileDep.getSources('c.js')).to.eql(['b.wpy']);\n    expect(fileDep.getSources('d.js')).to.eql(['b.wpy']);\n  });\n\n  it('should not add duplicated deps', function() {\n    const fileDep = new FileDep();\n\n    fileDep.addDeps('a.wpy', ['a.js', 'b.js']);\n    expect(fileDep.getDeps('a.wpy')).to.eql(['a.js', 'b.js']);\n    expect(fileDep.getSources('a.js')).to.eql(['a.wpy']);\n    expect(fileDep.getSources('b.js')).to.eql(['a.wpy']);\n\n    fileDep.addDeps('a.wpy', ['b.js', 'c.js', 'd.js']);\n    expect(fileDep.getDeps('a.wpy')).to.eql(['a.js', 'b.js', 'c.js', 'd.js']);\n    expect(fileDep.getSources('a.js')).to.eql(['a.wpy']);\n    expect(fileDep.getSources('b.js')).to.eql(['a.wpy']);\n    expect(fileDep.getSources('c.js')).to.eql(['a.wpy']);\n    expect(fileDep.getSources('d.js')).to.eql(['a.wpy']);\n  });\n\n  it('should get isInvolved correctly', function() {\n    const fileDep = new FileDep();\n\n    fileDep.addDeps('a.wpy', ['b.js', 'c.js']);\n    expect(fileDep.isInvolved('a.wpy')).to.be.true;\n    expect(fileDep.isInvolved('b.js')).to.be.true;\n    expect(fileDep.isInvolved('c.js')).to.be.true;\n    expect(fileDep.isInvolved('d.js')).to.be.false;\n\n    fileDep.cleanDeps('a.wpy');\n    expect(fileDep.isInvolved('a.wpy')).to.be.false;\n    expect(fileDep.isInvolved('b.js')).to.be.false;\n    expect(fileDep.isInvolved('c.js')).to.be.false;\n  });\n});\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/assert/attrWithoutValue.wxml",
    "content": "<view hidden></view>\n<scroll-view scroll-x></scroll-view>\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/assert/bindClass.wxml",
    "content": "<view class=\"default {{ [ express - 1 === 0 ? 'test' : '',has ? 'has' : '' ] }}\"></view>\n<view class=\" {{ [ test ? 'test' : '',has ? 'has' : '',something ] }}\"></view>\n<view class=\"default {{ [ item.selected ? 'selected' : '',has ? 'has' : '' ] }}\"></view>\n<view class=\"default {{ [ (value >= 0 ? 'increase': 'decrease'); ] }}\"></view>\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/assert/bindStyle.wxml",
    "content": "<view style=\" {{ 'background:' + (current === idx ? activeColor : normalColor) + ';' }}\"></view>\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/assert/joinStyle.wxml",
    "content": "<view style=\"width: 100rpx; {{ 'background:' + (bgColor) + ';' }}\"></view>\n<view style=\"height: 200rpx; {{ 'font-size:' + (titleFontSize) + ';' }}\"></view>\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/assert/ref.wxml",
    "content": "<view id=\"ref-0-0\"></view>\n<view id=\"ref-0-1\"></view>\n<view id=\"hello\"></view>\n<view id=\"{{ hello }}\"></view>\n<custom-component-01 bind_init=\"__initComponent\" data-ref=\"myCom01\"></custom-component-01>\n<custom-component-02 bind_init=\"__initComponent\" data-ref=\"{{ myCom02 }}\"></custom-component-02>"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/assert/reference.wxml",
    "content": "<import src=\"item.wxml\" />\n<template is=\"item\" data=\"{{text: 'foobar'}}\" />\n<include src=\"header.wxml\" />\n<view> body </view>\n<include src=\"footer.wxml\" />\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/assert/v-for.wxml",
    "content": "<view wx:for=\"{{ items }}\" wx:for-index=\"index\" wx:for-item=\"item\" wx:key=\"index\"></view>\n<view wx:for=\"{{ items }}\" wx:for-index=\"index\" wx:for-item=\"item\" wx:key=\"index\"></view>\n<view wx:for=\"{{ object }}\" wx:for-index=\"key\" wx:for-item=\"value\" wx:key=\"index\"></view>\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/assert/v-if.wxml",
    "content": "<view wx:if=\"{{ case01 }}\"></view>\n<view wx:elif=\"{{ case02 }}\"></view>\n<view wx:else></view>\n<view wx:if=\"{{ a < 1 }}\"></view>\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/assert/v-on/0-0.tap.js",
    "content": "function proxy () {\n  var $wx = arguments[arguments.length - 1].$wx;\n  var $event = ($wx.detail && $wx.detail.arguments) ? $wx.detail.arguments[0] : arguments[arguments.length -1];\n  var $args = $wx.detail && $wx.detail.arguments;\n  var _vm=this;\n  return (function () {\n    _vm.myclick.apply(_vm, $args || [$event]);\n  })();\n}\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/assert/v-on/0-1.tap.js",
    "content": "function proxy () {\n  var $wx = arguments[arguments.length - 1].$wx;\n  var $event = ($wx.detail && $wx.detail.arguments) ? $wx.detail.arguments[0] : arguments[arguments.length -1];\n  var $args = $wx.detail && $wx.detail.arguments;\n  var _vm=this;\n  return (function () {\n    _vm.myclickStop.apply(_vm, $args || [$event]);\n  })();\n}\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/assert/v-on/0-10.tap.js",
    "content": "function proxy () {\n  var $wx = arguments[arguments.length - 1].$wx;\n  var $args = $wx.detail && $wx.detail.arguments;\n  var _vm = this;\n  return (function () {\n    _vm.myclick(1, $args);\n  })();\n}\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/assert/v-on/0-11.tap.js",
    "content": "function proxy () {\n  var $wx = arguments[arguments.length - 1].$wx;\n  var $event = ($wx.detail && $wx.detail.arguments) ? $wx.detail.arguments[0] : arguments[arguments.length - 1];\n  var _vm = this;\n  return (function () {\n    _vm.myclick(1, $event);\n  })();\n}\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/assert/v-on/0-12.tap.js",
    "content": "function proxy () {\n  var $wx = arguments[arguments.length - 1].$wx;\n  var _vm = this;\n  return (function () {\n    _vm.myclick(1, $wx);\n  })();\n}\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/assert/v-on/0-13.tap.js",
    "content": "function proxy () {\n  var $wx = arguments[arguments.length - 1].$wx;\n  var $event = ($wx.detail && $wx.detail.arguments) ? $wx.detail.arguments[0] : arguments[arguments.length - 1];\n  var $args = $wx.detail && $wx.detail.arguments;\n  var _vm = this;\n  return (function () {\n    _vm.myclick(1, $wx, $event, $args);\n  })();\n}\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/assert/v-on/0-14.tap.js",
    "content": "function proxy () {\n  var _vm = this;\n  return (function () {\n    _vm.myclick();\n  })();\n}\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/assert/v-on/0-15.tap.js",
    "content": "function proxy () {\n  var _vm = this;\n  return (function () {\n    _vm.myclick(1);\n  })();\n}\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/assert/v-on/0-2.tap.js",
    "content": "function proxy () {\n  var $wx = arguments[arguments.length - 1].$wx;\n  var $event = ($wx.detail && $wx.detail.arguments) ? $wx.detail.arguments[0] : arguments[arguments.length -1];\n  var $args = $wx.detail && $wx.detail.arguments;\n  var _vm=this;\n  return (function () {\n    _vm.myclickCapture.apply(_vm, $args || [$event]);\n  })();\n}\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/assert/v-on/0-3.tap.js",
    "content": "function proxy () {\n  var $wx = arguments[arguments.length - 1].$wx;\n  var $event = ($wx.detail && $wx.detail.arguments) ? $wx.detail.arguments[0] : arguments[arguments.length -1];\n  var $args = $wx.detail && $wx.detail.arguments;\n  var _vm=this;\n  return (function () {\n    _vm.myclickCaptureStop.apply(_vm, $args || [$event]);\n  })();\n}\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/assert/v-on/0-4.tap.js",
    "content": "function proxy () {\n  var _vm = this;\n  return (function () {\n    _vm.myClickCaptureStopWithParams(1, { a: 1 }, [1, 2]);\n  })();\n}\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/assert/v-on/0-5.tap.js",
    "content": "function proxy () {\n  var $wx = arguments[arguments.length - 1].$wx;\n  var $event = ($wx.detail && $wx.detail.arguments) ? $wx.detail.arguments[0] : arguments[arguments.length - 1];\n  var _vm = this;\n  return (function () {\n    _vm.myclick($event);\n  })();\n}\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/assert/v-on/0-6.tap.js",
    "content": "function proxy (item) {\n  var _vm = this;\n  return (function () {\n    _vm.myClickInFor(item);\n  })();\n}\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/assert/v-on/0-7.tap.js",
    "content": "function proxy () {\n  var $wx = arguments[arguments.length - 1].$wx;\n  var $event = ($wx.detail && $wx.detail.arguments) ? $wx.detail.arguments[0] : arguments[arguments.length - 1];\n  var $args = $wx.detail && $wx.detail.arguments;\n  var _vm = this;\n  return (function () {\n    _vm.handleCaptureBindTap.apply(_vm, $args || [$event]);\n  })();\n}\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/assert/v-on/0-8.tap.js",
    "content": "function proxy () {\n  var $wx = arguments[arguments.length - 1].$wx;\n  var $event = ($wx.detail && $wx.detail.arguments) ? $wx.detail.arguments[0] : arguments[arguments.length - 1];\n  var $args = $wx.detail && $wx.detail.arguments;\n  var _vm = this;\n  return (function () {\n    _vm.handleCaptureCatchTap.apply(_vm, $args || [$event]);\n  })();\n}\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/assert/v-on/0-9.click-right.js",
    "content": "function proxy () {\n  var $wx = arguments[arguments.length - 1].$wx;\n  var $event = ($wx.detail && $wx.detail.arguments) ? $wx.detail.arguments[0] : arguments[arguments.length - 1];\n  var $args = $wx.detail && $wx.detail.arguments;\n  var _vm = this;\n  return (function () {\n    _vm.rightNavbar.apply(_vm, $args || [$event]);\n  })();\n}\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/assert/v-on.wxml",
    "content": "<view data-wpy-evt=\"0-0\" bind:tap=\"__dispatcher\"></view>\n<view data-wpy-evt=\"0-1\" catch:tap=\"__dispatcher\"></view>\n<view data-wpy-evt=\"0-2\" capture-bind:tap=\"__dispatcher\"></view>\n<view data-wpy-evt=\"0-3\" capture-catch:tap=\"__dispatcher\"></view>\n<view data-wpy-evt=\"0-4\" capture-catch:tap=\"__dispatcher\"></view>\n\n<view data-wpy-evt=\"0-5\" bind:tap=\"__dispatcher\"></view>\n\n<view wx:for=\"{{ list }}\" wx:for-index=\"index\" wx:for-item=\"item\" wx:key=\"index\">\n  <button data-wpy-evt=\"0-6\" bind:tap=\"__dispatcher\" data-wpytap-a=\"{{ item }}\"></button>\n</view>\n\n<view data-wpy-evt=\"0-7\" capture-bind:tap=\"__dispatcher\"></view>\n<view data-wpy-evt=\"0-8\" capture-catch:tap=\"__dispatcher\"></view>\n\n<view data-wpy-evt=\"0-9\" bind:click-right=\"__dispatcher\"></view>\n\n<view data-wpy-evt=\"0-10\" bind:tap=\"__dispatcher\"></view>\n<view data-wpy-evt=\"0-11\" bind:tap=\"__dispatcher\"></view>\n<view data-wpy-evt=\"0-12\" bind:tap=\"__dispatcher\"></view>\n<view data-wpy-evt=\"0-13\" bind:tap=\"__dispatcher\"></view>\n<view data-wpy-evt=\"0-14\" bind:tap=\"__dispatcher\"></view>\n<view data-wpy-evt=\"0-15\" bind:tap=\"__dispatcher\"></view>\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/assert/v-on.wxs.wxml",
    "content": "<view bind:tap=\"{{ m.touchmove }}\"></view>\n<view data-wpy-evt=\"0-0\" bind:tap=\"__dispatcher\"></view>\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/assert/v-show.wxml",
    "content": "<view hidden=\"{{ !(show) }}\"></view>\n<view hidden=\"{{ !(case01 && case02) }}\"></view>\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/original/attrWithoutValue.html",
    "content": "<div hidden></div>\n<scroll-view scroll-x></scroll-view>\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/original/bindClass.html",
    "content": "<div class=\"default\" :class=\"{'test': express - 1 === 0, 'has': has}\"></div>\n<div :class=\"[ something, { 'test': test, 'has': has } ]\"></div>\n<div class=\"default\" :class=\"{selected: item.selected, 'has': has}\"></div>\n<div class=\"default\" :class=\"value >= 0 ? 'increase': 'decrease'\"></div>\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/original/bindStyle.html",
    "content": "<div :style=\"{ 'background': current === idx ? activeColor : normalColor }\"></div>\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/original/joinStyle.html",
    "content": "<div style=\"width: 100rpx\" :style=\"{ 'background': bgColor }\"></div>\n<div style=\"height: 200rpx;\" :style=\"{ 'font-size': titleFontSize }\"></div>\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/original/ref.html",
    "content": "<div :ref=\"value01\"></div>\n<div :ref=\"value02\"></div>\n<div id=\"hello\" :ref=\"value03\"></div>\n<div :id=\"hello\" :ref=\"value04\"></div>\n<custom-component-01 ref=\"myCom01\" ></custom-component-01>\n<custom-component-02 :ref=\"myCom02\"></custom-component-02>"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/original/reference.html",
    "content": "<import src=\"item.wxml\" />\n<template is=\"item\" data=\"{{text: 'foobar'}}\" />\n<include src=\"header.wxml\" />\n<view> body </view>\n<include src=\"footer.wxml\" />\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/original/v-for.html",
    "content": "<view v-for=\"items\"></view>\n<view v-for=\"(item, index) in items\"></view>\n<view v-for=\"(value, key, index) in object\"></view>\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/original/v-if.html",
    "content": "<view v-if=\"case01\"></view>\n<view v-else-if=\"case02\"></view>\n<view v-else></view>\n<view v-if=\"a &lt; 1\"></view>\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/original/v-on.html",
    "content": "<div @tap=\"myclick\"></div>\n<div @tap.stop=\"myclickStop\"></div>\n<div @tap.capture=\"myclickCapture\"></div>\n<div @tap.stop.capture=\"myclickCaptureStop\"></div>\n<div @tap.capture.stop=\"myClickCaptureStopWithParams(1, {a: 1}, [1, 2])\"></div>\n\n<div @tap=\"myclick($event)\"></div>\n\n<div v-for=\"(item, index) in list\">\n  <button @tap=\"myClickInFor(item)\"></button>\n</div>\n\n<div capture-bind:tap=\"handleCaptureBindTap\"></div>\n<div capture-catch:tap=\"handleCaptureCatchTap\"></div>\n\n<div @click-right=\"rightNavbar\"></div>\n\n<div @tap=\"myclick(1, arguments)\"></div>\n<div @tap=\"myclick(1, $event)\"></div>\n<div @tap=\"myclick(1, $wx)\"></div>\n<div @tap=\"myclick(1, $wx, $event, arguments)\"></div>\n<div @tap=\"myclick()\"></div>\n<div @tap=\"myclick(1)\"></div>\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/original/v-on.wxs.html",
    "content": "<div @tap=\"m.touchmove\"></div>\n<div @tap=\"m1.touchmove\"></div>\n"
  },
  {
    "path": "packages/cli/test/core/fixtures/template/original/v-show.html",
    "content": "<view v-show=\"show\"></view>\n<view v-show=\"case01 && case02\"></view>\n"
  },
  {
    "path": "packages/cli/test/core/hook.test.js",
    "content": "const expect = require('chai').expect;\nconst Hook = require('../../core/hook');\n\ndescribe('Hook', function() {\n  it('should register', function() {\n    const hook = new Hook();\n    const handler = function() {};\n    hook.register('process-test', handler);\n\n    expect(hook._hooks).to.have.a.property('process-test');\n    expect(hook._hooks['process-test']).to.be.a('array');\n    expect(hook._hooks['process-test']).to.includes(handler);\n  });\n\n  it('should unregister', function() {\n    const hook = new Hook();\n    const handler1 = function() {};\n    const handler2 = function() {};\n\n    const unregisterHandler1 = hook.register('process-test', handler1);\n    hook.register('process-test', handler2);\n    expect(hook._hooks['process-test']).to.includes(handler1);\n    expect(hook._hooks['process-test']).to.includes(handler2);\n\n    unregisterHandler1();\n    expect(hook._hooks['process-test']).to.not.includes(handler1);\n    expect(hook._hooks['process-test']).to.includes(handler2);\n\n    hook.unregisterAll('process-test');\n    expect(hook._hooks['process-test']).to.be.an('undefined');\n  });\n\n  it('should has hook', function() {\n    const hook = new Hook();\n    const handler = function() {};\n    hook.register('process-test', handler);\n\n    expect(hook.hasHook('process-test')).to.be.true;\n    expect(hook.hasHook('process-another')).to.be.false;\n  });\n\n  it('should hook', function() {\n    const hook = new Hook();\n    hook.register('process-test', function() {\n      return 1;\n    });\n\n    expect(hook.hook('process-test')).to.eql([1]);\n\n    hook.register('process-test', function(a) {\n      return a;\n    });\n    expect(hook.hook('process-test', 6)).to.eql([1, 6]);\n\n    hook.register('process-test', function(a, b) {\n      return a + b;\n    });\n    expect(hook.hook('process-test', 6, 66)).to.eql([1, 6, 72]);\n  });\n\n  it('should hookSeq', function() {\n    const hook = new Hook();\n\n    expect(hook.hookSeq('unknown')).to.be.undefined;\n    expect(hook.hookSeq('unknown', 1)).to.equal(1);\n    expect(hook.hookSeq('unknown', 1, 2)).to.eql([1, 2]);\n\n    hook.register('process-test', function(a) {\n      return a + 1;\n    });\n    expect(hook.hookSeq('process-test', 6)).to.equal(7);\n\n    hook.register('process-test', function(b) {\n      return b * 2;\n    });\n    expect(hook.hookSeq('process-test', 6)).to.equal(14);\n  });\n\n  it('should hookUnique', function() {\n    const hook = new Hook();\n\n    expect(hook.hookUnique('unknown')).to.be.undefined;\n\n    hook.register('process-test', function(a) {\n      return a + 1;\n    });\n    expect(hook.hookUnique('process-test', 6)).to.equal(7);\n\n    hook.register('process-test', function(a) {\n      return a * 2;\n    });\n    expect(hook.hookUnique('process-test', 6)).to.equal(12);\n  });\n\n  it('should hookUniqueReturnArg', function() {\n    const hook = new Hook();\n\n    expect(hook.hookUniqueReturnArg('unknown')).to.be.undefined;\n    expect(hook.hookUniqueReturnArg('unknown', 666)).to.equal(666);\n\n    hook.register('process-test', function(a) {\n      return a + 1;\n    });\n    expect(hook.hookUniqueReturnArg('process-test', 6)).to.equal(7);\n\n    hook.register('process-test', function(a) {\n      return a * 2;\n    });\n    expect(hook.hookUniqueReturnArg('process-test', 6)).to.equal(12);\n  });\n\n  it('should hookReturnOrigin', function() {\n    const hook = new Hook();\n    let oneFnCalled = false;\n    let twoFnCalled = false;\n\n    expect(hook.hookReturnOrigin('unknown', 6)).to.equal(6);\n    expect(hook.hookReturnOrigin('unknown', 6, 66)).to.eql([6, 66]);\n\n    hook.register('process-test', function() {\n      oneFnCalled = true;\n    });\n\n    expect(hook.hookReturnOrigin('process-test', 66)).to.equal(66);\n    expect(oneFnCalled).to.be.true;\n\n    hook.register('process-test', function() {\n      twoFnCalled = true;\n    });\n    expect(hook.hookReturnOrigin('process-test', 666)).to.equal(666);\n    expect(twoFnCalled).to.be.true;\n\n    oneFnCalled = false;\n    twoFnCalled = false;\n    expect(hook.hookReturnOrigin('process-test', 66, 666)).to.eql([66, 666]);\n    expect(oneFnCalled).to.be.true;\n    expect(twoFnCalled).to.be.true;\n  });\n\n  it('hookAsyncSeq should call then correctly', function() {\n    const hook = new Hook();\n\n    return hook\n      .hookAsyncSeq('unknown', 6)\n      .then(rst => {\n        // should return args[0]\n        expect(rst).to.equal(6);\n\n        return hook.hookAsyncSeq('unknown', 6, 66);\n      })\n      .then(rst => {\n        // should return args\n        expect(rst).to.eql([6, 66]);\n\n        hook.register('process-test', function(obj) {\n          return { count: obj.count + 1 };\n        });\n        return hook.hookAsyncSeq('process-test', { count: 6 });\n      })\n      .then(rst => {\n        // should return lastRst for one hook fn\n        expect(rst).to.eql({ count: 7 });\n\n        hook.register('process-test', function(obj) {\n          return new Promise(function(resolve) {\n            resolve({ count: obj.count + 1 });\n          });\n        });\n        return hook.hookAsyncSeq('process-test', { count: 6 });\n      })\n      .then(rst => {\n        // should return lastRst for multiple hook fns\n        expect(rst).to.eql({ count: 8 });\n\n        hook.register('process-test', function(obj) {\n          return new Promise(function(resolve) {\n            resolve({ ...obj, text: 'hello, world!' });\n          });\n        });\n        return hook.hookAsyncSeq('process-test', { count: 66 });\n      })\n      .then(rst => {\n        // should return lastRst\n        expect(rst).to.eql({ count: 68, text: 'hello, world!' });\n\n        hook.register('process-test', function(obj) {\n          return new Promise(function(resolve) {\n            resolve([obj, { more: true }]);\n          });\n        });\n        hook.register('process-test', function(obj, extra) {\n          return new Promise(function(resolve) {\n            expect(extra).to.eql({ more: true });\n            resolve([obj, extra]);\n          });\n        });\n        return hook.hookAsyncSeq('process-test', { count: 666 });\n      })\n      .then(rst => {\n        // should return lastRst[0] if args.length === 1\n        expect(rst).to.eql({ count: 668, text: 'hello, world!' });\n\n        return hook.hookAsyncSeq('process-test', { count: 6666 }, { more: false });\n      })\n      .then(rst => {\n        // should return lastRst if args.length > 1\n        expect(rst).to.eql([{ count: 6668, text: 'hello, world!' }, { more: true }]);\n      });\n  });\n\n  it('hookAsyncSeq should call catch', function(done) {\n    const hook = new Hook();\n\n    hook.register('process-test', function() {\n      return new Promise(function(resolve, reject) {\n        reject({ text: 'hi, rejected!' });\n      });\n    });\n    hook.hookAsyncSeq('process-test', { n: 6 }).catch(err => {\n      expect(err).to.eql({ text: 'hi, rejected!' });\n      done();\n    });\n  });\n\n  it('hookAsyncSeq should not call then but catch', function(done) {\n    const hook = new Hook();\n\n    hook.register('process-test', function(obj) {\n      return { n: obj.n + 1 };\n    });\n    hook.register('process-test', function() {\n      return new Promise(function(resolve, reject) {\n        reject({ text: 'hi, rejected!' });\n      });\n    });\n    hook.register('process-test', function(obj) {\n      return { n: obj.n + 2 };\n    });\n    hook\n      .hookAsyncSeq('process-test', { n: 66 })\n      .then(() => {\n        throw new Error('it will not happen!');\n      })\n      .catch(err => {\n        expect(err).to.eql({ text: 'hi, rejected!' });\n        done();\n      });\n  });\n});\n"
  },
  {
    "path": "packages/cli/test/core/init/plugin.test.js",
    "content": "const { alias } = require('../../config');\nconst expect = require('chai').expect;\nconst initPlugin = require(`${alias.init}/plugin`);\nconst Hook = require(`${alias.core}/hook`);\n\nconst specs = {\n  normal: {\n    called: false,\n    plugins: [\n      () => {\n        specs.normal.called = true;\n      }\n    ]\n  },\n  single: {\n    called: false,\n    plugins: () => {\n      specs.single.called = true;\n    }\n  },\n  validArr: {\n    type: 'error',\n    plugins: {},\n    error: 'EXIT'\n  },\n  validSingle: {\n    type: 'error',\n    plugins: {},\n    error: 'EXIT'\n  }\n};\n\nconst createCompile = plugins => {\n  const compile = new Hook();\n\n  compile.options = { plugins };\n\n  compile.logger = {\n    error() {}\n  };\n\n  initPlugin(compile);\n};\n\nconst compare = (name, done) => {\n  const spec = specs[name];\n\n  if (spec.type === 'error') {\n    expect(() => createCompile(spec.plugins)).to.throw(spec.error);\n    done();\n  } else {\n    createCompile(spec.plugins);\n\n    expect(spec.called).to.be.true;\n    done();\n  }\n};\n\ndescribe('init plugin', function() {\n  Object.keys(specs).forEach(key => {\n    it(`test ${key} plugin`, done => {\n      compare(key, done);\n    });\n  });\n});\n"
  },
  {
    "path": "packages/cli/test/core/parseOption.test.js",
    "content": "const expect = require('chai').expect;\nconst po = require('../../core/parseOptions');\n\ndescribe('parseOptions', function() {\n  it('getValue', function() {\n    expect(po.getValue({}, 'a.b.c')).to.equal(undefined);\n\n    expect(po.getValue({ a: 1 }, 'a')).to.equal(1);\n\n    expect(po.getValue({ a: { b: { c: 2 } } }, 'a.b')).to.deep.equal({ c: 2 });\n  });\n\n  it('setValue', function() {\n    expect(po.setValue({}, 'a.b.c', 1)).to.deep.equal({ a: { b: { c: 1 } } });\n\n    expect(po.setValue({ a: {}, a2: 2 }, 'a.b.c', 1)).to.deep.equal({ a: { b: { c: 1 } }, a2: 2 });\n\n    expect(po.setValue({ a: { b: 3 }, a2: 2 }, 'a.b.c', 1)).to.deep.equal({ a: { b: { c: 1 } }, a2: 2 });\n\n    expect(po.setValue({ a: { b: { c: 2, d: 3 } }, a2: 2 }, 'a.b.c', 1)).to.deep.equal({\n      a: { b: { c: 1, d: 3 } },\n      a2: 2\n    });\n  });\n\n  it('parse', function() {\n    expect(po.parse().wpyExt).to.equal('.wpy');\n\n    expect(po.parse({ wpyExt: '.vue' }).wpyExt).to.equal('.vue');\n\n    expect(po.parse({ build: { web: { resolve: { a: 1 } } } }).build.web.resolve.a).to.equal(1);\n\n    expect(\n      po.parse({ watchOption: { awaitWriteFinish: { stabilityThreshold: 1000 } } }).watchOption.awaitWriteFinish\n        .stabilityThreshold\n    ).to.equal(1000);\n  });\n});\n"
  },
  {
    "path": "packages/cli/test/core/plugins/helper/sfcCustomBlock.test.js",
    "content": "const { alias } = require('../../../config');\nconst sfcCompiler = require('vue-template-compiler');\nconst Hook = require(`${alias.core}/hook`);\nconst initPlugin = require(`${alias.core}/init/plugin`);\n\nconst expect = require('chai').expect;\n\nfunction createCompile() {\n  const hook = new Hook();\n  hook.options = { plugins: [] };\n  initPlugin(hook);\n\n  return hook;\n}\n\ndescribe('sfcCustomBlock', function() {\n  const compiler = createCompile();\n\n  it('test default lang', function() {\n    const sfc = sfcCompiler.parseComponent(\n      `\n      <config></config>\n      <wxs></wxs>\n    `,\n      { pad: 'space' }\n    );\n\n    const parsedSfc = compiler.hookSeq('sfc-custom-block', sfc);\n\n    expect(parsedSfc).to.have.a.property('config');\n    expect(parsedSfc).to.have.a.property('wxs');\n    expect(parsedSfc.config.lang).to.equal('json');\n    expect(parsedSfc.wxs).to.be.an.instanceof(Array);\n  });\n\n  it('test custom lang', function() {\n    const sfc = sfcCompiler.parseComponent(\n      `\n      <config lang=\"customLang1\"></config>\n      <wxs lang=\"customLang2\"></wxs>\n      <wxs></wxs>\n    `,\n      { pad: 'space' }\n    );\n\n    const parsedSfc = compiler.hookSeq('sfc-custom-block', sfc);\n\n    expect(parsedSfc).to.have.a.property('config');\n    expect(parsedSfc).to.have.a.property('wxs');\n    expect(parsedSfc.config.lang).to.equal('customLang1');\n    expect(parsedSfc.wxs).to.have.lengthOf(2);\n    expect(parsedSfc.wxs.some(_ => _.lang === 'customLang2')).to.be.true;\n  });\n});\n"
  },
  {
    "path": "packages/cli/test/core/plugins/template/parse.test.js",
    "content": "const { alias } = require('../../../config');\nconst expect = require('chai').expect;\nconst path = require('path');\nconst fs = require('fs-extra');\nconst Hook = require(`${alias.core}/hook`);\nconst tag = require(`${alias.core}/tag`);\nconst initPlugin = require(`${alias.core}/init/plugin`);\nconst moduleSet = require(`${alias.core}/moduleSet`);\n\nfunction cached(fn) {\n  var _cache = {};\n  return function(key) {\n    if (!_cache[key]) {\n      _cache[key] = fn(key);\n    }\n    return _cache[key];\n  };\n}\n\nconst getRaw = cached(function(file) {\n  const original = path.join(__dirname, '..', '..', 'fixtures/template/original', file + '.html');\n  const assert = path.join(__dirname, '..', '..', 'fixtures/template/assert', file + '.wxml');\n\n  return {\n    originalRaw: fs.readFileSync(original, 'utf-8'),\n    assertRaw: fs.readFileSync(assert, 'utf-8')\n  };\n});\n\nconst spec = {\n  attr: [\n    { file: 'v-if' },\n    { file: 'v-for' },\n    { file: 'v-show' },\n    { file: 'bindClass' },\n    { file: 'joinStyle' },\n    { file: 'attrWithoutValue' },\n    { file: 'reference' },\n    {\n      file: 'ref',\n      component: {\n        'custom-component-01': '~@/component/custom-component-01',\n        'custom-component-02': '~@/component/custom-component-02'\n      }\n    }\n  ],\n  event: [\n    {\n      file: 'v-on',\n      sfc: {\n        wxs: [],\n        template: { content: getRaw('v-on').originalRaw, code: getRaw('v-on').assertRaw }\n      }\n    },\n    {\n      file: 'v-on.wxs',\n      sfc: {\n        wxs: [{ attrs: { module: 'm' } }],\n        template: { content: getRaw('v-on.wxs').originalRaw, code: getRaw('v-on.wxs').assertRaw }\n      }\n    }\n  ],\n  directives: ['v-model']\n};\n\nfunction createLogger(type) {\n  return function(...args) {\n    // mute silly and info\n    if (type === 'silly' || type === 'info') {\n      return;\n    }\n    /* eslint-disable no-console */\n    console.log('==== This is ' + type + ' log===');\n    console.log(...args);\n    /* eslint-enable no-console */\n  };\n}\n\nfunction createCompiler(options = {}) {\n  const instance = new Hook();\n  const appConfig = options.appConfig || {};\n  const userDefinedTags = appConfig.tags || {};\n  instance.options = { plugins: [] };\n\n  instance.logger = {\n    info: createLogger('info'),\n    warn: createLogger('warn'),\n    error: createLogger('error'),\n    silly: createLogger('silly')\n  };\n  instance.tags = {\n    htmlTags: tag.combineTag(tag.HTML_TAGS, userDefinedTags.htmlTags),\n    wxmlTags: tag.combineTag(tag.WXML_TAGS, userDefinedTags.wxmlTags),\n    html2wxmlMap: tag.combineTagMap(tag.HTML2WXML_MAP, userDefinedTags.html2wxmlMap),\n    selfCloseTags: tag.SELF_CLOSE_TAGS\n  };\n  initPlugin(instance);\n\n  instance.assets = new moduleSet();\n  return instance;\n}\n\nfunction assetHanlder(handlers) {\n  for (let id in handlers) {\n    for (let type in handlers[id]) {\n      const func = handlers[id][type];\n      const funcfile = path.join(__dirname, '..', '..', 'fixtures/template/assert/v-on/', id + '.' + type + '.js');\n      const fixture = fs.readFileSync(funcfile, 'utf-8');\n\n      try {\n        expect(func.replace(/\\s*/gi, '').replace(/\\n*/gi, '')).to.equal(\n          fixture.replace(/\\s*/gi, '').replace(/\\n*/gi, '')\n        );\n      } catch (e) {\n        /* eslint-disable no-console */\n        console.log('Compiled Handler: ' + id + '.' + type + '.js');\n        console.log(func);\n        /* eslint-enable no-console */\n        throw e;\n      }\n    }\n  }\n}\n\nfunction assertCodegen(originalRaw, assertRaw, options = {}, ctx, done) {\n  const compiler = createCompiler(options);\n  compiler.assets.add(ctx.file);\n  compiler\n    .hookUnique('template-parse', originalRaw, options.component || {}, ctx)\n    .then(rst => {\n      expect(rst.code).to.equal(assertRaw);\n      if (ctx.file === 'v-on') {\n        assetHanlder(rst.rel.handlers);\n      }\n      done();\n    })\n    .catch(err => {\n      done(err);\n      // throw err;\n    });\n}\n\ndescribe('template-parse', function() {\n  spec.attr.forEach(ctx => {\n    it('test attr: ' + ctx.file, function(done) {\n      const { originalRaw, assertRaw } = getRaw(ctx.file);\n      assertCodegen(originalRaw, assertRaw, ctx, ctx, done);\n    });\n  });\n\n  spec.event.forEach(ctx => {\n    it('test attr: ' + ctx.file, function(done) {\n      const { originalRaw, assertRaw } = getRaw(ctx.file);\n      assertCodegen(originalRaw, assertRaw, ctx, ctx, done);\n    });\n  });\n});\n"
  },
  {
    "path": "packages/cli/test/core/tag.test.js",
    "content": "const expect = require('chai').expect;\nconst tag = require('../../core/tag');\n\ndescribe('tag', function() {\n  it('should combineTagMap', function() {\n    const additional = {\n      'test-tag-1': 'to-test-tag-1',\n      'test-tag-2': 'to-test-tag-2'\n    };\n    const ret = tag.combineTagMap(tag.HTML2WXML_MAP, additional);\n\n    expect(ret).to.include(tag.HTML2WXML_MAP);\n    expect(ret).to.include(additional);\n  });\n\n  it('should combineTag', function() {\n    let additional = 'add-test-tag-1';\n    let ret = tag.combineTag(tag.HTML_TAGS, additional);\n    expect(ret).to.include.members(tag.HTML_TAGS);\n    expect(ret).to.include(additional);\n\n    additional = 'add-test-tag-1,add-test-tag-2';\n    ret = tag.combineTag(tag.HTML_TAGS, additional);\n    expect(ret).to.include.members(tag.HTML_TAGS);\n    expect(ret).to.include.members(additional.split(','));\n\n    additional = ['add-test-tag-1', 'add-test-tag-2'];\n    ret = tag.combineTag(tag.HTML_TAGS, additional);\n    expect(ret).to.include.members(tag.HTML_TAGS);\n    expect(ret).to.include.members(additional);\n\n    additional = 123;\n    ret = tag.combineTag(tag.HTML_TAGS, additional);\n    expect(ret).to.eql(tag.HTML_TAGS);\n  });\n});\n"
  },
  {
    "path": "packages/cli/util/logger.js",
    "content": "const log = require('npmlog');\n\nconst mylog = {};\n\nconst datetime = (date = new Date(), format = 'HH:mm:ss') => {\n  let fn = d => {\n    return ('0' + d).slice(-2);\n  };\n  if (date && typeof date === 'string') {\n    date = new Date(Date.parse(date));\n  }\n  const formats = {\n    YYYY: date.getFullYear(),\n    MM: fn(date.getMonth() + 1),\n    DD: fn(date.getDate()),\n    HH: fn(date.getHours()),\n    mm: fn(date.getMinutes()),\n    ss: fn(date.getSeconds())\n  };\n  return format.replace(/([a-z])\\1+/gi, function(a) {\n    return formats[a] || a;\n  });\n};\n\n['info', 'silly', 'verbose', 'http', 'timing', 'notice', 'silent', 'warn', 'error'].forEach(v => {\n  mylog[v] = (...args) => {\n    log.heading = '[' + datetime() + ']';\n    if (args.length === 1) {\n      args = [''].concat(args);\n    }\n    if (log.level !== 'trace') {\n      args.forEach(\n        (arg, i) =>\n          typeof arg === 'object' && arg instanceof Error && arg.stack && arg.message && (args[i] = arg.message)\n      );\n    }\n    log.log.apply(log, [v].concat(args));\n  };\n});\n\nmylog.level = v => (v ? (log.level = v) : log.level);\n\nexports = module.exports = mylog;\n"
  },
  {
    "path": "packages/compiler-babel/.npmignore",
    "content": "src\ntest\nnode_modules"
  },
  {
    "path": "packages/compiler-babel/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n# 2.1.0 (2020-07-04)\n\n**Note:** Version bump only for package @wepy/compiler-babel\n\n\n\n\n\n# 2.1.0-alpha.10 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-babel\n\n\n\n\n\n# 2.1.0-alpha.9 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-babel\n\n\n\n\n\n# 2.1.0-alpha.8 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-babel\n\n\n\n\n\n# 2.1.0-alpha.7 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-babel\n\n\n\n\n\n# 2.1.0-alpha.6 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-babel\n\n\n\n\n\n# 2.1.0-alpha.5 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-babel\n\n\n\n\n\n# [2.1.0-alpha.4](https://github.com/Tencent/wepy/compare/v2.1.0-alpha.2...v2.1.0-alpha.4) (2020-06-20)\n\n**Note:** Version bump only for package @wepy/compiler-babel\n"
  },
  {
    "path": "packages/compiler-babel/README.md",
    "content": "# wepy babel 编译器\n\n## 安装\n\n```\nnpm install @wepy/compiler-babel --save-dev\n```\n\n## 配置`wepy.config.js`\n\n```\nmodule.exports = {\n    \"compilers\": {\n        babel: {\n            'presets': [\n                'es2015',\n                'stage-1'\n            ],\n            'plugins': [\n                'transform-export-extensions',\n                'syntax-export-extensions',\n                'transform-runtime'\n            ]\n        }\n    }\n};\n```\n\n## 参数说明\n\n[Babel](https://github.com/babel/babel)"
  },
  {
    "path": "packages/compiler-babel/index.js",
    "content": "/**\n * Tencent is pleased to support the open source community by making WePY available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n *\n * Licensed under the MIT License (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n * http://opensource.org/licenses/MIT\n * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n */\n\nconst babel = require('@babel/core');\nconst path = require('path');\n\nexports = module.exports = function(options) {\n  return function() {\n    this.register('wepy-compiler-babel', function(node, ctx) {\n      let p;\n      const file = typeof ctx === 'string' ? ctx : ctx.file;\n      const outputFileName = path.basename(file, path.extname(file)) + '.js';\n      const scriptFile = node.src ? path.resolve(path.basename(file), node.src) : file;\n      try {\n        let compiled = babel.transformSync(node.content, { filename: scriptFile, ...options });\n        node.compiled = compiled;\n        if (path.extname(scriptFile) === '.ts') {\n          compiled.outputFileName = outputFileName;\n        }\n        p = Promise.resolve(node);\n      } catch (e) {\n        this.hookUnique('error-handler', {\n          type: 'error',\n          title: 'babel',\n          file: scriptFile,\n          message: e.message,\n          snapshot: e.codeFrame\n        });\n        p = Promise.reject(e);\n      }\n      return p;\n    });\n\n    /*  There are two format for the bable compilation\n     *  1. var _core = _interopRequireDefault(require(\"@wepy/core\"));\n     *\n     *  2. var core = require(\"@wepy/core\");\n     *     var _core2 = _interopRequireDefault(core);\n     */\n\n    // eslint-disable-next-line\n    this.register('prewalk-VariableDeclarator', function(walker, declarator, name, decl) {\n      if (walker.lang !== 'babel') return;\n\n      if (declarator.init && declarator.init.type === 'CallExpression') {\n        if (declarator.init.callee.name === 'require') {\n          const arg = declarator.init.arguments[0];\n          if (arg && arg.type === 'Literal' && arg.value === '@wepy/core') {\n            walker.scope.instances.push(declarator.id.name);\n          }\n        } else if (declarator.init.callee.name === '_interopRequireDefault') {\n          const arg = declarator.init.arguments[0];\n          if (\n            arg &&\n            arg.type === 'CallExpression' &&\n            arg.callee.name === 'require' &&\n            arg.arguments[0].value === '@wepy/core'\n          ) {\n            // var _core = _interopRequireDefault(require('@wepy/core'));\n            walker.scope.instances.push(name);\n          } else if (arg && arg.type === 'Identifier' && walker.scope.instances.indexOf(arg.name) > -1) {\n            // var core2 = _interopRequireDefault(core);\n            walker.scope.instances.push(name);\n          }\n        }\n      }\n    });\n\n    this.register('walker-detect-entry', function(walker, expression, exprName) {\n      if (walker.lang !== 'babel') return;\n      if (walker.scope.instances && walker.scope.instances.length && exprName) {\n        if (exprName.callee === 'app' || exprName.callee === 'page' || exprName.callee === 'component') {\n          if (walker.scope.instances.some(item => item + '.default' === exprName.instance)) {\n            walker.entry = expression;\n          }\n        }\n      }\n    });\n  };\n};\n"
  },
  {
    "path": "packages/compiler-babel/package.json",
    "content": "{\n  \"name\": \"@wepy/compiler-babel\",\n  \"version\": \"2.1.0\",\n  \"description\": \"wepy compile babel\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"mocha ./test/*.test.js\"\n  },\n  \"keywords\": [\n    \"babel\"\n  ],\n  \"author\": {\n    \"name\": \"Gcaufy\"\n  },\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"@babel/core\": \"^7.1.0\"\n  },\n  \"readme\": \"ERROR: No README data found!\",\n  \"_id\": \"@wepy/compiler-babel@2.0.5\",\n  \"_commitid\": \"e4c7adb\",\n  \"devDependencies\": {\n    \"acorn\": \"^5.4.1\",\n    \"acorn-dynamic-import\": \"^3.0.0\",\n    \"acorn-walk\": \"^7.1.1\",\n    \"babel-preset-env\": \"^1.7.0\"\n  },\n  \"gitHead\": \"5a25776457360bbbbc54a4d059f6bc7c032d5df3\"\n}\n"
  },
  {
    "path": "packages/compiler-babel/test/fixtures/app.js",
    "content": "import wepy from '@wepy/core'\n\nwepy.app({\n  onLaunch() {\n    console.log('on launch')\n  }\n});\n\n"
  },
  {
    "path": "packages/compiler-babel/test/helper/ast.js",
    "content": "const acorn = require('acorn-dynamic-import').default;\n\nconst ECMA_VERSION = 2017;\n\nconst POSSIBLE_AST_OPTIONS = [\n  {\n    ranges: true,\n    locations: true,\n    ecmaVersion: ECMA_VERSION,\n    sourceType: 'module',\n    plugins: {\n      dynamicImport: true\n    }\n  },\n  {\n    ranges: true,\n    locations: true,\n    ecmaVersion: ECMA_VERSION,\n    sourceType: 'script',\n    plugins: {\n      dynamicImport: true\n    }\n  }\n];\n\nexports = module.exports = function ast(source) {\n  let ast;\n  const comments = [];\n  for (let i = 0, len = POSSIBLE_AST_OPTIONS.length; i < len; i++) {\n    if (!ast) {\n      try {\n        comments.length = 0;\n        POSSIBLE_AST_OPTIONS[i].onComment = comments;\n        ast = acorn.parse(source, POSSIBLE_AST_OPTIONS[i]);\n      } catch (e) {\n        // ignore the error\n      }\n    }\n  }\n\n  if (!ast) {\n    ast = acorn.parse(source, {\n      ranges: true,\n      locations: true,\n      ecmaVersion: ECMA_VERSION,\n      sourceType: 'module',\n      plugins: {\n        dynamicImport: true\n      },\n      onComment: comments\n    });\n  }\n\n  if (!ast || typeof ast !== 'object') {\n    throw new Error(`Source could't be parsed`);\n  }\n  return ast;\n};\n"
  },
  {
    "path": "packages/compiler-babel/test/helper/index.js",
    "content": "exports = module.exports = {\n  getNameForExpression(expression) {\n    let expr = expression;\n    const exprName = [];\n    while (expr.type === 'MemberExpression' && expr.property.type === (expr.computed ? 'Literal' : 'Identifier')) {\n      exprName.push(expr.computed ? expr.property.value : expr.property.name);\n      expr = expr.object;\n    }\n    let free;\n    if (expr.type === 'Identifier') {\n      free = this.scope.definitions.indexOf(expr.name) === -1;\n      exprName.push(this.scope.renames['$' + expr.name] || expr.name);\n    } else if (expr.type === 'ThisExpression' && this.scope.renames.$this) {\n      free = true;\n      exprName.push(this.scope.renames.$this);\n    } else if (expr.type === 'ThisExpression') {\n      free = false;\n      exprName.push('this');\n    } else {\n      return null;\n    }\n    let prefix = '';\n    for (let i = exprName.length - 1; i >= 1; i--) prefix += exprName[i] + '.';\n    const name = prefix + exprName[0];\n    const nameGeneral = prefix + '*';\n    return {\n      name,\n      nameGeneral,\n      instance: prefix.substring(0, prefix.length - 1),\n      callee: exprName[0],\n      free\n    };\n  }\n};\n"
  },
  {
    "path": "packages/compiler-babel/test/index.test.js",
    "content": "const fs = require('fs');\nconst path = require('path');\nconst expect = require('chai').expect;\nconst compileBabel = require('../index');\nconst helper = require('./helper/index');\nconst ast = require('./helper/ast');\nconst walk = require('acorn-walk');\n\nclass Hook {\n  constructor() {\n    this._hooks = {};\n  }\n\n  register(key, fn) {\n    if (!this._hooks[key]) {\n      this._hooks[key] = [];\n    }\n    this._hooks[key].push(fn);\n  }\n  hook(key, ...args) {\n    return this._hooks[key].apply(this, args);\n  }\n  hookUnique(key, ...args) {\n    let fns = this._hooks[key] || [];\n    let lastFn = fns[fns.length - 1];\n\n    if (typeof lastFn === 'function') {\n      return lastFn.apply(this, args);\n    }\n  }\n  clear() {\n    this._hooks = {};\n  }\n}\n\nfunction createWalker() {\n  return {\n    lang: 'babel',\n    scope: {\n      instances: [],\n      definitions: [],\n      renames: {}\n    }\n  };\n}\n\nfunction createCompile(opt) {\n  let instance = new Hook();\n  compileBabel(opt || {}).call(instance);\n\n  instance.logger = {\n    error(e) {\n      /* eslint-disable no-console */\n      console.log('======= ERROR OUTPUT ======');\n      console.log(e);\n      /* eslint-enable no-console */\n    }\n  };\n  instance.register('error-handler', function(err) {\n    /* eslint-disable no-console */\n    console.error(err);\n    /* eslint-enable no-console */\n  });\n  return instance;\n}\n\nfunction testFixture(file) {\n  const compiler = createCompile({\n    presets: ['env']\n  });\n\n  const walker = createWalker();\n\n  const code = fs.readFileSync(path.join(__dirname, './fixtures/', file));\n\n  return compiler\n    .hookUnique(\n      'wepy-compiler-babel',\n      {\n        src: './src',\n        content: code\n      },\n      { file: file }\n    )\n    .then(rst => {\n      const data = ast(rst.compiled.code);\n\n      walk.simple(data, {\n        VariableDeclarator(node) {\n          compiler.hookUnique('prewalk-' + node.type, walker, node, node.id.name, node.id);\n        },\n        ExpressionStatement(node) {\n          const expression = node.expression;\n          if (expression.callee && expression.callee.type === 'MemberExpression') {\n            const exprName = helper.getNameForExpression.call(walker, expression.callee);\n            compiler.hookUnique('walker-detect-entry', walker, expression, exprName);\n          }\n        }\n      });\n      return walker;\n    });\n}\n\ndescribe('@wepy/compiler-babel', function() {\n  it('Find entry', function() {\n    return testFixture('app.js')\n      .then(walker => {\n        return !!walker.entry;\n      })\n      .then(res => {\n        expect(res).to.equal(true);\n      });\n  });\n});\n"
  },
  {
    "path": "packages/compiler-less/.npmignore",
    "content": "node_modules\n"
  },
  {
    "path": "packages/compiler-less/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n# 2.1.0 (2020-07-04)\n\n**Note:** Version bump only for package @wepy/compiler-less\n\n\n\n\n\n# 2.1.0-alpha.10 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-less\n\n\n\n\n\n# 2.1.0-alpha.9 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-less\n\n\n\n\n\n# 2.1.0-alpha.8 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-less\n\n\n\n\n\n# 2.1.0-alpha.7 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-less\n\n\n\n\n\n# 2.1.0-alpha.6 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-less\n\n\n\n\n\n# 2.1.0-alpha.5 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-less\n\n\n\n\n\n# [2.1.0-alpha.4](https://github.com/Tencent/wepy/compare/v2.1.0-alpha.2...v2.1.0-alpha.4) (2020-06-20)\n\n**Note:** Version bump only for package @wepy/compiler-less\n"
  },
  {
    "path": "packages/compiler-less/README.md",
    "content": "# wepy less 编译器\n\n## 安装\n\n```\nnpm install @wepy/compiler-less less --save-dev\n```\n\n\n## 配置`wepy.config.js`\n\n```\nmodule.exports = {\n    \"compilers\": {\n        less: {\n            \"compress\": true\n        }\n    }\n};\n```\n\n## 参数说明\n\n[Less](https://github.com/less/less.js)\n"
  },
  {
    "path": "packages/compiler-less/createPlugin.js",
    "content": "const fs = require('fs');\nconst less = require('less');\nconst loaderUtils = require('loader-utils');\n\nconst matchMalformedModuleFilename = /(~[^/\\\\]+)\\.less$/;\nconst isModuleName = /^~[^/\\\\]+$/;\nconst trailingSlash = /[/\\\\]$/;\n\nfunction createPlugin(compliation) {\n  class aliasManager extends less.FileManager {\n    supportsSync() {\n      if (less.version[0] >= 3) {\n        return true;\n      }\n      return false;\n    }\n    loadFileSync(filename, currentDirectory, options, environment) {\n      options.syncImport = true;\n      return super.loadFile(filename, currentDirectory, options, environment);\n    }\n    supports() {\n      return true;\n    }\n    loadFile(filename, dir, options) {\n      let url;\n      if (less.version[0] >= 3) {\n        if (options.ext && !isModuleName.test(filename)) {\n          url = this.tryAppendExtension(filename, options.ext);\n        } else {\n          url = filename;\n        }\n      } else {\n        url = filename.replace(matchMalformedModuleFilename, '$1');\n      }\n      const moduleRequest = loaderUtils.urlToRequest(url, url.charAt(0) === '/' ? '' : null);\n\n      return compliation.resolvers.normal.resolve({}, dir.replace(trailingSlash, ''), moduleRequest, {}).then(rst => {\n        return {\n          contents: fs.readFileSync(rst.path, 'utf-8'),\n          filename: rst.path\n        };\n      });\n    }\n  }\n\n  return {\n    install(instance, pluginManager) {\n      pluginManager.addFileManager(new aliasManager());\n    },\n    minVersion: [2, 1, 1]\n  };\n}\n\nexports = module.exports = createPlugin;\n"
  },
  {
    "path": "packages/compiler-less/index.js",
    "content": "/**\n * Tencent is pleased to support the open source community by making WePY available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n *\n * Licensed under the MIT License (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n * http://opensource.org/licenses/MIT\n * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n */\n\nconst less = require('less');\nconst createPlugin = require('./createPlugin');\n\nexports = module.exports = function(options) {\n  return function() {\n    this.register('wepy-compiler-less', function(node, ctx) {\n      let config = Object.assign(\n        {\n          relativeUrls: true,\n          plugins: []\n        },\n        options\n      );\n      let file = typeof ctx === 'string' ? ctx : ctx.file;\n      config.filename = file;\n      config.plugins.push(createPlugin(this));\n\n      return less.render(node.content || '', config).then(rst => {\n        node.compiled = {\n          code: rst.css,\n          dep: rst.imports\n        };\n        this.fileDep.addDeps(file, node.compiled.dep);\n        return node;\n      });\n    });\n\n    this.register('wepy-watch-file-changed-less', function(buildTask) {\n      buildTask.files = this.fileDep.getSources(buildTask.changed);\n      if (buildTask.files.includes(this.options.entry)) {\n        buildTask.partial = false;\n      }\n      return buildTask;\n    });\n  };\n};\n"
  },
  {
    "path": "packages/compiler-less/package.json",
    "content": "{\n  \"name\": \"@wepy/compiler-less\",\n  \"version\": \"2.1.0\",\n  \"description\": \"wepy compile less\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"node ./test/helpers/lessc.js && mocha ./test/*.test.js\"\n  },\n  \"keywords\": [\n    \"less\"\n  ],\n  \"dependencies\": {\n    \"loader-utils\": \"^1.1.0\"\n  },\n  \"peerDependencies\": {\n    \"less\": \"^2.7.1 || ^3.5.0\"\n  },\n  \"author\": {\n    \"name\": \"Gcaufy\"\n  },\n  \"license\": \"MIT\",\n  \"devDependencies\": {\n    \"enhanced-resolve\": \"^4.0.0\",\n    \"fs-extra\": \"^6.0.1\",\n    \"less\": \"^3.11.3\",\n    \"lessc\": \"^1.0.2\"\n  },\n  \"readme\": \"ERROR: No README data found!\",\n  \"_id\": \"@wepy/compiler-less@2.0.7\",\n  \"_commitid\": \"174b2e1\",\n  \"gitHead\": \"5a25776457360bbbbc54a4d059f6bc7c032d5df3\"\n}\n"
  },
  {
    "path": "packages/compiler-less/test/fixtures/css/alias.css",
    "content": "body {\n  color: #ff0101;\n}\n"
  },
  {
    "path": "packages/compiler-less/test/fixtures/css/basic.css",
    "content": ".no-math {\n  width: calc(50% + (25vh - 20px));\n  foo: 3 calc(3 + 4) 11;\n  bar: calc(1 + 20%);\n}\n"
  },
  {
    "path": "packages/compiler-less/test/fixtures/css/extend.css",
    "content": ".some-module,\n#it-works,\n#it-works-all {\n  color: red;\n  transform: scale(2);\n}\n.some-module .sub-module,\n#it-works-all .sub-module {\n  color: green;\n}\n#it-works {\n  margin: 0;\n  transform: rotate(15deg);\n}\n#it-works-all {\n  margin: 0;\n}\n"
  },
  {
    "path": "packages/compiler-less/test/fixtures/css/function.css",
    "content": ".image-width {\n  width: 1px;\n}\n.image-height {\n  height: 1px;\n}\n.image-size {\n  width: 1px 1px;\n}\n"
  },
  {
    "path": "packages/compiler-less/test/fixtures/css/guards.css",
    "content": "button {\n  foo: 1;\n}\n"
  },
  {
    "path": "packages/compiler-less/test/fixtures/css/import.css",
    "content": "body {\n  color: #ff0101;\n}\n"
  },
  {
    "path": "packages/compiler-less/test/fixtures/css/lazy.css",
    "content": ".lazy-eval {\n  width: 9%;\n}\n"
  },
  {
    "path": "packages/compiler-less/test/fixtures/css/list-each.css",
    "content": ".sel-blue {\n  a: b;\n}\n.sel-green {\n  a: b;\n}\n.sel-red {\n  a: b;\n}\n"
  },
  {
    "path": "packages/compiler-less/test/fixtures/css/list.css",
    "content": ".image-width {\n  width: 1px;\n}\n.image-height {\n  height: 1px;\n}\n.image-size {\n  width: 1px 1px;\n}\n"
  },
  {
    "path": "packages/compiler-less/test/fixtures/css/selector.css",
    "content": ".button-ok {\n  foo: 1;\n}\n.button-cancel {\n  foo: 1;\n}\n.button-custom {\n  foo: 1;\n}\n.grand .parent > .grand .parent {\n  foo: 1;\n}\n.grand .parent + .grand .parent {\n  foo: 1;\n}\n.grand .parent .grand .parent {\n  foo: 1;\n}\n.grand .parent.grand .parent {\n  foo: 1;\n}\n.grand .parent,\n.grand .parentish {\n  foo: 1;\n}\n"
  },
  {
    "path": "packages/compiler-less/test/fixtures/css/uri.css",
    "content": ".img {\n  background: url(\"imgs/vacant.gif\");\n  background: url(\"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\");\n}\n.img1 {\n  background: url(\"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\");\n}\n.img2 {\n  background-image: \"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\";\n}\n"
  },
  {
    "path": "packages/compiler-less/test/fixtures/less/alias.less",
    "content": "@import '~@/colors.less';\n\nbody {\n  color: @red;\n}\n"
  },
  {
    "path": "packages/compiler-less/test/fixtures/less/basic.less",
    "content": ".no-math {\n  @var: 50vh/2;\n  width: calc(50% + (@var - 20px));\n  foo: 1 + 2 calc(3 + 4) 5 + 6;\n  @floor: floor(1 + .1);\n  bar: calc(@floor + 20%);\n}\n"
  },
  {
    "path": "packages/compiler-less/test/fixtures/less/extend.less",
    "content": "@import \"~@/modules\";\r\n\r\n#it-works:extend(.some-module) {\r\n  margin: 0;\r\n  transform+_: rotate(15deg);\r\n}\r\n\r\n#it-works-all:extend(.some-module all) {\r\n  margin: 0;\r\n}\r\n"
  },
  {
    "path": "packages/compiler-less/test/fixtures/less/fail-missing-file.less",
    "content": "@import 'missingfile.less';\r\n\r\nbody {color: red;}\r\n"
  },
  {
    "path": "packages/compiler-less/test/fixtures/less/fail-uri-alias.less",
    "content": ".img-alias {\r\n  background: url(\"~@/vacant.gif\");\r\n  background: data-uri(\"~@/vacant.gif\");\r\n}\r\n"
  },
  {
    "path": "packages/compiler-less/test/fixtures/less/guards.less",
    "content": "@my-option: true;\r\n\r\nbutton when (@my-option = true) {\r\n  foo: 1;\r\n}\r\n"
  },
  {
    "path": "packages/compiler-less/test/fixtures/less/import.less",
    "content": "@import './vars/colors.less';\nbody {\n  color: @red;\n}\n"
  },
  {
    "path": "packages/compiler-less/test/fixtures/less/lazy.less",
    "content": ".lazy-eval {\r\n  width: @var;\r\n  @a: 9%;\r\n}\r\n\r\n@var: @a;\r\n@a: 100%;\r\n"
  },
  {
    "path": "packages/compiler-less/test/fixtures/less/list-each.less",
    "content": "@selectors: blue, green, red;\n\neach(@selectors, {\n  .sel-@{value} {\n    a: b;\n  }\n});\n"
  },
  {
    "path": "packages/compiler-less/test/fixtures/less/list.less",
    "content": "@imagePath: 'imgs/vacant.gif';\n.image-width {\n  width: image-width(@imagePath);\n}\n\n.image-height {\n  height: image-height(@imagePath);\n}\n\n.image-size {\n  width: image-size(@imagePath);\n}\n"
  },
  {
    "path": "packages/compiler-less/test/fixtures/less/selector.less",
    "content": ".button {\r\n  &-ok {\r\n    foo: 1;\r\n  }\r\n  &-cancel {\r\n    foo: 1;\r\n  }\r\n\r\n  &-custom {\r\n    foo: 1;\r\n  }\r\n}\r\n\r\n.grand {\r\n  .parent {\r\n    & > & {\r\n      foo: 1;\r\n    }\r\n\r\n    & + & {\r\n      foo: 1;\r\n    }\r\n\r\n    & & {\r\n      foo: 1;\r\n    }\r\n\r\n    && {\r\n      foo: 1;\r\n    }\r\n\r\n    &, &ish {\r\n      foo: 1;\r\n    }\r\n  }\r\n}\r\n"
  },
  {
    "path": "packages/compiler-less/test/fixtures/less/uri.less",
    "content": "@base64: \"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\";\r\n\r\n.img {\r\n  background: url(\"imgs/vacant.gif\");\r\n  background: data-uri(\"imgs/vacant.gif\");\r\n}\r\n\r\n.img1 {\r\n  background: data-uri(\"imgs/vacant.gif\");\r\n}\r\n\r\n.img2 {\r\n  background-image: @base64;\r\n}\r\n"
  },
  {
    "path": "packages/compiler-less/test/fixtures/less/vars/colors.less",
    "content": "@red: #ff0101;\n"
  },
  {
    "path": "packages/compiler-less/test/fixtures/less/vars/modules.less",
    "content": ".some-module {\r\n  color: red;\r\n  transform+_: scale(2);\r\n  .sub-module {\r\n    color: green;\r\n  }\r\n}"
  },
  {
    "path": "packages/compiler-less/test/helpers/lessc.js",
    "content": "const { exec } = require('child_process');\nconst path = require('path');\nconst fs = require('fs-extra');\nconst less = require('less');\nconst specs = require('./specs');\n\nconst projectPath = path.resolve(__dirname, '..', '..');\nconst fixturesPath = path.resolve(projectPath, 'test', 'fixtures');\nconst lessPath = path.resolve(fixturesPath, 'less');\nconst cssPath = path.resolve(fixturesPath, 'css');\n\n// Ignore the fail test cases;\nlet ids = specs.getIds().filter(v => !/^fail-/.test(v));\n\nids.forEach(id => {\n  const lessFile = path.join(lessPath, `${id}.less`);\n  const css = path.join(cssPath, `${id}.css`);\n  const tmpless = path.join(lessPath, `${id}.tmp.less`);\n\n  let replaces = specs.getReplacements(id);\n\n  let content = fs.readFileSync(lessFile, 'utf-8');\n\n  replaces.forEach(r => {\n    content = content.replace(r[0], r[1]);\n  });\n  fs.outputFileSync(tmpless, content);\n\n  let options = specs.getLesscOpt(id);\n\n  let relativeUrls = '--relative-urls';\n  if (less.version[0] >= 3 && less.version[1] >= 8) {\n    // https://github.com/less/less.js/blob/59e919b3fc968a403405e39cf15237936b1a6b46/bin/lessc#L479-L484\n    relativeUrls = '--rewrite-urls=all';\n  }\n  let cmd = `npx lessc ${relativeUrls} ${options} ${tmpless} ${css}`;\n\n  // eslint-disable-next-line\n  console.log(`Generate spec: ${id}`);\n\n  exec(cmd, { cwd: projectPath }, (err, stdout, stderr) => {\n    if (err || stdout || stderr) {\n      err = err || new Error(stdout || stderr);\n      throw err;\n    }\n    fs.removeSync(tmpless);\n  });\n});\n"
  },
  {
    "path": "packages/compiler-less/test/helpers/specs.js",
    "content": "const fs = require('fs');\nconst path = require('path');\nconst less = require('less');\n\nconst lessDir = path.resolve(__dirname, '../fixtures/less/');\n\nlet tests = null;\n\nconst options = {\n  basic: {\n    json: {},\n    string: [],\n    resolve: {}\n  },\n  alias: {\n    replace: [[/~@/g, '../less/vars']],\n    resolve: {\n      alias: {\n        '@': path.resolve(__dirname, '../fixtures/less/vars')\n      }\n    }\n  },\n  'fail-missing-file': {\n    error: `Can't resolve` // Error message.\n  },\n  'fail-uri-alias': {\n    then: true, // Consider as a success test case.\n    resolve: {\n      alias: {\n        '@': path.resolve(__dirname, '../fixtures/less/imgs')\n      }\n    }\n  },\n  extend: {\n    replace: [[/~@/g, '../less/vars']],\n    resolve: {\n      alias: {\n        '@': path.resolve(__dirname, '../fixtures/less/vars')\n      }\n    }\n  }\n};\n\nfunction compareArrayGe(arr1, arr2) {\n  return arr1.every((currentValue, index) => {\n    return currentValue >= arr2[index];\n  });\n}\n\nfunction versionFilter(name) {\n  const list = [\n    {\n      ge: [3, 7, 0],\n      whiteList: ['list-each.less']\n    }\n  ];\n  const lessVersion = less.version;\n\n  const allWhiteList = list.reduce((accumulator, currentValue) => {\n    return accumulator.concat(currentValue.whiteList);\n  }, []);\n  if (allWhiteList.indexOf(name) < 0) {\n    return true;\n  }\n\n  return list.some(element => {\n    if (compareArrayGe(lessVersion, element.ge) && element.whiteList.indexOf(name) >= 0) {\n      return true;\n    }\n  });\n}\n\nexports = module.exports = {\n  getIds() {\n    if (tests) {\n      return tests;\n    }\n    tests = fs\n      .readdirSync(lessDir)\n      .filter(name => path.extname(name) === '.less' && name.indexOf('.tmp') === -1 && versionFilter(name))\n      .map(name => path.basename(name, '.less'));\n    return tests;\n  },\n  getId(id) {\n    return options[id] || {};\n  },\n  getOpt(id) {\n    return this.getId(id).json || {};\n  },\n  getResolveOpt(id) {\n    return this.getId(id).resolve || {};\n  },\n  getLesscOpt(id) {\n    return (this.getId(id).string || []).join(' ');\n  },\n  getReplacements(id) {\n    return this.getId(id).replace || [];\n  }\n};\n"
  },
  {
    "path": "packages/compiler-less/test/index.test.js",
    "content": "const path = require('path');\nconst fs = require('fs-extra');\nconst expect = require('chai').expect;\nconst lessPlugin = require('../index');\nconst specs = require('./helpers/specs');\nconst ResolverFactory = require('enhanced-resolve').ResolverFactory;\nconst NodeJsInputFileSystem = require('enhanced-resolve/lib/NodeJsInputFileSystem');\nconst CachedInputFileSystem = require('enhanced-resolve/lib/CachedInputFileSystem');\n\nclass Hook {\n  constructor() {\n    // file will be involved for watch\n    this.fileDep = { addDeps() {} };\n  }\n\n  register(key, fn) {\n    if (!this._fns) this._fns = {};\n    this._fns[key] = fn;\n  }\n  hook(key, ...args) {\n    return this._fns[key].apply(this, args);\n  }\n  clear() {\n    this._fns = {};\n  }\n}\n\nfunction createCompile(lessOpt, resolveOpt) {\n  let instance = new Hook();\n  lessPlugin(lessOpt).call(instance);\n\n  instance.resolvers = {\n    normal: ResolverFactory.createResolver(\n      Object.assign(\n        {\n          fileSystem: new CachedInputFileSystem(new NodeJsInputFileSystem(), 60000)\n        },\n        resolveOpt\n      )\n    )\n  };\n\n  instance.logger = {\n    error(e) {\n      /* eslint-disable no-console */\n      console.log('======= ERROR OUTPUT ======');\n      console.log(e);\n      /* eslint-enable no-console */\n    }\n  };\n\n  let fnNormalBak = instance.resolvers.normal.resolve;\n  instance.resolvers.normal.resolve = function(...args) {\n    return new Promise((resolve, reject) => {\n      args.push(function(err, filepath, meta) {\n        if (err) {\n          reject(err);\n        } else {\n          resolve({ path: filepath, meta: meta });\n        }\n      });\n      fnNormalBak.apply(instance.resolvers.normal, args);\n    });\n  };\n  return instance;\n}\n\nfunction readSpec(id, isFailSpec) {\n  let lessfile = path.join(__dirname, 'fixtures', 'less', id + '.less');\n  let expectfile = isFailSpec ? '' : path.join(__dirname, 'fixtures', 'css', id + '.css');\n\n  return {\n    node: {\n      content: fs.readFileSync(lessfile, 'utf-8')\n    },\n    file: lessfile,\n    expect: isFailSpec ? '' : fs.readFileSync(expectfile, 'utf-8')\n  };\n}\n\nfunction compare(id, done) {\n  let compile = createCompile(specs.getOpt(id), specs.getResolveOpt(id));\n\n  let spec = readSpec(id);\n  return compile\n    .hook('wepy-compiler-less', spec.node, spec.file)\n    .then(node => {\n      let css = node.compiled.code;\n      expect(css).to.equal(spec.expect);\n      done();\n    })\n    .catch(e => {\n      done(e);\n    });\n}\n\nfunction compileFail(id, done) {\n  let compile = createCompile(specs.getOpt(id), specs.getResolveOpt(id));\n\n  let spec = readSpec(id, true);\n\n  let setting = specs.getId(id);\n\n  return compile\n    .hook('wepy-compiler-less', spec.node, spec.file)\n    .then(() => {\n      // e.g. uri-alias, alias is not awared in uri, so treat as compile successfully.\n      if (setting.then) {\n        done();\n      }\n    })\n    .catch(e => {\n      if (setting.error) {\n        expect(e.line).to.be.gt(0);\n        expect(e.message).to.have.string(setting.error);\n      } else {\n        expect(e).to.be.an('error');\n      }\n      done();\n    });\n}\n\ndescribe('wepy-compiler-less', function() {\n  let ids = specs.getIds();\n\n  let shouldPassIds = ids.filter(id => !/^fail-/.test(id));\n\n  let shouldFailIds = ids.filter(id => /^fail-/.test(id));\n\n  shouldPassIds.forEach(id => {\n    it('Pass test cases: ' + id, function(done) {\n      compare(id, done);\n    });\n  });\n  shouldFailIds.forEach(id => {\n    it('Fail test cases: ' + id, function(done) {\n      compileFail(id, done);\n    });\n  });\n});\n"
  },
  {
    "path": "packages/compiler-postcss/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n# 2.1.0 (2020-07-04)\n\n**Note:** Version bump only for package @wepy/compiler-postcss\n\n\n\n\n\n# 2.1.0-alpha.10 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-postcss\n\n\n\n\n\n# 2.1.0-alpha.9 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-postcss\n\n\n\n\n\n# 2.1.0-alpha.8 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-postcss\n\n\n\n\n\n# 2.1.0-alpha.7 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-postcss\n\n\n\n\n\n# 2.1.0-alpha.6 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-postcss\n\n\n\n\n\n# 2.1.0-alpha.5 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-postcss\n\n\n\n\n\n# [2.1.0-alpha.4](https://github.com/Tencent/wepy/compare/v2.1.0-alpha.2...v2.1.0-alpha.4) (2020-06-20)\n\n**Note:** Version bump only for package @wepy/compiler-postcss\n"
  },
  {
    "path": "packages/compiler-postcss/README.md",
    "content": "# wepy postcss 编译器\n\n## 安装\n\n```\nnpm install @wepy/compiler-postcss --save\n```\n\n\n## 配置 `wepy.config.js` ,以使用 `cssnext` 为例\n\n```\nconst cssnext = require('cssnext');\n\nmodule.exports = {\n    \"compilers\": {\n        postcss: {\n            plugins: [\n                cssnext({\n                    browsers:['iOS 9', 'Android 4.4']\n                })\n            ],\n            map: {\n                inline: true\n            }\n        },\n    }\n};\n```\n\n## 参数说明\n配置参数为[processOptions](http://api.postcss.org/global.html#processOptions)及[plugins](http://api.postcss.org/global.html#Plugin)\n\n\n## 已知Bug\n\n使用`cssnano`插件压缩css时，由于其依赖`macaddress`存在全局变量泄露问题，将导致无法完成编译过程。\n问题相关：[Github](https://github.com/webpack-contrib/css-loader/pull/472)\n\n## Contributor\n\n[fsy0718](mailto:fsy0718@gmail.com)\n"
  },
  {
    "path": "packages/compiler-postcss/index.js",
    "content": "const postcss = require('postcss');\n\nexports = module.exports = function(options = {}) {\n  const { plugins = [], ...other } = options;\n  return function() {\n    this.register('wepy-compiler-postcss', function(node, ctx) {\n      let file = typeof ctx === 'string' ? ctx : ctx.file;\n\n      return postcss(plugins)\n        .process(node.content || '', {\n          from: file,\n          ...other\n        })\n        .then(res => {\n          node.compiled = {\n            code: res.css\n          };\n          return node;\n        });\n    });\n  };\n};\n"
  },
  {
    "path": "packages/compiler-postcss/package.json",
    "content": "{\n  \"name\": \"@wepy/compiler-postcss\",\n  \"version\": \"2.1.0\",\n  \"description\": \"wepy compile postcss\",\n  \"keywords\": [\n    \"postcss\"\n  ],\n  \"author\": \"fsy0718 <fsy0718@gmail.com>\",\n  \"license\": \"MIT\",\n  \"main\": \"index.js\",\n  \"directories\": {\n    \"test\": \"test\"\n  },\n  \"scripts\": {\n    \"test\": \"node ./test/helpers/postcssc.js && mocha ./test/*.test.js\"\n  },\n  \"peerDependencies\": {\n    \"postcss\": \"^7.0.4\"\n  },\n  \"dependencies\": {\n    \"enhanced-resolve\": \"^4.1.0\",\n    \"mocha\": \"^5.2.0\",\n    \"postcss-cssnext\": \"^3.1.0\"\n  },\n  \"gitHead\": \"5a25776457360bbbbc54a4d059f6bc7c032d5df3\"\n}\n"
  },
  {
    "path": "packages/compiler-postcss/test/fixtures/css/basic.css",
    "content": "a {\n  color: red\n}\nb {\n  color: white;\n  background-color: red;\n}\n\na {\n  /* direct nesting (& MUST be the first part of selector)*/\n}\n\na span {\n  color: white;\n}\n\na {\n  /* @nest rule (for complex nesting)*/\n}\n\nspan a {\n  color: blue;\n}\n\na {\n  /* media query automatic nesting*/\n}\n\n@media (min-width: 30em) {\n  a {\n    color: yellow\n  }\n}"
  },
  {
    "path": "packages/compiler-postcss/test/fixtures/css/map.css",
    "content": "a {\n  color: red\n}\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvZml4dHVyZXMvcG9zdGNzcy9tYXAucG9zdGNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFJQTtFQUNFLFVBQXVCO0NBQ3hCIiwiZmlsZSI6InRlc3QvZml4dHVyZXMvcG9zdGNzcy9tYXAucG9zdGNzcyIsInNvdXJjZXNDb250ZW50IjpbIjpyb290IHtcbiAgLS1tYWluQ29sb3I6IHJlZFxufVxuXG5hIHtcbiAgY29sb3I6IHZhcigtLW1haW5Db2xvcilcbn0iXX0= */"
  },
  {
    "path": "packages/compiler-postcss/test/fixtures/postcss/basic.postcss",
    "content": ":root {\n  --mainColor: red;\n    --danger-theme: {\n    color: white;\n    background-color: red;\n  }\n}\n\na {\n  color: var(--mainColor)\n}\nb {\n    @apply --danger-theme;\n}\n\na {\n  /* direct nesting (& MUST be the first part of selector)*/\n  & span {\n    color: white;\n  }\n\n  /* @nest rule (for complex nesting) */\n  @nest span & {\n    color: blue;\n  }\n\n  /* media query automatic nesting */\n  @media (min-width: 30em) {\n    color: yellow;\n  }\n}"
  },
  {
    "path": "packages/compiler-postcss/test/fixtures/postcss/map.postcss",
    "content": ":root {\n  --mainColor: red\n}\n\na {\n  color: var(--mainColor)\n}"
  },
  {
    "path": "packages/compiler-postcss/test/helpers/postcssc.js",
    "content": "const path = require('path');\nconst postcss = require('postcss');\nconst fs = require('fs-extra');\nconst specs = require('./specs');\n\nconst projectPath = path.resolve(__dirname, '..', '..');\nconst fixturesPath = path.resolve(projectPath, 'test', 'fixtures');\nconst postcssPath = path.resolve(fixturesPath, 'postcss');\nconst cssPath = path.resolve(fixturesPath, 'css');\n\nlet ids = specs.getIds();\n\nids.forEach(id => {\n  const postcssfile = path.join(postcssPath, `${id}.postcss`);\n  const css = path.join(cssPath, `${id}.css`);\n  let content = fs.readFileSync(postcssfile, 'utf-8');\n\n  let options = specs.getOpt(id);\n\n  // eslint-disable-next-line\n  console.log(`Generate spec: ${id}`);\n  const { plugins = [], ...other } = options;\n  postcss(plugins)\n    .process(content, {\n      from: postcssfile,\n      ...other\n    })\n    .then(function(result) {\n      fs.outputFileSync(css, result.css.toString(), 'utf-8');\n    })\n    .catch(function(err) {\n      // eslint-disable-next-line\n      console.log(err);\n      return;\n    });\n});\n"
  },
  {
    "path": "packages/compiler-postcss/test/helpers/specs.js",
    "content": "const fs = require('fs');\nconst path = require('path');\nconst cssNext = require('postcss-cssnext');\n\nconst postcssDir = path.resolve(__dirname, '../fixtures/postcss/');\n\nlet tests = null;\n\nconst options = {\n  basic: {\n    json: {\n      plugins: [cssNext()]\n    },\n    string: [],\n    resolve: {}\n  },\n  map: {\n    json: {\n      plugins: [cssNext()],\n      map: {\n        inline: true\n      }\n    }\n  }\n};\n\nexports = module.exports = {\n  getIds() {\n    if (tests) {\n      return tests;\n    }\n    tests = fs\n      .readdirSync(postcssDir)\n      .filter(name => path.extname(name) === '.postcss' && name.indexOf('.tmp') === -1)\n      .map(name => path.basename(name, '.postcss'));\n    return tests;\n  },\n  getId(id) {\n    return options[id] || {};\n  },\n  getOpt(id) {\n    return this.getId(id).json || {};\n  },\n  getResolveOpt(id) {\n    return this.getId(id).resolve || {};\n  },\n  getReplacements(id) {\n    return this.getId(id).replace || [];\n  }\n};\n"
  },
  {
    "path": "packages/compiler-postcss/test/index.test.js",
    "content": "const path = require('path');\nconst fs = require('fs-extra');\nconst expect = require('chai').expect;\nconst postcssPlugin = require('../index');\nconst specs = require('./helpers/specs');\nconst ResolverFactory = require('enhanced-resolve').ResolverFactory;\nconst NodeJsInputFileSystem = require('enhanced-resolve/lib/NodeJsInputFileSystem');\nconst CachedInputFileSystem = require('enhanced-resolve/lib/CachedInputFileSystem');\n\nclass Hook {\n  register(key, fn) {\n    if (!this._fns) this._fns = {};\n    this._fns[key] = fn;\n  }\n  hook(key, ...args) {\n    return this._fns[key].apply(this, args);\n  }\n  clear() {\n    this._fns = {};\n  }\n}\n\nfunction createCompile(postcssOpt, resolveOpt) {\n  let instance = new Hook();\n  postcssPlugin(postcssOpt).call(instance);\n\n  instance.resolvers = {\n    normal: ResolverFactory.createResolver(\n      Object.assign(\n        {\n          fileSystem: new CachedInputFileSystem(new NodeJsInputFileSystem(), 60000)\n        },\n        resolveOpt\n      )\n    )\n  };\n\n  let fnNormalBak = instance.resolvers.normal.resolve;\n  instance.resolvers.normal.resolve = function(...args) {\n    return new Promise((resolve, reject) => {\n      args.push(function(err, filepath, meta) {\n        if (err) {\n          reject(err);\n        } else {\n          resolve({ path: filepath, meta: meta });\n        }\n      });\n      fnNormalBak.apply(instance.resolvers.normal, args);\n    });\n  };\n  return instance;\n}\n\nfunction readSpec(id) {\n  let postcssfile = path.join(__dirname, 'fixtures', 'postcss', id + '.postcss');\n  let expectfile = path.join(__dirname, 'fixtures', 'css', id + '.css');\n\n  return {\n    node: {\n      content: fs.readFileSync(postcssfile, 'utf-8')\n    },\n    file: postcssfile,\n    expect: fs.readFileSync(expectfile, 'utf-8')\n  };\n}\n\nfunction compare(id, done) {\n  let compile = createCompile(specs.getOpt(id), specs.getResolveOpt(id));\n\n  let spec = readSpec(id);\n  let ext = path.extname(spec.file);\n  let type = ext.substring(1, ext.length);\n\n  return compile\n    .hook('wepy-compiler-' + type, spec.node, spec.file)\n    .then(node => {\n      let css = node.compiled.code;\n      expect(css).to.equal(spec.expect);\n      done();\n    })\n    .catch(e => {\n      done();\n      throw e;\n    });\n}\n\ndescribe('wepy-compiler-postcss', function() {\n  let ids = specs.getIds();\n\n  ids.forEach(id => {\n    it('testing ' + id, function(done) {\n      compare(id, done);\n    });\n  });\n});\n"
  },
  {
    "path": "packages/compiler-sass/.npmignore",
    "content": "src\ntest\nnode_modules"
  },
  {
    "path": "packages/compiler-sass/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n# 2.1.0 (2020-07-04)\n\n**Note:** Version bump only for package @wepy/compiler-sass\n\n\n\n\n\n# 2.1.0-alpha.10 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-sass\n\n\n\n\n\n# 2.1.0-alpha.9 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-sass\n\n\n\n\n\n# 2.1.0-alpha.8 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-sass\n\n\n\n\n\n# 2.1.0-alpha.7 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-sass\n\n\n\n\n\n# 2.1.0-alpha.6 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-sass\n\n\n\n\n\n# 2.1.0-alpha.5 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-sass\n\n\n\n\n\n# [2.1.0-alpha.4](https://github.com/Tencent/wepy/compare/v2.1.0-alpha.2...v2.1.0-alpha.4) (2020-06-20)\n\n**Note:** Version bump only for package @wepy/compiler-sass\n"
  },
  {
    "path": "packages/compiler-sass/README.md",
    "content": "# wepy sass 编译器\n\n## 安装\n\n```\nnpm install @wepy/compiler-sass --save-dev\n```\n\n## 配置`wepy.config.js`\n\n```\nmodule.exports = {\n    \"compilers\": {\n        sass: {\n            'outputStyle': 'compressed'\n        }\n    }\n};\n```\n\n\n## 参数说明\n\n[sass](https://github.com/sass/dart-sass)\n"
  },
  {
    "path": "packages/compiler-sass/importsToResolve.js",
    "content": "const path = require('path');\nconst utils = require('loader-utils');\n\n// eslint-disable-next-line\nconst matchModuleImport = /^~([^\\/]+|@[^\\/]+[\\/][^\\/]+)$/;\n\n/**\n * When libsass tries to resolve an import, it uses a special algorithm.\n * Since the sass-loader uses webpack to resolve the modules, we need to simulate that algorithm. This function\n * returns an array of import paths to try. The last entry in the array is always the original url\n * to enable straight-forward webpack.config aliases.\n *\n * @param {string} url\n * @returns {Array<string>}\n */\nfunction importsToResolve(url) {\n  const request = utils.urlToRequest(url);\n  // Keep in mind: ext can also be something like '.datepicker' when the true extension is omitted and the filename contains a dot.\n  // @see https://github.com/webpack-contrib/sass-loader/issues/167\n  const ext = path.extname(request);\n\n  if (matchModuleImport.test(url)) {\n    return [request, url];\n  }\n\n  // libsass' import algorithm works like this:\n\n  // In case there is a file extension...\n  //   - If the file is a CSS-file, do not include it all, but just link it via @import url().\n  //   - The exact file name must match (no auto-resolving of '_'-modules).\n  if (ext === '.css') {\n    return [];\n  }\n  if (ext === '.scss' || ext === '.sass') {\n    return [request, url];\n  }\n\n  // In case there is no file extension...\n  //   - Prefer modules starting with '_'.\n  //   - File extension precedence: .scss, .sass, .css.\n  const basename = path.basename(request);\n\n  if (basename.charAt(0) === '_') {\n    return [`${request}.scss`, `${request}.sass`, `${request}.css`, url];\n  }\n\n  const dirname = path.dirname(request);\n\n  return [\n    `${dirname}/_${basename}.scss`,\n    `${dirname}/_${basename}.sass`,\n    `${dirname}/_${basename}.css`,\n    `${request}.scss`,\n    `${request}.sass`,\n    `${request}.css`,\n    url\n  ];\n}\n\nmodule.exports = importsToResolve;\n"
  },
  {
    "path": "packages/compiler-sass/index.js",
    "content": "/**\n * Tencent is pleased to support the open source community by making WePY available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n *\n * Licensed under the MIT License (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n * http://opensource.org/licenses/MIT\n * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n */\n\nconst os = require('os');\nconst path = require('path');\nconst sass = require('sass');\nconst resolveImporter = require('./resolveImporter');\n\nfunction createSassPlugin(compilation, type, options) {\n  return function(node, ctx) {\n    let file = typeof ctx === 'string' ? ctx : ctx.file;\n    let config = Object.assign(\n      {\n        file: file\n      },\n      options\n    );\n\n    config.data = config.data ? config.data + os.EOL + node.content : node.content;\n\n    config.importer = config.importer || [];\n    config.importer.push(resolveImporter(compilation, file));\n\n    config.includePaths = config.includePaths || [];\n    config.includePaths.push(path.dirname(file));\n\n    if (type === 'sass' && 'indentedSyntax' in config === false) {\n      config.indentedSyntax = true;\n    } else {\n      config.indentedSyntax = Boolean(config.indentedSyntax);\n    }\n\n    return new Promise((resolve, reject) => {\n      sass.render(config, (err, res) => {\n        if (err) {\n          reject(err);\n        } else {\n          node.compiled = {\n            code: res.css.toString()\n          };\n          resolve(node);\n        }\n      });\n    });\n  };\n}\n\nexports = module.exports = function(options) {\n  return function() {\n    ['sass', 'scss'].forEach(type => {\n      this.register(`wepy-compiler-${type}`, createSassPlugin(this, type, options));\n    });\n  };\n};\n"
  },
  {
    "path": "packages/compiler-sass/package.json",
    "content": "{\n  \"name\": \"@wepy/compiler-sass\",\n  \"version\": \"2.1.0\",\n  \"description\": \"wepy compile sass\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"node ./test/helpers/generate.js && mocha ./test/*.test.js\"\n  },\n  \"keywords\": [\n    \"sass\"\n  ],\n  \"author\": {\n    \"name\": \"Gcaufy\"\n  },\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"loader-utils\": \"^1.1.0\",\n    \"sass\": \"^1.26.9\"\n  },\n  \"devDependencies\": {\n    \"enhanced-resolve\": \"^4.0.0\"\n  },\n  \"readme\": \"ERROR: No README data found!\",\n  \"_id\": \"@wepy/compiler-sass@2.0.3\",\n  \"_commitid\": \"cf96591\",\n  \"gitHead\": \"5a25776457360bbbbc54a4d059f6bc7c032d5df3\"\n}\n"
  },
  {
    "path": "packages/compiler-sass/resolveImporter.js",
    "content": "const path = require('path');\nconst importsToResolve = require('./importsToResolve');\n\n//const matchMalformedModuleFilename = /(~[^/\\\\]+)\\.less$/;\n\nfunction resolveImporter(compilation, file) {\n  function doResolve(dir, imports) {\n    if (imports.length === 0) {\n      return Promise.reject();\n    }\n    return compilation.resolvers.normal.resolve({}, dir, imports[0], {}).then(resolved => {\n      return { file: resolved.path };\n    });\n  }\n  return function(url, prev, done) {\n    let dir = path.dirname(prev === 'stdin' ? file : prev);\n\n    doResolve(dir, importsToResolve(url))\n      .then(done)\n      .catch(() => ({ file: url }));\n  };\n}\n\nexports = module.exports = resolveImporter;\n"
  },
  {
    "path": "packages/compiler-sass/src/index.js",
    "content": "/**\n * Tencent is pleased to support the open source community by making WePY available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n *\n * Licensed under the MIT License (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n * http://opensource.org/licenses/MIT\n * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n */\n\nimport sass from 'sass';\n\nexport default function(content, config, file) {\n  return new Promise((resolve, reject) => {\n    config.data = content;\n    config.file = file;\n    sass.render(config, (err, res) => {\n      if (err) {\n        reject(err);\n      } else {\n        resolve(res.css);\n      }\n    });\n  });\n}\n"
  },
  {
    "path": "packages/compiler-sass/test/fixtures/css/alias.scss.css",
    "content": "body {\n  color: #ff0101;\n}"
  },
  {
    "path": "packages/compiler-sass/test/fixtures/css/basic.sass.css",
    "content": "body {\n  font: 100% Helvetica, sans-serif;\n  color: #333;\n}\n\nnav ul {\n  margin: 0;\n  padding: 0;\n  list-style: none;\n}\nnav li {\n  display: inline-block;\n}\nnav a {\n  display: block;\n  padding: 6px 12px;\n  text-decoration: none;\n}"
  },
  {
    "path": "packages/compiler-sass/test/fixtures/css/basic.scss.css",
    "content": "body {\n  font: 100% Helvetica, sans-serif;\n  color: #333;\n}\n\nnav ul {\n  margin: 0;\n  padding: 0;\n  list-style: none;\n}\nnav li {\n  display: inline-block;\n}\nnav a {\n  display: block;\n  padding: 6px 12px;\n  text-decoration: none;\n}"
  },
  {
    "path": "packages/compiler-sass/test/fixtures/css/import.sass.css",
    "content": "body {\n  color: #ff0101;\n}"
  },
  {
    "path": "packages/compiler-sass/test/fixtures/css/import.scss.css",
    "content": "body {\n  color: #ff0101;\n}"
  },
  {
    "path": "packages/compiler-sass/test/fixtures/sass/alias.scss",
    "content": "@import '~@/colors.scss';\nbody {\n  color: $red;\n}\n"
  },
  {
    "path": "packages/compiler-sass/test/fixtures/sass/basic.sass",
    "content": "$font-stack:    Helvetica, sans-serif\n$primary-color: #333\n$pi:            '\\e0C6'\n\nbody\n  font: 100% $font-stack\n  color: $primary-color\n\nnav\n  ul\n    margin: 0\n    padding: 0\n    list-style: none\n\n  li\n    display: inline-block\n\n  a\n    display: block\n    padding: 6px 12px\n    text-decoration: none\n"
  },
  {
    "path": "packages/compiler-sass/test/fixtures/sass/basic.scss",
    "content": "$font-stack:    Helvetica, sans-serif;\n$primary-color: #333;\n$pi:            '\\e0C6';\n\nbody {\n  font: 100% $font-stack;\n  color: $primary-color;\n}\n\nnav {\n  ul {\n    margin: 0;\n    padding: 0;\n    list-style: none;\n  }\n\n  li { display: inline-block; }\n\n  a {\n    display: block;\n    padding: 6px 12px;\n    text-decoration: none;\n  }\n}\n\n"
  },
  {
    "path": "packages/compiler-sass/test/fixtures/sass/import.sass",
    "content": "@import './vars/colors.scss'\n\nbody \n  color: $red\n"
  },
  {
    "path": "packages/compiler-sass/test/fixtures/sass/import.scss",
    "content": "@import './vars/colors.scss';\nbody {\n  color: $red;\n}\n"
  },
  {
    "path": "packages/compiler-sass/test/fixtures/sass/vars/colors.scss",
    "content": "$red: #ff0101;\n"
  },
  {
    "path": "packages/compiler-sass/test/helpers/generate.js",
    "content": "const path = require('path');\nconst sass = require('sass');\nconst fs = require('fs-extra');\nconst specs = require('./specs');\n\nconst projectPath = path.resolve(__dirname, '..', '..');\nconst fixturesPath = path.resolve(projectPath, 'test', 'fixtures');\nconst sassPath = path.resolve(fixturesPath, 'sass');\nconst cssPath = path.resolve(fixturesPath, 'css');\n\nspecs.getIds().forEach(id => {\n  const ext = path.extname(id);\n  const name = id.replace(new RegExp(ext + '$'), '');\n  const sassFile = path.join(sassPath, id);\n  const css = path.join(cssPath, `${id}.css`);\n  const tmpsass = path.join(sassPath, `${name}.tmp${ext}`);\n\n  let replaces = specs.getReplacements(id);\n\n  let content = fs.readFileSync(sassFile, 'utf-8');\n\n  replaces.forEach(r => {\n    content = content.replace(r[0], r[1]);\n  });\n  fs.outputFileSync(tmpsass, content);\n\n  let options = specs.getOpt(id);\n\n  // eslint-disable-next-line\n  console.log(`Generate spec: ${id}`);\n\n  sass.render(\n    {\n      file: tmpsass,\n      outFile: css,\n      ...options\n    },\n    function(err, result) {\n      if (err) {\n        // eslint-disable-next-line\n        console.log(err);\n        return;\n      }\n      fs.outputFileSync(css, result.css.toString(), 'utf-8');\n      fs.removeSync(tmpsass);\n    }\n  );\n});\n"
  },
  {
    "path": "packages/compiler-sass/test/helpers/specs.js",
    "content": "const fs = require('fs');\nconst path = require('path');\n\nconst sassDir = path.resolve(__dirname, '../fixtures/sass/');\n\nlet tests = null;\n\nconst options = {\n  'basic.scss': {\n    json: {},\n    string: [],\n    resolve: {}\n  },\n  'alias.scss': {\n    replace: [[/~@/g, '../sass/vars']],\n    resolve: {\n      alias: {\n        '@': path.resolve(__dirname, '../fixtures/sass/vars')\n      }\n    }\n  }\n};\n\nexports = module.exports = {\n  getIds() {\n    if (tests) {\n      return tests;\n    }\n    tests = fs.readdirSync(sassDir).filter(name => {\n      let ext = path.extname(name);\n      return name.indexOf('.tmp') === -1 && (ext === '.sass' || ext === '.scss');\n    });\n    return tests;\n  },\n  getId(id) {\n    return options[id] || {};\n  },\n  getOpt(id) {\n    return this.getId(id).json || {};\n  },\n  getResolveOpt(id) {\n    return this.getId(id).resolve || {};\n  },\n  getReplacements(id) {\n    return this.getId(id).replace || [];\n  }\n};\n"
  },
  {
    "path": "packages/compiler-sass/test/index.test.js",
    "content": "const path = require('path');\nconst fs = require('fs-extra');\nconst expect = require('chai').expect;\nconst sassPlugin = require('../index');\nconst specs = require('./helpers/specs');\nconst ResolverFactory = require('enhanced-resolve').ResolverFactory;\nconst NodeJsInputFileSystem = require('enhanced-resolve/lib/NodeJsInputFileSystem');\nconst CachedInputFileSystem = require('enhanced-resolve/lib/CachedInputFileSystem');\n\nclass Hook {\n  register(key, fn) {\n    if (!this._fns) this._fns = {};\n    this._fns[key] = fn;\n  }\n  hook(key, ...args) {\n    return this._fns[key].apply(this, args);\n  }\n  clear() {\n    this._fns = {};\n  }\n}\n\nfunction createCompile(sassOpt, resolveOpt) {\n  let instance = new Hook();\n  sassPlugin(sassOpt).call(instance);\n\n  instance.resolvers = {\n    normal: ResolverFactory.createResolver(\n      Object.assign(\n        {\n          fileSystem: new CachedInputFileSystem(new NodeJsInputFileSystem(), 60000)\n        },\n        resolveOpt\n      )\n    )\n  };\n\n  let fnNormalBak = instance.resolvers.normal.resolve;\n  instance.resolvers.normal.resolve = function(...args) {\n    return new Promise((resolve, reject) => {\n      args.push(function(err, filepath, meta) {\n        if (err) {\n          reject(err);\n        } else {\n          resolve({ path: filepath, meta: meta });\n        }\n      });\n      fnNormalBak.apply(instance.resolvers.normal, args);\n    });\n  };\n  return instance;\n}\n\nfunction readSpec(id) {\n  let sassfile = path.join(__dirname, 'fixtures', 'sass', id);\n  let expectfile = path.join(__dirname, 'fixtures', 'css', id + '.css');\n\n  return {\n    node: {\n      content: fs.readFileSync(sassfile, 'utf-8')\n    },\n    file: sassfile,\n    expect: fs.readFileSync(expectfile, 'utf-8')\n  };\n}\n\nfunction compare(id, done) {\n  let compile = createCompile(specs.getOpt(id), specs.getResolveOpt(id));\n\n  let spec = readSpec(id);\n  let ext = path.extname(spec.file);\n  let type = ext.substring(1, ext.length);\n\n  return compile\n    .hook('wepy-compiler-' + type, spec.node, spec.file)\n    .then(node => {\n      let css = node.compiled.code;\n      expect(css).to.equal(spec.expect);\n      done();\n    })\n    .catch(e => {\n      done();\n      throw e;\n    });\n}\n\ndescribe('wepy-compiler-less', function() {\n  let ids = specs.getIds();\n\n  ids.forEach(id => {\n    it('testing ' + id, function(done) {\n      compare(id, done);\n    });\n  });\n});\n"
  },
  {
    "path": "packages/compiler-stylus/.npmignore",
    "content": "node_modules\n"
  },
  {
    "path": "packages/compiler-stylus/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n# 2.1.0 (2020-07-04)\n\n**Note:** Version bump only for package @wepy/compiler-stylus\n\n\n\n\n\n# 2.1.0-alpha.10 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-stylus\n\n\n\n\n\n# 2.1.0-alpha.9 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-stylus\n\n\n\n\n\n# 2.1.0-alpha.8 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-stylus\n\n\n\n\n\n# 2.1.0-alpha.7 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-stylus\n\n\n\n\n\n# 2.1.0-alpha.6 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-stylus\n\n\n\n\n\n# 2.1.0-alpha.5 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-stylus\n\n\n\n\n\n# [2.1.0-alpha.4](https://github.com/Tencent/wepy/compare/v2.1.0-alpha.2...v2.1.0-alpha.4) (2020-06-20)\n\n**Note:** Version bump only for package @wepy/compiler-stylus\n"
  },
  {
    "path": "packages/compiler-stylus/README.md",
    "content": "# wepy stylus 编译器\n\n## 安装\n\n```\nnpm install @wepy/compiler-stylus --save-dev\n```\n\n\n## 配置`wepy.config.js`\n\n```\nmodule.exports = {\n    \"compilers\": {\n        stylus: {\n            \"compress\": true\n        }\n    }\n};\n```\n\n## 参数说明\n\n[Stylus](http://www.zhangxinxu.com/jq/stylus/js.php)"
  },
  {
    "path": "packages/compiler-stylus/createPlugin.js",
    "content": "const loaderUtils = require('loader-utils');\nconst stylus = require('stylus');\nconst isModuleName = /^~[^/\\\\]+$/;\nconst trailingSlash = /[/\\\\]$/;\n\nfunction createPlugin(compliation) {\n  return function(style) {\n    style.define('url', function() {\n      const file = style.get('filename');\n      const fileArrs = file.split('.');\n      const fileExt = fileArrs.pop();\n      const fileArrs1 = fileArrs[0].split('/');\n      const fileName = fileArrs1.pop();\n\n      let url;\n      if (fileExt && !isModuleName.test(fileName)) {\n        url = fileName + '.' + fileExt;\n      } else {\n        url = fileName;\n      }\n      const moduleRequest = loaderUtils.urlToRequest(url, url.charAt(0) === '/' ? '' : null);\n      compliation.resolvers.normal\n        .resolve({}, fileArrs1.join('/').replace(trailingSlash, ''), moduleRequest, {})\n        .then(rst => {\n          compliation.involved[rst.path] = 1;\n          return stylus.url({ paths: [rst.path] });\n        });\n    });\n  };\n}\n\nexports = module.exports = createPlugin;\n"
  },
  {
    "path": "packages/compiler-stylus/index.js",
    "content": "/**\n * Tencent is pleased to support the open source community by making WePY available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n *\n * Licensed under the MIT License (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n * http://opensource.org/licenses/MIT\n * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n */\n\nconst stylus = require('stylus');\nconst createPlugin = require('./createPlugin');\n\nexports = module.exports = function(options) {\n  return function() {\n    this.register('wepy-compiler-stylus', function(node, ctx) {\n      let file = typeof ctx === 'string' ? ctx : ctx.file;\n      const plugins = createPlugin(this);\n      let config = Object.assign(\n        {\n          use: plugins,\n          filename: file\n        },\n        options\n      );\n      const styl = stylus(node.content || '', config);\n\n      return new Promise((resolve, reject) => {\n        styl.render(function(err, css) {\n          if (err) reject(err);\n          else {\n            node.compiled = {\n              code: css,\n              dep: styl.deps()\n            };\n            resolve(node);\n          }\n        });\n      });\n    });\n  };\n};\n"
  },
  {
    "path": "packages/compiler-stylus/package.json",
    "content": "{\n  \"name\": \"@wepy/compiler-stylus\",\n  \"version\": \"2.1.0\",\n  \"description\": \"wepy compile stylus\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"node ./test/helpers/stylus.js && mocha ./test/*.test.js\"\n  },\n  \"keywords\": [\n    \"stylus\"\n  ],\n  \"dependencies\": {\n    \"loader-utils\": \"^1.1.0\"\n  },\n  \"peerDependencies\": {\n    \"stylus\": \"^0.54.0\"\n  },\n  \"author\": {\n    \"name\": \"Gcaufy\"\n  },\n  \"license\": \"MIT\",\n  \"devDependencies\": {\n    \"enhanced-resolve\": \"^4.0.0\",\n    \"fs-extra\": \"^6.0.1\"\n  },\n  \"readme\": \"ERROR: No README data found!\",\n  \"_id\": \"@wepy/compiler-stylus@2.0.1\",\n  \"_commitid\": \"4913bce\",\n  \"gitHead\": \"5a25776457360bbbbc54a4d059f6bc7c032d5df3\"\n}\n"
  },
  {
    "path": "packages/compiler-stylus/test/fixtures/css/alias.css",
    "content": "body {\n  color: #ff0101;\n}\n"
  },
  {
    "path": "packages/compiler-stylus/test/fixtures/css/basic.css",
    "content": ".no-math {\n  width: calc(50% + (25vh - 20px));\n  foo: 3 calc(3 + 4) 11;\n  bar: calc(1 + 20%);\n}\n"
  },
  {
    "path": "packages/compiler-stylus/test/fixtures/css/extend.css",
    "content": ".some-module,\n#it-works {\n  color: #f00;\n  transform: scale(2);\n}\n.some-module .sub-module {\n  color: #008000;\n}\n#it-works {\n  margin: 0;\n  transform: rotate(15deg);\n}\n"
  },
  {
    "path": "packages/compiler-stylus/test/fixtures/css/function.css",
    "content": ".image-width {\n  width: 1px;\n}\n.image-height {\n  height: 1px;\n}\n.image-size {\n  width: 1px 1px;\n}\n"
  },
  {
    "path": "packages/compiler-stylus/test/fixtures/css/guards.css",
    "content": "button {\n  foo: 1;\n}\n"
  },
  {
    "path": "packages/compiler-stylus/test/fixtures/css/import.css",
    "content": "body {\n  color: #ff0101;\n}\n"
  },
  {
    "path": "packages/compiler-stylus/test/fixtures/css/list-each.css",
    "content": ".sel-blue {\n  a: b;\n}\n.sel-green {\n  a: b;\n}\n.sel-red {\n  a: b;\n}\n"
  },
  {
    "path": "packages/compiler-stylus/test/fixtures/css/list.css",
    "content": ".image-width {\n  width: 1px;\n}\n.image-height {\n  height: 1px;\n}\n.image-size {\n  width: 1px 1px;\n}\n"
  },
  {
    "path": "packages/compiler-stylus/test/fixtures/css/selector.css",
    "content": ".button-ok {\n  foo: 1;\n}\n.button-cancel {\n  foo: 1;\n}\n.button-custom {\n  foo: 1;\n}\n.grand .parent > .grand .parent {\n  foo: 1;\n}\n.grand .parent + .grand .parent {\n  foo: 1;\n}\n.grand .parent .grand .parent {\n  foo: 1;\n}\n.grand .parent.grand .parent {\n  foo: 1;\n}\n.grand .parent,\n.grand .parentish {\n  foo: 1;\n}\n"
  },
  {
    "path": "packages/compiler-stylus/test/fixtures/css/uri.css",
    "content": ".img {\n  background: url(\"../stylus/imgs/vacant.gif\");\n  background: url(\"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\");\n}\n.img1 {\n  background: url(\"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\");\n}\n.img2 {\n  background-image: \"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\";\n}\n"
  },
  {
    "path": "packages/compiler-stylus/test/fixtures/stylus/alias.styl",
    "content": "@import '~@/colors.styl'\n\nbody\n  color $red\n"
  },
  {
    "path": "packages/compiler-stylus/test/fixtures/stylus/basic.styl",
    "content": "var = 50vh/2\nfloor = floor(1 + .1)\n\n.no-math\n  width: \"calc(50% + (%s - 20px))\" % var\n  foo: 1 + 2 calc(3 + 4) 5 + 6\n  bar: \"calc(%s + 20%)\" % floor\n"
  },
  {
    "path": "packages/compiler-stylus/test/fixtures/stylus/extend.styl",
    "content": "@import \"~@/modules\"\r\n\r\n#it-works\r\n  @extends .some-module\r\n  margin 0\r\n  transform rotate(15deg)\r\n"
  },
  {
    "path": "packages/compiler-stylus/test/fixtures/stylus/fail-missing-file.styl",
    "content": "@import 'missingfile.styl';\r\n\r\nbody\r\n  color red\r\n"
  },
  {
    "path": "packages/compiler-stylus/test/fixtures/stylus/fail-uri-alias.styl",
    "content": ".img-alias\r\n  background url(\"~@/vacant.gif\")\r\n  background data-uri(\"~@/vacant.gif\")\r\n"
  },
  {
    "path": "packages/compiler-stylus/test/fixtures/stylus/guards.styl",
    "content": "my-option = true\r\n\r\nif my-option\r\n  button\r\n    foo 1"
  },
  {
    "path": "packages/compiler-stylus/test/fixtures/stylus/import.styl",
    "content": "@import './vars/colors.styl'\nbody\n  color $red\n"
  },
  {
    "path": "packages/compiler-stylus/test/fixtures/stylus/list-each.styl",
    "content": "for $value in 'blue' 'green' 'red'\n  .sel-{$value}\n    a b\n"
  },
  {
    "path": "packages/compiler-stylus/test/fixtures/stylus/list.styl",
    "content": "$imagePath = 'imgs/vacant.gif'\n.image-width\n  width image-size($imagePath)[0]\n\n.image-height\n  height image-size($imagePath)[1]\n\n.image-size\n  width image-size($imagePath)\n"
  },
  {
    "path": "packages/compiler-stylus/test/fixtures/stylus/selector.styl",
    "content": ".button\r\n  &-ok\r\n    foo 1\r\n  &-cancel\r\n    foo 1\r\n  &-custom\r\n    foo 1\r\n\r\n.grand \r\n  .parent \r\n    & > & \r\n      foo 1\r\n    & + & \r\n      foo 1\r\n    & & \r\n      foo 1\r\n    &&\r\n      foo 1\r\n    &, &ish \r\n      foo 1\r\n"
  },
  {
    "path": "packages/compiler-stylus/test/fixtures/stylus/uri.styl",
    "content": "$base64 = \"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\";\r\n\r\n.img\r\n  background url(\"imgs/vacant.gif\")\r\n  background embedurl(\"imgs/vacant.gif\")\r\n\r\n.img1\r\n  background embedurl(\"imgs/vacant.gif\")\r\n\r\n.img2\r\n  background-image $base64\r\n"
  },
  {
    "path": "packages/compiler-stylus/test/fixtures/stylus/vars/colors.styl",
    "content": "$red = #ff0101\n"
  },
  {
    "path": "packages/compiler-stylus/test/fixtures/stylus/vars/modules.styl",
    "content": ".some-module\r\n  color red\r\n  transform scale(2)\r\n  .sub-module\r\n    color green"
  },
  {
    "path": "packages/compiler-stylus/test/helpers/specs.js",
    "content": "const fs = require('fs');\nconst path = require('path');\n\nconst stylusDir = path.resolve(__dirname, '../fixtures/stylus/');\n\nlet tests = null;\n\nconst options = {\n  basic: {\n    json: {},\n    string: [],\n    resolve: {}\n  },\n  alias: {\n    replace: [[/~@/g, '../stylus/vars']],\n    resolve: {\n      alias: {\n        '@': path.resolve(__dirname, '../fixtures/stylus/vars')\n      }\n    }\n  },\n  'fail-missing-file': {\n    error: 'fail-missing-file' // Error message.\n  },\n  'fail-uri-alias': {\n    then: true, // Consider as a success test case.\n    resolve: {\n      alias: {\n        '@': path.resolve(__dirname, '../fixtures/stylus/imgs')\n      }\n    }\n  },\n  extend: {\n    replace: [[/~@/g, '../stylus/vars']],\n    resolve: {\n      alias: {\n        '@': path.resolve(__dirname, '../fixtures/stylus/vars')\n      }\n    }\n  }\n};\n\nexports = module.exports = {\n  getIds() {\n    if (tests) {\n      return tests;\n    }\n    tests = fs\n      .readdirSync(stylusDir)\n      .filter(name => path.extname(name) === '.styl' && name.indexOf('.tmp') === -1)\n      .map(name => path.basename(name, '.styl'));\n    return tests;\n  },\n  getId(id) {\n    return options[id] || {};\n  },\n  getOpt(id) {\n    return this.getId(id).json || {};\n  },\n  getResolveOpt(id) {\n    return this.getId(id).resolve || {};\n  },\n  getStyluscOpt(id) {\n    return (this.getId(id).string || []).join(' ');\n  },\n  getReplacements(id) {\n    return this.getId(id).replace || [];\n  }\n};\n"
  },
  {
    "path": "packages/compiler-stylus/test/helpers/stylus.js",
    "content": "const { exec } = require('child_process');\nconst path = require('path');\nconst fs = require('fs-extra');\nconst specs = require('./specs');\n\nconst styluscPath = require.resolve('.bin/stylus');\n\nconst projectPath = path.resolve(__dirname, '..', '..');\nconst fixturesPath = path.resolve(projectPath, 'test', 'fixtures');\nconst stylusPath = path.resolve(fixturesPath, 'stylus');\nconst cssPath = path.resolve(fixturesPath, 'css');\n\n// Ignore the fail test cases;\nlet ids = specs.getIds().filter(v => !/^fail-/.test(v));\n\nids.forEach(id => {\n  const stylusFile = path.join(stylusPath, `${id}.styl`);\n  const css = path.join(cssPath, `${id}.css`);\n  const tmpstylus = path.join(stylusPath, `${id}.tmp.styl`);\n\n  let replaces = specs.getReplacements(id);\n\n  let content = fs.readFileSync(stylusFile, 'utf-8');\n\n  replaces.forEach(r => {\n    content = content.replace(r[0], r[1]);\n  });\n  fs.outputFileSync(tmpstylus, content);\n\n  let options = specs.getStyluscOpt(id);\n\n  const relativeUrls = '--resolve-url';\n  let cmd = `${styluscPath} ${relativeUrls} ${options} ${tmpstylus} ${css}`;\n\n  // eslint-disable-next-line\n  console.log(`Generate spec: ${id}`);\n\n  exec(cmd, { cwd: projectPath }, (err, stdout, stderr) => {\n    if (err || stderr) {\n      err = err || new Error(stderr);\n      throw err;\n    }\n    if (stdout) fs.removeSync(tmpstylus);\n  });\n});\n"
  },
  {
    "path": "packages/compiler-stylus/test/index.test.js",
    "content": "const path = require('path');\nconst fs = require('fs-extra');\nconst expect = require('chai').expect;\nconst stylusPlugin = require('../index');\nconst specs = require('./helpers/specs');\nconst ResolverFactory = require('enhanced-resolve').ResolverFactory;\nconst NodeJsInputFileSystem = require('enhanced-resolve/lib/NodeJsInputFileSystem');\nconst CachedInputFileSystem = require('enhanced-resolve/lib/CachedInputFileSystem');\n\nclass Hook {\n  constructor() {}\n\n  register(key, fn) {\n    if (!this._fns) this._fns = {};\n    this._fns[key] = fn;\n  }\n  hook(key, ...args) {\n    return this._fns[key].apply(this, args);\n  }\n  clear() {\n    this._fns = {};\n  }\n}\n\nfunction createCompile(stylusOpt, resolveOpt) {\n  let instance = new Hook();\n  stylusPlugin(stylusOpt).call(instance);\n\n  instance.resolvers = {\n    normal: ResolverFactory.createResolver(\n      Object.assign(\n        {\n          fileSystem: new CachedInputFileSystem(new NodeJsInputFileSystem(), 60000)\n        },\n        resolveOpt\n      )\n    )\n  };\n\n  instance.logger = {\n    error(e) {\n      /* eslint-disable no-console */\n      console.log('======= ERROR OUTPUT ======');\n      console.log(e);\n      /* eslint-enable no-console */\n    }\n  };\n\n  let fnNormalBak = instance.resolvers.normal.resolve;\n  instance.resolvers.normal.resolve = function(...args) {\n    return new Promise((resolve, reject) => {\n      args.push(function(err, filepath, meta) {\n        if (err) {\n          reject(err);\n        } else {\n          resolve({ path: filepath, meta: meta });\n        }\n      });\n      fnNormalBak.apply(instance.resolvers.normal, args);\n    });\n  };\n  return instance;\n}\n\nfunction readSpec(id, isFailSpec) {\n  let stylusfile = path.join(__dirname, 'fixtures', 'stylus', id + '.styl');\n  let expectfile = isFailSpec ? '' : path.join(__dirname, 'fixtures', 'css', id + '.css');\n\n  return {\n    node: {\n      content: fs.readFileSync(stylusfile, 'utf-8')\n    },\n    file: stylusfile,\n    expect: isFailSpec ? '' : fs.readFileSync(expectfile, 'utf-8')\n  };\n}\n\nfunction compare(id, done) {\n  let compile = createCompile(specs.getOpt(id), specs.getResolveOpt(id));\n\n  let spec = readSpec(id);\n  return compile\n    .hook('wepy-compiler-stylus', spec.node, spec.file)\n    .then(node => {\n      let css = node.compiled.code;\n      expect(css).to.equal(spec.expect);\n      done();\n    })\n    .catch(e => {\n      done(e);\n    });\n}\n\nfunction compileFail(id, done) {\n  let compile = createCompile(specs.getOpt(id), specs.getResolveOpt(id));\n\n  let spec = readSpec(id, true);\n\n  let setting = specs.getId(id);\n\n  return compile\n    .hook('wepy-compiler-stylus', spec.node, spec.file)\n    .then(() => {\n      // e.g. uri-alias, alias is not awared in uri, so treat as compile successfully.\n      if (setting.then) {\n        done();\n      }\n    })\n    .catch(e => {\n      if (setting.error) {\n        expect(e.lineno).to.be.gt(0);\n        expect(e.filename).to.have.string(setting.error);\n      } else {\n        expect(e).to.be.an('error');\n      }\n      done();\n    });\n}\n\ndescribe('wepy-compiler-stylus', function() {\n  let ids = specs.getIds();\n\n  let shouldPassIds = ids.filter(id => !/^fail-/.test(id));\n\n  let shouldFailIds = ids.filter(id => /^fail-/.test(id));\n\n  shouldPassIds.forEach(id => {\n    it('Pass test cases: ' + id, function(done) {\n      compare(id, done);\n    });\n  });\n  shouldFailIds.forEach(id => {\n    it('Fail test cases: ' + id, function(done) {\n      compileFail(id, done);\n    });\n  });\n});\n"
  },
  {
    "path": "packages/compiler-typescript/.npmignore",
    "content": "src\ntest\nnode_modules"
  },
  {
    "path": "packages/compiler-typescript/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n# 2.1.0 (2020-07-04)\n\n**Note:** Version bump only for package @wepy/compiler-typescript\n\n\n\n\n\n# 2.1.0-alpha.10 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-typescript\n\n\n\n\n\n# 2.1.0-alpha.9 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-typescript\n\n\n\n\n\n# 2.1.0-alpha.8 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-typescript\n\n\n\n\n\n# 2.1.0-alpha.7 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-typescript\n\n\n\n\n\n# 2.1.0-alpha.6 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-typescript\n\n\n\n\n\n# 2.1.0-alpha.5 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/compiler-typescript\n\n\n\n\n\n# [2.1.0-alpha.4](https://github.com/Tencent/wepy/compare/v2.1.0-alpha.2...v2.1.0-alpha.4) (2020-06-20)\n\n**Note:** Version bump only for package @wepy/compiler-typescript\n"
  },
  {
    "path": "packages/compiler-typescript/README.md",
    "content": "# wepy typescript 编译器\n\n## 安装\n\n```\nnpm install @wepy/compiler-typescript typescript --save-dev\n```\n\n## 配置`wepy.config.js`\n\n```\n\nconst TypeScriptCompiler = require('@wepy/compiler-typescript');\n\n\nmodule.exports = {\n  \"plugins\": [\n      TypeScriptCompiler()\n  ]\n};\n```\n\n## 参数说明\n\n[TypeScript](https://www.typescriptlang.org/docs/handbook/compiler-options.html)\n"
  },
  {
    "path": "packages/compiler-typescript/index.js",
    "content": "/**\n * Tencent is pleased to support the open source community by making WePY available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n *\n * Licensed under the MIT License (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n * http://opensource.org/licenses/MIT\n * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n */\nconst path = require('path');\nconst ts = require('typescript');\n\nexports = module.exports = function(options) {\n  return function() {\n    this.register('wepy-compiler-typescript', function(node, ctx) {\n      let p;\n      let file = typeof ctx === 'string' ? ctx : ctx.file;\n      let source = node.content;\n      let params = Object.assign(\n        {},\n        {\n          fileName: file,\n          compilerOptions: {\n            esModuleInterop: true,\n            module: ts.ModuleKind.CommonJS\n          }\n        },\n        options\n      );\n      try {\n        let compiled = ts.transpileModule(source, params);\n        compiled.code = compiled.outputText;\n        let fileObj = path.parse(ctx.file);\n        delete compiled.outputText;\n        node.compiled = compiled;\n\n        compiled.outputFileName = fileObj.name + '.js';\n        p = Promise.resolve(node);\n      } catch (e) {\n        this.hookUnique('error-handler', {\n          type: 'error',\n          title: 'babel',\n          file: file,\n          message: e.message,\n          snapshot: e.codeFrame\n        });\n        p = Promise.reject(e);\n      }\n      return p;\n    });\n\n    // eslint-disable-next-line\n    this.register('prewalk-VariableDeclarator', function(walker, declarator, name, decl) {\n      if (walker.lang !== 'typescript') return;\n      // var core_1 = __importDefault(require('@wepy/core'))\n      if (declarator.init && declarator.init.type === 'CallExpression') {\n        if (declarator.init.callee.name === '__importDefault') {\n          let arg = declarator.init.arguments[0];\n          if (\n            arg &&\n            arg.type === 'CallExpression' &&\n            arg.callee.name === 'require' &&\n            arg.arguments[0].value === '@wepy/core'\n          ) {\n            walker.scope.instances.push(name + '.default');\n          }\n        }\n        /*\n         * var core_1 = require('@wepy/core');\n        if (declarator.init.callee.name === 'require') {\n          if (declarator.init.arguments && declarator.init.arguments[0] && declarator.init.arguments[0].value === '@wepy/core') {\n            walker.scope.instances.push(name + '.default');\n          }\n        }*/\n      }\n    });\n\n    this.register('walker-detect-entry', function(walker, expression, exprName) {\n      if (walker.lang !== 'typescript') return;\n      if (walker.scope.instances && walker.scope.instances.length && exprName) {\n        if (exprName.callee === 'app' || exprName.callee === 'page' || exprName.callee === 'component') {\n          if (walker.scope.instances.indexOf(exprName.instance) !== -1) {\n            walker.entry = expression;\n          }\n        }\n      }\n    });\n  };\n};\n"
  },
  {
    "path": "packages/compiler-typescript/package.json",
    "content": "{\n  \"name\": \"@wepy/compiler-typescript\",\n  \"version\": \"2.1.0\",\n  \"description\": \"wepy compile typescript\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"keywords\": [\n    \"typescript\"\n  ],\n  \"author\": {\n    \"name\": \"Gcaufy\"\n  },\n  \"license\": \"MIT\",\n  \"readme\": \"ERROR: No README data found!\",\n  \"peerDependencies\": {\n    \"typescript\": \"^3.3.3\"\n  },\n  \"_id\": \"@wepy/compiler-typescript@2.0.2\",\n  \"_commitid\": \"eae8bf5\",\n  \"gitHead\": \"5a25776457360bbbbc54a4d059f6bc7c032d5df3\"\n}\n"
  },
  {
    "path": "packages/core/.nycrc",
    "content": "{\n  \"reporter\": [\n    \"html\",\n    \"text\",\n    \"text-summary\"\n  ],\n  \"include\": [\n    \"src/**/*.js\"\n  ],\n  \"require\": [\n    \"esm\"\n  ],\n  \"check-coverage\": false,\n  \"cache\": true\n}\n"
  },
  {
    "path": "packages/core/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n# 2.1.0 (2020-07-04)\n\n**Note:** Version bump only for package @wepy/core\n\n\n\n\n\n# 2.1.0-alpha.10 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/core\n\n\n\n\n\n# 2.1.0-alpha.9 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/core\n\n\n\n\n\n# 2.1.0-alpha.8 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/core\n\n\n\n\n\n# 2.1.0-alpha.7 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/core\n\n\n\n\n\n# 2.1.0-alpha.6 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/core\n\n\n\n\n\n# 2.1.0-alpha.5 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/core\n\n\n\n\n\n# [2.1.0-alpha.4](https://github.com/Tencent/wepy/compare/v2.1.0-alpha.2...v2.1.0-alpha.4) (2020-06-20)\n\n\n### Bug Fixes\n\n* fixed eslint ([570050e](https://github.com/Tencent/wepy/commit/570050edb292ce75cc06a75448819c753275ecb4))\n"
  },
  {
    "path": "packages/core/ant/apis/index.js",
    "content": "import { use } from '../../weapp/apis/use';\nimport { mixin } from '../../weapp/apis/mixin';\nimport { set, del, observe } from '../../weapp/observer/index';\nimport { renderNextTick } from '../../weapp/util/next-tick';\nimport { app, page, component } from '../native/index';\n\nexport function initGlobalAPI(wepy) {\n  wepy.use = use;\n  wepy.mixin = mixin;\n\n  wepy.set = function(target, key, val) {\n    set.apply(wepy, [undefined, target, key, val]);\n  };\n\n  wepy.delete = del;\n\n  wepy.observe = observe;\n\n  wepy.nextTick = renderNextTick;\n\n  wepy.app = app;\n  wepy.page = page;\n  wepy.component = component;\n\n  return wepy;\n}\n"
  },
  {
    "path": "packages/core/ant/class/WepyComponent.js",
    "content": "import Base from './../../weapp/class/Base';\nimport Watcher from './../../weapp/observer/watcher';\nimport { isArr, isPlainObject } from '../../shared/index';\nimport { renderNextTick } from './../../weapp/util/next-tick';\n\nexport default class WepyComponent extends Base {\n  $watch(expOrFn, cb, options) {\n    let vm = this;\n    if (isArr(cb)) {\n      cb.forEach(handler => {\n        this.$watch(expOrFn, handler, options);\n      });\n    }\n    if (isPlainObject(cb)) {\n      let handler = cb;\n      options = handler;\n      handler = handler.handler;\n      if (typeof handler === 'string') handler = this[handler];\n      return this.$watch(expOrFn, handler, options);\n    }\n\n    options = options || {};\n    options.user = true;\n    let watcher = new Watcher(vm, expOrFn, cb, options);\n    if (options.immediate) {\n      cb.call(vm, watcher.value);\n    }\n    return function unwatchFn() {\n      watcher.teardown();\n    };\n  }\n\n  $forceUpdate() {\n    if (this._watcher) {\n      this._watcher.update();\n    }\n  }\n}\n\nWepyComponent.prototype.$nextTick = renderNextTick;\n"
  },
  {
    "path": "packages/core/ant/class/WepyPage.js",
    "content": "import WepyComponent from './WepyComponent';\nimport { isStr, isNum, isObj, isUndef, isFunc } from '../../shared/index';\n\n// eslint-disable-next-line\nlet wx = my;\nexport default class WepyPage extends WepyComponent {\n  $launch(url, params) {\n    this.$route('reLaunch', url, params);\n  }\n  $navigate(url, params) {\n    this.$route('navigate', url, params);\n  }\n\n  $redirect(url, params) {\n    this.$route('redirect', url, params);\n  }\n\n  $back(p = {}) {\n    if (isNum(p)) p = { delta: p };\n\n    if (!p.delta) p.delta = 1;\n\n    return wx.navigateBack(p);\n  }\n\n  $route(type, url, params = {}) {\n    let wxparams;\n    if (isStr(url)) {\n      let paramsList = [];\n      if (isObj(params)) {\n        for (let k in params) {\n          if (!isUndef(params[k])) {\n            paramsList.push(`${k}=${encodeURIComponent(params[k])}`);\n          }\n        }\n      }\n      if (paramsList.length) url = url + '?' + paramsList.join('&');\n\n      wxparams = { url: url };\n    } else {\n      wxparams = url;\n    }\n    let fn = wx[type] || wx[type + 'To'];\n    if (isFunc(fn)) {\n      return fn(wxparams);\n    }\n  }\n}\n"
  },
  {
    "path": "packages/core/ant/init/events.js",
    "content": "/*\n * initialize events\n */\nexport function initEvents(vm) {\n  let parent = vm.$parent;\n  let rel = parent.$rel;\n  vm._events = {};\n  let on = rel.info.on;\n  let evtId = vm.$evtId;\n  if (!evtId) return;\n\n  let evtNames = on[evtId];\n\n  evtNames.forEach(evtName => {\n    vm.$on(evtName, function() {\n      let fn = rel.handlers[evtId][evtName];\n      fn.apply(parent, arguments);\n    });\n  });\n}\n"
  },
  {
    "path": "packages/core/ant/init/index.js",
    "content": "export * from '../../weapp/init/data';\nexport * from '../../weapp/init/computed';\nexport * from './lifecycle';\nexport * from './methods';\nexport * from '../../weapp/init/watch';\nexport * from './props';\nexport * from '../../weapp/init/mixins';\nexport * from '../../weapp/init/hooks';\nexport * from '../../weapp/init/relations';\n"
  },
  {
    "path": "packages/core/ant/init/lifecycle.js",
    "content": "import WepyApp from '../../weapp/class/WepyApp';\nimport WepyPage from '../class/WepyPage';\nimport WepyComponent from '../../weapp/class/WepyComponent';\n\nimport { initHooks } from '../../weapp/init/hooks';\nimport { initProps } from './props';\nimport { initWatch } from '../../weapp/init/watch';\nimport { initRender } from '../../weapp/init/render';\nimport { initData } from '../../weapp/init/data';\nimport { initComputed } from '../../weapp/init/computed';\nimport { initMethods } from './methods';\nimport { initEvents } from './events';\nimport { isArr, isFunc } from '../../shared/index';\nimport Dirty from '../../weapp/class/Dirty';\nimport { WEAPP_APP_LIFECYCLE, WEAPP_PAGE_LIFECYCLE, WEAPP_COMPONENT_LIFECYCLE } from '../../shared/index';\nimport { warn } from '../../weapp/util/index';\n\nlet comid = 0;\nlet app;\n\nconst callUserMethod = function(vm, userOpt, method, args) {\n  let result;\n  let methods = userOpt[method];\n  if (isFunc(methods)) {\n    result = userOpt[method].apply(vm, args);\n  } else if (isArr(methods)) {\n    for (let i in methods) {\n      if (isFunc(methods[i])) {\n        result = methods[i].apply(vm, args);\n      }\n    }\n  }\n  return result;\n};\n\nconst getLifecycycle = (defaultLifecycle, rel, type) => {\n  let lifecycle = defaultLifecycle.concat([]);\n  if (rel && rel.lifecycle && rel.lifecycle[type]) {\n    let userDefinedLifecycle = [];\n    if (isFunc(rel.lifecycle[type])) {\n      userDefinedLifecycle = rel.lifecycle[type].call(null, lifecycle);\n    }\n    userDefinedLifecycle.forEach(u => {\n      if (lifecycle.indexOf(u) > -1) {\n        warn(`'${u}' is already implemented in current version, please remove it from your lifecycel config`);\n      } else {\n        lifecycle.push(u);\n      }\n    });\n  }\n  return lifecycle;\n};\n\n/*\n * patch app lifecyle\n */\nexport function patchAppLifecycle(appConfig, options, rel = {}) {\n  appConfig.onLaunch = function(...args) {\n    let vm = new WepyApp();\n    app = vm;\n    vm.$options = options;\n    vm.$route = {};\n    vm.$rel = rel;\n\n    vm.$wx = this;\n    this.$wepy = vm;\n\n    initHooks(vm, options.hooks);\n\n    initMethods(vm, options.methods);\n\n    return callUserMethod(vm, vm.$options, 'onLaunch', args);\n  };\n\n  let lifecycle = getLifecycycle(WEAPP_APP_LIFECYCLE, rel, 'app');\n\n  lifecycle.forEach(k => {\n    // it's not defined aready && user defined it && it's an array or function\n    if (!appConfig[k] && options[k] && (isFunc(options[k]) || isArr(options[k]))) {\n      appConfig[k] = function(...args) {\n        return callUserMethod(app, app.$options, k, args);\n      };\n    }\n  });\n}\n\nexport function patchLifecycle(output, options, rel, isComponent) {\n  const initClass = isComponent ? WepyComponent : WepyPage;\n  const initLifecycle = function(...args) {\n    let vm = new initClass();\n\n    vm.$dirty = new Dirty('path');\n    vm.$children = [];\n    vm.$refs = {};\n\n    this.$wepy = vm;\n    vm.$wx = this;\n    vm.$is = this.is;\n    vm.$options = options;\n    vm.$rel = rel;\n    vm._watchers = [];\n    if (!isComponent) {\n      vm.$root = vm;\n      vm.$app = app;\n    }\n    if (this.is === 'custom-tab-bar/index') {\n      vm.$app = app;\n      vm.$parent = app;\n    }\n\n    vm.$id = ++comid + (isComponent ? '.1' : '.0');\n    if (!vm.$app) {\n      // vm.$app = $global.$app;\n    }\n\n    callUserMethod(vm, vm.$options, 'beforeCreate', args);\n\n    initHooks(vm, options.hooks);\n\n    initProps(vm, output.properties);\n\n    initData(vm, output.data, isComponent);\n\n    initMethods(vm, options.methods);\n\n    initComputed(vm, options.computed, true);\n\n    initWatch(vm, options.watch);\n\n    // create render watcher\n    initRender(\n      vm,\n      Object.keys(vm._data)\n        .concat(Object.keys(vm._props))\n        .concat(Object.keys(vm._computedWatchers || {})),\n      Object.keys(vm._computedWatchers || {})\n    );\n\n    callUserMethod(vm, vm.$options, 'created', args);\n    return callUserMethod(vm, vm.$options, 'onLoad', args);\n  };\n\n  if (isComponent) {\n    output.onInit = initLifecycle; // 组件生命周期函数，组件创建时触发\n  } else {\n    output.onLoad = initLifecycle; // 页面加载时触发\n  }\n\n  if (isComponent) {\n    output.didMount = function(...args) {\n      // Component attached  组件生命周期函数，组件创建完毕时触发\n      let outProps = output.properties || {};\n\n      // this.propperties are includes datas\n      let vm = this.$wepy;\n      let acceptProps = vm.$wx.props;\n\n      // let target = isComponent ? output.methods: output;\n      // target.__initComponent(vm);\n      vm.$wx.props.onInit(vm);\n      // let parent = this.triggerEvent('_init', vm);\n\n      // created 不能调用 setData，如果有 dirty 在此更新\n      vm.$forceUpdate();\n\n      initEvents(vm);\n\n      Object.keys(outProps).forEach(k => (vm[k] = acceptProps[k]));\n\n      return callUserMethod(vm, vm.$options, 'didMount', args);\n    };\n  } else {\n    output.onShow = function(...args) {\n      // Page attached\n      let vm = this.$wepy;\n      let app = vm.$app;\n      // eslint-disable-next-line\n      let pages = getCurrentPages();\n      let currentPage = pages[pages.length - 1];\n      let path = currentPage.__route__;\n      let webViewId = currentPage.__wxWebviewId__;\n\n      // created 不能调用 setData，如果有 dirty 在此更新\n      vm.$forceUpdate();\n\n      if (app.$route.path !== path) {\n        app.$route.path = path;\n        app.$route.webViewId = webViewId;\n        vm.routed && vm.routed();\n      }\n\n      // TODO: page attached\n      return callUserMethod(vm, vm.$options, 'onShow', args);\n    };\n    // Page lifecycle will be called under methods\n    // e.g:\n    // Component({\n    //   methods: {\n    //     onLoad () {\n    //       console.log('page onload')\n    //     }\n    //   }\n    // })\n\n    let lifecycle = getLifecycycle(WEAPP_PAGE_LIFECYCLE, rel, 'page');\n\n    lifecycle.forEach(k => {\n      if (!output[k] && options[k] && (isFunc(options[k]) || isArr(options[k]))) {\n        output.methods[k] = function(...args) {\n          return callUserMethod(this.$wepy, this.$wepy.$options, k, args);\n        };\n      }\n    });\n  }\n  let lifecycle = getLifecycycle(WEAPP_COMPONENT_LIFECYCLE, rel, 'component');\n\n  lifecycle.forEach(k => {\n    // beforeCreate is not a real lifecycle\n    if (!output[k] && k !== 'beforeCreate' && (isFunc(options[k]) || isArr(options[k]))) {\n      output[k] = function(...args) {\n        return callUserMethod(this.$wepy, this.$wepy.$options, k, args);\n      };\n    }\n  });\n}\n"
  },
  {
    "path": "packages/core/ant/init/methods.js",
    "content": "import { warn } from '../../weapp/util/index';\nimport { dispatcher } from '../../weapp/dispatcher/index';\n\n/*\n * initialize page methods, also the app\n */\nexport function initMethods(vm, methods) {\n  if (methods) {\n    Object.keys(methods).forEach(method => {\n      vm[method] = methods[method];\n    });\n  }\n}\n\n/*\n * patch method option\n */\nexport function patchMethods(output, methods, isComponent) {\n  output.methods = {};\n  let target = isComponent ? output.methods : output;\n\n  target.__initComponent = function(e) {\n    let child = e;\n    var ref = e.$wx.props['data-ref'];\n    var wpyEvt = e.$wx.props['data-wpy-evt'];\n\n    let vm = this.$wepy;\n    vm.$children.push(child);\n    if (ref) {\n      if (vm.$refs[ref]) {\n        warn('duplicate ref \"' + ref + '\" will be covered by the last instance.\\n', vm);\n      }\n      vm.$refs[ref] = child;\n    }\n    child.$evtId = wpyEvt;\n    child.$parent = vm;\n    child.$app = vm.$app;\n    child.$root = vm.$root;\n    // 支付宝组件嵌套时，子组件执行早已组件\n    if (e.$children && e.$children.length) {\n      e.$children.forEach(x => {\n        x.$app = vm.$app;\n        x.$root = vm.$root;\n      });\n    }\n    return vm;\n  };\n  target.__dispatcher = dispatcher;\n\n  // TODO: perf\n  // Only orginal component method goes to target. no need to add all methods.\n  if (methods) {\n    Object.keys(methods).forEach(method => {\n      target[method] = methods[method];\n    });\n  }\n}\n"
  },
  {
    "path": "packages/core/ant/init/props.js",
    "content": "import { observe } from '../../weapp/observer/index';\nimport { proxy } from '../../weapp/init/data';\nimport { isArr, isStr, isObj } from '../../weapp/util/index';\n\nconst observerFn = function() {\n  return function(newVal, oldVal, changedPaths) {\n    let vm = this.$wepy;\n\n    // changedPaths 长度大于 1，说明是由内部赋值改变的 prop\n    if (changedPaths.length > 1) {\n      return;\n    }\n    let _data = newVal;\n    if (typeof _data === 'function') {\n      _data = _data.call(vm);\n    }\n    vm[changedPaths[0]] = _data;\n  };\n};\n/*\n * patch props option\n */\nexport function patchProps(output, props) {\n  let newProps = {};\n  if (isStr(props)) {\n    newProps = [props];\n  }\n  if (isArr(props)) {\n    props.forEach(prop => {\n      newProps[prop] = {\n        type: null,\n        observer: observerFn(output, props, prop)\n      };\n    });\n  } else if (isObj(props)) {\n    for (let k in props) {\n      let prop = props[k];\n\n      // notsupport obj\n      if (!isObj(prop)) {\n        newProps[k] = prop;\n      } else {\n        newProps[k] = prop.default ? prop.default : '';\n      }\n    }\n  }\n\n  newProps['onInit'] = '';\n  output.properties = newProps;\n}\n\n/*\n * init props\n */\nexport function initProps(vm, properties) {\n  vm._props = {};\n\n  if (!properties) {\n    return;\n  }\n\n  Object.keys(properties).forEach(key => {\n    vm._props[key] = properties[key].value;\n    proxy(vm, '_props', key);\n  });\n\n  observe({\n    vm: vm,\n    key: '',\n    value: vm._props,\n    root: true\n  });\n}\n"
  },
  {
    "path": "packages/core/ant/native/app.js",
    "content": "import { patchMixins, patchAppLifecycle } from '../init/index';\n\nexport function app(option, rel) {\n  let appConfig = {};\n\n  patchMixins(appConfig, option, option.mixins);\n  patchAppLifecycle(appConfig, option, rel);\n\n  return App(appConfig);\n}\n"
  },
  {
    "path": "packages/core/ant/native/component.js",
    "content": "import { patchMixins, patchMethods, patchData, patchLifecycle, patchProps, patchRelations } from '../init/index';\n\nexport function component(opt = {}, rel) {\n  let compConfig = {\n    externalClasses: opt.externalClasses || [],\n    // support component options property\n    // example: options: {addGlobalClass:true}\n    options: opt.options || {}\n  };\n\n  patchMixins(compConfig, opt, opt.mixins);\n\n  if (opt.properties) {\n    compConfig.props = opt.properties;\n    if (opt.props) {\n      // eslint-disable-next-line no-console\n      console.warn(`props will be ignore, if properties is set`);\n    }\n  } else if (opt.props) {\n    patchProps(compConfig, opt.props);\n  }\n\n  compConfig.props = compConfig.properties;\n\n  patchMethods(compConfig, opt.methods, true);\n\n  patchData(compConfig, opt.data, true);\n\n  patchRelations(compConfig, opt.relations);\n\n  patchLifecycle(compConfig, opt, rel, true);\n\n  return Component(compConfig);\n}\n"
  },
  {
    "path": "packages/core/ant/native/index.js",
    "content": "export * from './app';\nexport * from './component';\nexport * from './page';\n"
  },
  {
    "path": "packages/core/ant/native/page.js",
    "content": "import { patchMixins, patchData, patchMethods, patchLifecycle, patchProps } from '../init/index';\n\nexport function page(opt = {}, rel) {\n  let pageConfig = {\n    externalClasses: opt.externalClasses || [],\n    // support component options property\n    // example: options: {addGlobalClass:true}\n    options: opt.options || {}\n  };\n\n  patchMixins(pageConfig, opt, opt.mixins);\n\n  if (opt.properties) {\n    pageConfig.properties = opt.properties;\n    if (opt.props) {\n      // eslint-disable-next-line\n      console.warn(`props will be ignore, if properties is set`);\n    }\n  } else if (opt.props) {\n    patchProps(pageConfig, opt.props);\n  }\n\n  patchMethods(pageConfig, opt.methods);\n\n  patchData(pageConfig, opt.data);\n\n  patchLifecycle(pageConfig, opt, rel);\n\n  return Page(pageConfig);\n}\n"
  },
  {
    "path": "packages/core/ant/wepy.js",
    "content": "import WepyConstructor from '../weapp/class/WepyConstructor';\nimport $global from '../weapp/global';\nimport { initGlobalAPI } from './apis/index';\nimport { config } from '../weapp/config';\n\nconst wepy = initGlobalAPI(WepyConstructor);\n\nwepy.config = config;\nwepy.global = $global;\nwepy.version = __VERSION__;\n\nexport default wepy;\n"
  },
  {
    "path": "packages/core/dist/wepy.ant.js",
    "content": "'use strict';\n\n// can we use __proto__?\nfunction getHasProto() {\n  var hasProto = false;\n  if ('__proto__' in {}) {\n    var fn = function () {};\n    var arr = [];\n    arr.__proto__ = { push: fn };\n    hasProto = fn === arr.push;\n  }\n  return hasProto;\n}\nvar hasProto = getHasProto();\n\nvar _Set; // $flow-disable-line\n/* istanbul ignore if */ if (typeof Set !== 'undefined' && isNative(Set)) {\n  // use native Set when available.\n  _Set = Set;\n} else {\n  // a non-standard Set polyfill that only works with primitive keys.\n  _Set = /*@__PURE__*/(function () {\n    function Set() {\n      this.set = Object.create(null);\n    }\n    Set.prototype.has = function has (key) {\n      return this.set[key] === true;\n    };\n    Set.prototype.add = function add (key) {\n      this.set[key] = true;\n    };\n    Set.prototype.clear = function clear () {\n      this.set = Object.create(null);\n    };\n\n    return Set;\n  }());\n}\n\n/* istanbul ignore next */\nfunction isNative(Ctor) {\n  return typeof Ctor === 'function' && /native code/.test(Ctor.toString());\n}\n\n/**\n * String type check\n */\nvar isStr = function (v) { return typeof v === 'string'; };\n/**\n * Number type check\n */\nvar isNum = function (v) { return typeof v === 'number'; };\n/**\n * Array type check\n */\nvar isArr = Array.isArray;\n/**\n * undefined type check\n */\nvar isUndef = function (v) { return v === undefined; };\n/**\n * Function type check\n */\nvar isFunc = function (v) { return typeof v === 'function'; };\n/**\n * Quick object check - this is primarily used to tell\n * Objects from primitive values when we know the value\n * is a JSON-compliant type.\n */\nfunction isObject(obj) {\n  return obj !== null && typeof obj === 'object';\n}\n\nvar isObj = isObject;\n/**\n * Strict object type check. Only returns true\n * for plain JavaScript objects.\n */\nvar _toString = Object.prototype.toString;\nfunction isPlainObject(obj) {\n  return _toString.call(obj) === '[object Object]';\n}\n\n/**\n * Check whether the object has the property.\n */\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\nfunction hasOwn(obj, key) {\n  return hasOwnProperty.call(obj, key);\n}\n\n/**\n * Perform no operation.\n * Stubbing args to make Flow happy without leaving useless transpiled code\n * with ...rest (https://flow.org/blog/2017/05/07/Strict-Function-Call-Arity/)\n */\n// eslint-disable-next-line\nfunction noop(a, b, c) {}\n\n/**\n * Check if val is a valid array index.\n */\nfunction isValidArrayIndex(val) {\n  var n = parseFloat(String(val));\n  return n >= 0 && Math.floor(n) === n && isFinite(val);\n}\n\n/**\n * Convert an Array-lik object to a real Array\n */\nfunction toArray(list, start) {\n  if ( start === void 0 ) start = 0;\n\n  var i = list.length - start;\n  var rst = new Array(i);\n  while (i--) {\n    rst[i] = list[i + start];\n  }\n  return rst;\n}\n\n/**\n * Cached simply key function return\n */\nvar cached = function (fn) {\n  var cache = {};\n  return function (str) { return cache[str] || (cache[str] = fn(str)); };\n};\n\nvar camelizeRE = /-(\\w)/g;\n\n/**\n * camelize words\n * e.g. my-key => myKey\n */\nvar camelize = cached(function (str) { return str.replace(camelizeRE, function (_, c) { return (c ? c.toUpperCase() : ''); }); });\n\n/*\n * extend objects\n * e.g.\n * extend({}, {a: 1}) : extend {a: 1} to {}\n * extend(true, [], [1,2,3]) : deep extend [1,2,3] to an empty array\n * extend(true, {}, {a: 1}, {b: 2}) : deep extend two objects to {}\n */\nfunction extend() {\n  var arguments$1 = arguments;\n\n  var options,\n    name,\n    src,\n    copy,\n    copyIsArray,\n    clone,\n    target = arguments[0] || {},\n    i = 1,\n    length = arguments.length,\n    deep = false;\n\n  // Handle a deep copy situation\n  if (typeof target === 'boolean') {\n    deep = target;\n\n    // Skip the boolean and the target\n    target = arguments[i] || {};\n    i++;\n  }\n\n  // Handle case when target is a string or something (possible in deep copy)\n  if (typeof target !== 'object' && !(typeof target === 'function')) {\n    target = {};\n  }\n\n  // Extend jQuery itself if only one argument is passed\n  if (i === length) {\n    target = this;\n    i--;\n  }\n\n  for (; i < length; i++) {\n    // Only deal with non-null/undefined values\n    if ((options = arguments$1[i])) {\n      // Extend the base object\n      for (name in options) {\n        src = target[name];\n        copy = options[name];\n\n        // Prevent never-ending loop\n        if (target === copy) {\n          continue;\n        }\n\n        // Recurse if we're merging plain objects or arrays\n        if (deep && copy && (isPlainObject(copy) || (copyIsArray = Array.isArray(copy)))) {\n          if (copyIsArray) {\n            copyIsArray = false;\n            clone = src && Array.isArray(src) ? src : [];\n          } else {\n            clone = src && isPlainObject(src) ? src : {};\n          }\n\n          // Never move original objects, clone them\n          target[name] = extend(deep, clone, copy);\n\n          // Don't bring in undefined values => bring undefined values\n        } else {\n          target[name] = copy;\n        }\n      }\n    }\n  }\n\n  // Return the modified object\n  return target;\n}\n\n/*\n * clone objects, return a cloned object default to use deep clone\n * e.g.\n * clone({a: 1})\n * clone({a: b: {c : 1}}, false);\n */\nfunction clone(sth, deep) {\n  if ( deep === void 0 ) deep = true;\n\n  if (isArr(sth)) {\n    return extend(deep, [], sth);\n  } else if ('' + sth === 'null') {\n    return sth;\n  } else if (isPlainObject(sth)) {\n    return extend(deep, {}, sth);\n  } else {\n    return sth;\n  }\n}\n\nvar WEAPP_APP_LIFECYCLE = ['onLaunch', 'onShow', 'onHide', 'onError', 'onPageNotFound'];\n\nvar WEAPP_PAGE_LIFECYCLE = [\n  'onLoad',\n  'onShow',\n  'onReady',\n  'onHide',\n  'onUnload',\n  'onPullDownRefresh',\n  'onReachBottom',\n  'onShareAppMessage',\n  'onPageScroll',\n  'onTabItemTap',\n  'onResize'\n];\n\nvar WEAPP_COMPONENT_LIFECYCLE = ['beforeCreate', 'created', 'attached', 'ready', 'moved', 'detached'];\n\nvar WEAPP_LIFECYCLE = []\n  .concat(WEAPP_APP_LIFECYCLE)\n  .concat(WEAPP_PAGE_LIFECYCLE)\n  .concat(WEAPP_COMPONENT_LIFECYCLE);\n\nvar config = {};\n\nvar warn = noop;\n\nvar generateComponentTrace = function(vm) {\n  return (\"Found in component: \\\"\" + (vm.$is) + \"\\\"\");\n};\n\n{\n  var hasConsole = typeof console !== 'undefined';\n  // TODO\n  warn = function (msg, vm) {\n    if (hasConsole && !config.silent) {\n      // eslint-disable-next-line\n      console.error(\"[WePY warn]: \" + msg + (vm ? generateComponentTrace(vm) : ''));\n    }\n  };\n}\n\nfunction handleError(err, vm, info) {\n  if (vm) {\n    var cur = vm;\n    while ((cur = cur.$parent)) {\n      var hooks = cur.$options.errorCaptured;\n      if (hooks) {\n        for (var i = 0; i < hooks.length; i++) {\n          try {\n            var capture = hooks[i].call(cur, err, vm, info) === false;\n            if (capture) { return; }\n          } catch (e) {\n            globalHandleError(e, cur, 'errorCaptured hook');\n          }\n        }\n      }\n    }\n  }\n  globalHandleError(err, vm, info);\n}\n\nfunction globalHandleError(err, vm, info) {\n  if (config.errorHandler) {\n    try {\n      return config.errorHandler.call(null, err, vm, info);\n    } catch (e) {\n      logError(e, null, 'config.errorHandler');\n    }\n  }\n  logError(err, vm, info);\n}\n\nfunction logError(err, vm, info) {\n  {\n    warn((\"Error in \" + info + \": \\\"\" + (err.toString()) + \"\\\"\"), vm);\n  }\n  /* istanbul ignore else */\n  if (typeof console !== 'undefined') {\n    // eslint-disable-next-line\n    console.error(err);\n  } else {\n    throw err;\n  }\n}\n\nvar callbacks = [];\nvar pending = false;\n\nfunction flushCallbacks() {\n  pending = false;\n  var copies = callbacks.slice(0);\n  callbacks.length = 0;\n  for (var i = 0; i < copies.length; i++) {\n    copies[i]();\n  }\n}\n\n// Here we have async deferring wrappers using both micro and macro tasks.\n// In < 2.4 we used micro tasks everywhere, but there are some scenarios where\n// micro tasks have too high a priority and fires in between supposedly\n// sequential events (e.g. #4521, #6690) or even between bubbling of the same\n// event (#6566). However, using macro tasks everywhere also has subtle problems\n// when state is changed right before repaint (e.g. #6813, out-in transitions).\n// Here we use micro task by default, but expose a way to force macro task when\n// needed (e.g. in event handlers attached by v-on).\nvar microTimerFunc;\nvar macroTimerFunc;\nvar useMacroTask = false;\n\n// Determine (macro) Task defer implementation.\n// Technically setImmediate should be the ideal choice, but it's only available\n// in IE. The only polyfill that consistently queues the callback after all DOM\n// events triggered in the same loop is by using MessageChannel.\n/* istanbul ignore if */\nif (typeof setImmediate !== 'undefined' && isNative(setImmediate)) {\n  macroTimerFunc = function () {\n    setImmediate(flushCallbacks);\n  };\n} else if (\n  /* eslint-disable no-undef */\n  typeof MessageChannel !== 'undefined' &&\n  (isNative(MessageChannel) ||\n    // PhantomJS\n    MessageChannel.toString() === '[object MessageChannelConstructor]')\n) {\n  var channel = new MessageChannel();\n  var port = channel.port2;\n  channel.port1.onmessage = flushCallbacks;\n  macroTimerFunc = function () {\n    port.postMessage(1);\n  };\n  /* eslint-enable no-undef */\n} else {\n  /* istanbul ignore next */\n  macroTimerFunc = function () {\n    setTimeout(flushCallbacks, 0);\n  };\n}\n\n// Determine MicroTask defer implementation.\n/* istanbul ignore next, $flow-disable-line */\nif (typeof Promise !== 'undefined' && isNative(Promise)) {\n  var p = Promise.resolve();\n  microTimerFunc = function () {\n    p.then(flushCallbacks);\n    // in problematic UIWebViews, Promise.then doesn't completely break, but\n    // it can get stuck in a weird state where callbacks are pushed into the\n    // microtask queue but the queue isn't being flushed, until the browser\n    // needs to do some other work, e.g. handle a timer. Therefore we can\n    // \"force\" the microtask queue to be flushed by adding an empty timer.\n    // if (isIOS) setTimeout(noop)\n  };\n} else {\n  // fallback to macro\n  microTimerFunc = macroTimerFunc;\n}\n\nfunction nextTick(cb, ctx) {\n  var _resolve;\n  callbacks.push(function () {\n    if (cb) {\n      try {\n        cb.call(ctx);\n      } catch (e) {\n        handleError(e, ctx, 'nextTick');\n      }\n    } else if (_resolve) {\n      _resolve(ctx);\n    }\n  });\n  if (!pending) {\n    pending = true;\n    if (useMacroTask) {\n      macroTimerFunc();\n    } else {\n      microTimerFunc();\n    }\n  }\n  // $flow-disable-line\n  if (!cb && typeof Promise !== 'undefined') {\n    return new Promise(function (resolve) {\n      _resolve = resolve;\n    });\n  }\n}\n\nvar renderCallbacks = [];\n\nfunction renderFlushCallbacks() {\n  var copies = renderCallbacks.slice(0);\n  renderCallbacks.length = 0;\n  for (var i = 0; i < copies.length; i++) {\n    copies[i]();\n  }\n}\n\nfunction renderNextTick(cb, ctx) {\n  var _resolve;\n  renderCallbacks.push(function () {\n    if (cb) {\n      try {\n        cb.call(ctx);\n      } catch (e) {\n        handleError(e, ctx, 'nextTick');\n      }\n    } else if (_resolve) {\n      _resolve(ctx);\n    }\n  });\n\n  if (!cb && typeof Promise !== 'undefined') {\n    return new Promise(function (resolve) {\n      _resolve = resolve;\n    });\n  }\n}\n\n/**\n * Parse a v-model expression into a base path and a final key segment.\n * Handles both dot-path and possible square brackets.\n *\n * Possible cases:\n *\n * - test\n * - test[key]\n * - test[test1[key]]\n * - test[\"a\"][key]\n * - xxx.test[a[a].test1[key]]\n * - test.xxx.a[\"asa\"][test1[key]]\n *\n */\n\n/**\n * Remove an item from an array\n */\nfunction remove(arr, item) {\n  if (arr.length) {\n    var index = arr.indexOf(item);\n    if (index > -1) {\n      return arr.splice(index, 1);\n    }\n  }\n}\n\n/**\n * Define a property.\n */\nfunction def(obj, key, val, enumerable) {\n  Object.defineProperty(obj, key, {\n    value: val,\n    enumerable: !!enumerable,\n    writable: true,\n    configurable: true\n  });\n}\n\n/**\n * Parse simple path.\n */\nvar bailRE = /[^\\w.$]/;\nfunction parsePath(path) {\n  if (bailRE.test(path)) {\n    return;\n  }\n  var segments = path.split('.');\n  return function(obj) {\n    for (var i = 0; i < segments.length; i++) {\n      if (!obj) { return; }\n      obj = obj[segments[i]];\n    }\n    return obj;\n  };\n}\n\n// import type Watcher from './watcher'\n\nvar uid = 0;\n\n/**\n * A dep is an observable that can have multiple\n * directives subscribing to it.\n */\nvar Dep = function Dep() {\n  this.id = uid++;\n  this.subs = [];\n};\n\nDep.prototype.addSub = function addSub (sub) {\n  this.subs.push(sub);\n};\n\nDep.prototype.removeSub = function removeSub (sub) {\n  remove(this.subs, sub);\n};\n\nDep.prototype.depend = function depend () {\n  if (Dep.target) {\n    Dep.target.addDep(this);\n  }\n};\n\nDep.prototype.notify = function notify () {\n  // stabilize the subscriber list first\n  var subs = this.subs.slice();\n  for (var i = 0, l = subs.length; i < l; i++) {\n    subs[i].update();\n  }\n};\n\n// the current target watcher being evaluated.\n// this is globally unique because there could be only one\n// watcher being evaluated at any time.\nDep.target = null;\nvar targetStack = [];\n\nfunction pushTarget(_target) {\n  if (Dep.target) { targetStack.push(Dep.target); }\n  Dep.target = _target;\n}\n\nfunction popTarget() {\n  Dep.target = targetStack.pop();\n}\n\n/**\n * @desc ObserverPath 类以及相关处理函数\n * Observer 所在位置对应在整棵 data tree 的路径集合\n * @createDate 2019-07-21\n */\n\n/**\n * 生成完整路径\n * @param key  {String|Number} 当为字符串时，说明是属性名，当为数字时，说明是索引\n * @param parentPath {String} 父路径\n * @return {string}\n */\nvar setPath = function (key, parentPath) {\n  return isNum(key) ? (parentPath + \"[\" + key + \"]\") : (parentPath + \".\" + key);\n};\n\n/**\n * 得到 ObserverPath\n * @param value 被观察对象\n * @return {ObserverPath|null}\n */\nvar pickOp = function (value) {\n  return isObject(value) && hasOwn(value, '__ob__') ? value.__ob__.op : null;\n};\n\nvar ObserverPath = function ObserverPath(key, ob, parentOp) {\n  this.ob = ob;\n  // eslint-disable-next-line eqeqeq\n  if (parentOp) {\n    var ref = getPathMap(key, parentOp.pathKeys, parentOp.pathMap);\n    var combinePathKeys = ref.combinePathKeys;\n    var combinePathMap = ref.combinePathMap;\n    this.pathKeys = combinePathKeys;\n    this.pathMap = combinePathMap;\n  } else {\n    this.pathKeys = null;\n    this.pathMap = null;\n  }\n};\n\nObserverPath.prototype.traverseOp = function traverseOp (key, pathKeys, pathMap, handler) {\n  // 得到 newKey 和 pathMap 组合的路径集合\n  var ref = getPathMap(key, pathKeys, pathMap);\n    var combinePathMap = ref.combinePathMap;\n    var combinePathKeys = ref.combinePathKeys;\n  var handlePathKeys = [];\n  var handlePathMap = {};\n  var hasChange = false;\n\n  // 遍历 combinePathMap\n  for (var i = 0; i < combinePathKeys.length; i++) {\n    var pathObj = handler(combinePathMap[combinePathKeys[i]], this);\n    if (pathObj) {\n      hasChange = true;\n      handlePathKeys.push(pathObj.path);\n      handlePathMap[pathObj.path] = pathObj;\n    }\n  }\n\n  if (hasChange) {\n    var value = this.ob.value;\n    if (Array.isArray(value)) {\n      for (var i$1 = 0; i$1 < value.length; i$1++) {\n        var op = pickOp(value[i$1]);\n        op && op.traverseOp(i$1, handlePathKeys, handlePathMap, handler);\n      }\n    } else {\n      var keys = Object.keys(value);\n      for (var i$2 = 0; i$2 < keys.length; i$2++) {\n        var key$1 = keys[i$2];\n        var op$1 = pickOp(value[key$1]);\n        op$1 && op$1.traverseOp(key$1, handlePathKeys, handlePathMap, handler);\n      }\n    }\n  }\n};\n\nObserverPath.prototype.addPath = function addPath (pathObj) {\n  this.pathKeys.push(pathObj.path);\n  this.pathMap[pathObj.path] = pathObj;\n};\n\nObserverPath.prototype.delPath = function delPath (path) {\n  remove(this.pathKeys, path);\n  delete this.pathMap[path];\n};\n\n/**\n * 添加新的 __ob__ 的 path\n */\nfunction addPaths(newKey, op, parentOp) {\n  op.traverseOp(newKey, parentOp.pathKeys, parentOp.pathMap, handler);\n\n  function handler(pathObj, op) {\n    if (!(pathObj.path in op.pathMap)) {\n      // 新增一条 path\n      op.addPath(pathObj);\n      return pathObj;\n    } else {\n      return null;\n    }\n  }\n}\n\n/**\n * 删除指定的 __ob__ 的 path\n */\nfunction cleanPaths(oldKey, op, parentOp) {\n  op.traverseOp(oldKey, parentOp.pathKeys, parentOp.pathMap, handler);\n\n  function handler(pathObj, op) {\n    // 删除一条 path\n    op.delPath(pathObj.path);\n    return pathObj;\n  }\n}\n\n/**\n * 得到 pathMap 与 key 组合后的路径集合\n */\nfunction getPathMap(key, pathKeys, pathMap) {\n  var obj;\n\n  if (pathMap) {\n    // console.log('pathMap', pathMap)\n    var combinePathKeys = [];\n    var combinePathMap = {};\n    for (var i = 0; i < pathKeys.length; i++) {\n      var path = setPath(key, pathMap[pathKeys[i]].path);\n      combinePathKeys.push(path);\n      combinePathMap[path] = { key: key, root: pathMap[pathKeys[i]].root, path: path };\n    }\n    return { combinePathKeys: combinePathKeys, combinePathMap: combinePathMap };\n  } else {\n    return {\n      combinePathKeys: [key],\n      combinePathMap: ( obj = {}, obj[key] = { key: key, root: key, path: key }, obj)\n    };\n  }\n}\n\n/*\n * not type checking this file because flow doesn't play well with\n * dynamically accessing methods on Array prototype\n */\n\nvar arrayProto = Array.prototype;\nvar arrayMethods = Object.create(arrayProto);\n\nvar methodsToPatch = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'];\n\n/**\n * Intercept mutating methods and emit events\n */\nmethodsToPatch.forEach(function(method) {\n  // cache original method\n  var original = arrayProto[method];\n  def(arrayMethods, method, function mutator() {\n    var args = [], len$1 = arguments.length;\n    while ( len$1-- ) args[ len$1 ] = arguments[ len$1 ];\n\n    var len = this.length;\n    // 清除已经失效的 paths\n    if (len > 0) {\n      switch (method) {\n        case 'pop':\n          delInvalidPaths(len - 1, this[len - 1], this);\n          break;\n        case 'shift':\n          delInvalidPaths(0, this[0], this);\n          break;\n        case 'splice':\n        case 'sort':\n        case 'reverse':\n          for (var i = 0; i < this.length; i++) {\n            delInvalidPaths(i, this[i], this);\n          }\n      }\n    }\n\n    var result = original.apply(this, args);\n    var ob = this.__ob__;\n    var vm = ob.vm;\n\n    // push parent key to dirty, wait to setData\n    if (vm.$dirty) {\n      if (method === 'push') {\n        var lastIndex = ob.value.length - 1;\n        vm.$dirty.set(ob.op, lastIndex, ob.value[lastIndex]);\n      } else {\n        vm.$dirty.set(ob.op, null, ob.value);\n      }\n    }\n\n    // 这里和 vue 不一样，所有变异方法都需要更新 path\n    ob.observeArray(ob.key, ob.value);\n\n    // notify change\n    ob.dep.notify();\n    return result;\n  });\n});\n\nfunction delInvalidPaths(key, value, parent) {\n  if (isObject(value) && hasOwn(value, '__ob__')) {\n    // delete invalid paths\n    cleanPaths(key, value.__ob__.op, parent.__ob__.op);\n  }\n}\n\nvar arrayKeys = Object.getOwnPropertyNames(arrayMethods);\n\n/**\n * By default, when a reactive property is set, the new value is\n * also converted to become reactive. However when passing down props,\n * we don't want to force conversion because the value may be a nested value\n * under a frozen data structure. Converting it would defeat the optimization.\n */\nvar observerState = {\n  shouldConvert: true\n};\n\n/**\n * Observer class that are attached to each observed\n * object. Once attached, the observer converts target\n * object's property keys into getter/setters that\n * collect dependencies and dispatches updates.\n */\nvar Observer = function Observer(ref) {\n  var vm = ref.vm;\n  var key = ref.key;\n  var value = ref.value;\n  var parent = ref.parent;\n\n  this.value = value;\n  this.dep = new Dep();\n  this.vmCount = 0;\n  this.vm = vm;\n  this.op = new ObserverPath(key, this, parent && parent.__ob__ && parent.__ob__.op);\n\n  def(value, '__ob__', this);\n  if (Array.isArray(value)) {\n    var augment = hasProto ? protoAugment : copyAugment;\n    augment(value, arrayMethods, arrayKeys);\n    this.observeArray(key, value);\n  } else {\n    this.walk(key, value);\n  }\n};\n\n/**\n * Walk through each property and convert them into\n * getter/setters. This method should only be called when\n * value type is Object.\n */\nObserver.prototype.walk = function walk (key, obj) {\n  var keys = Object.keys(obj);\n  for (var i = 0; i < keys.length; i++) {\n    defineReactive({ vm: this.vm, obj: obj, key: keys[i], value: obj[keys[i]], parent: obj });\n    //defineReactive(this.vm, obj, keys[i], obj[keys[i]]);\n  }\n};\n\n/**\n * Observe a list of Array items.\n */\nObserver.prototype.observeArray = function observeArray (key, items) {\n  for (var i = 0, l = items.length; i < l; i++) {\n    observe({ vm: this.vm, key: i, value: items[i], parent: items });\n  }\n};\n\n/**\n * Check if path exsit in vm\n */\nObserver.prototype.hasPath = function hasPath (path) {\n  var value = this.vm;\n  var key = '';\n  var i = 0;\n  while (i < path.length) {\n    if (path[i] !== '.' && path[i] !== '[' && path[i] !== ']') {\n      key += path[i];\n    } else if (key.length !== 0) {\n      value = value[key];\n      key = '';\n      if (!isObject(value)) {\n        return false;\n      }\n    }\n    i++;\n  }\n  return true;\n};\n\n/**\n * Is this path value equal\n */\nObserver.prototype.isPathEq = function isPathEq (path, value) {\n  var objValue = this.vm;\n  var key = '';\n  var i = 0;\n  while (i < path.length) {\n    if (path[i] !== '.' && path[i] !== '[' && path[i] !== ']') {\n      key += path[i];\n    } else if (key.length !== 0) {\n      objValue = objValue[key];\n      key = '';\n      if (!isObject(objValue)) {\n        return false;\n      }\n    }\n    i++;\n  }\n  if (key.length !== 0) {\n    objValue = objValue[key];\n  }\n  return value === objValue;\n};\n\n// helpers\n\n/**\n * Augment an target Object or Array by intercepting\n * the prototype chain using __proto__\n */\nfunction protoAugment(target, src) {\n  /* eslint-disable no-proto */\n  target.__proto__ = src;\n  /* eslint-enable no-proto */\n}\n\n/**\n * Augment an target Object or Array by defining\n * hidden properties.\n */\n/* istanbul ignore next */\nfunction copyAugment(target, src, keys) {\n  for (var i = 0, l = keys.length; i < l; i++) {\n    var key = keys[i];\n    def(target, key, src[key]);\n  }\n}\n\n/**\n * Attempt to create an observer instance for a value,\n * returns the new observer if successfully observed,\n * or the existing observer if the value already has one.\n */\nfunction observe(ref) {\n  var vm = ref.vm;\n  var key = ref.key;\n  var value = ref.value;\n  var parent = ref.parent;\n  var root = ref.root;\n\n  if (!isObject(value)) {\n    return;\n  }\n  var ob;\n  if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {\n    ob = value.__ob__;\n    var op = ob.op;\n    addPaths(key, op, parent.__ob__.op);\n  } else if (\n    observerState.shouldConvert &&\n    (Array.isArray(value) || isPlainObject(value)) &&\n    Object.isExtensible(value) &&\n    !value._isVue\n  ) {\n    ob = new Observer({ vm: vm, key: key, value: value, parent: parent });\n  }\n  if (root && ob) {\n    ob.vmCount++;\n  }\n  return ob;\n}\n\n/**\n * Define a reactive property on an Object.\n */\nfunction defineReactive(ref) {\n  var vm = ref.vm;\n  var obj = ref.obj;\n  var key = ref.key;\n  var value = ref.value;\n  var parent = ref.parent;\n  var customSetter = ref.customSetter;\n  var shallow = ref.shallow;\n\n  var dep = new Dep();\n\n  var property = Object.getOwnPropertyDescriptor(obj, key);\n  if (property && property.configurable === false) {\n    return;\n  }\n\n  // cater for pre-defined getter/setters\n  var getter = property && property.get;\n  if (!getter && arguments.length === 2) {\n    value = obj[key];\n  }\n  var setter = property && property.set;\n\n  var childOb = !shallow && observe({ vm: vm, key: key, value: value, parent: obj });\n  Object.defineProperty(obj, key, {\n    enumerable: true,\n    configurable: true,\n    get: function reactiveGetter() {\n      var val = getter ? getter.call(obj) : value;\n      if (Dep.target) {\n        dep.depend();\n        if (childOb) {\n          childOb.dep.depend();\n          if (Array.isArray(val)) {\n            dependArray(val);\n          }\n        }\n      }\n      return val;\n    },\n    set: function reactiveSetter(newVal) {\n      var val = getter ? getter.call(obj) : value;\n      /* eslint-disable no-self-compare */\n      if (newVal === val || (newVal !== newVal && val !== val)) {\n        return;\n      }\n\n      if (isObject(value) && hasOwn(value, '__ob__')) {\n        /**\n         * 删掉无效的 paths\n         * 注意：即使 path 只有一个也要删掉，因为其子节点可能有多个 path\n         */\n        cleanPaths(key, value.__ob__.op, parent.__ob__.op);\n      }\n\n      /* eslint-enable no-self-compare */\n      if (\"development\" !== 'production' && customSetter) {\n        customSetter();\n      }\n      if (setter) {\n        setter.call(obj, newVal);\n      } else {\n        value = newVal;\n      }\n\n      // Have to set dirty after value assigned, otherwise the dirty key is incrrect.\n      if (vm) {\n        // push parent key to dirty, wait to setData\n        if (vm.$dirty) {\n          vm.$dirty.set(obj.__ob__.op, key, newVal);\n        }\n      }\n      childOb = !shallow && observe({ vm: vm, key: key, value: newVal, parent: parent });\n      dep.notify();\n    }\n  });\n}\n\n/**\n * Set a property on an object. Adds the new property and\n * triggers change notification if the property doesn't\n * already exist.\n */\nfunction set(vm, target, key, val) {\n  if (Array.isArray(target) && isValidArrayIndex(key)) {\n    target.length = Math.max(target.length, key);\n    target.splice(key, 1, val);\n    return val;\n  }\n\n  if (key in target && !(key in Object.prototype)) {\n    target[key] = val;\n    return val;\n  }\n\n  var ob = target.__ob__;\n  if (target._isVue || (ob && ob.vmCount)) {\n    \"development\" !== 'production' &&\n      warn(\n        'Avoid adding reactive properties to a Vue instance or its root $data ' +\n          'at runtime - declare it upfront in the data option.'\n      );\n    return val;\n  }\n\n  if (!ob) {\n    target[key] = val;\n    return val;\n  }\n\n  if (isObject(target[key]) && hasOwn(target[key], '__ob__')) {\n    // delete invalid paths\n    cleanPaths(key, target[key].__ob__.op, ob.op);\n  }\n  defineReactive({ vm: vm, obj: ob.value, key: key, value: val, parent: ob.value });\n  if (vm) {\n    // push parent key to dirty, wait to setData\n    if (vm.$dirty && hasOwn(target, '__ob__')) {\n      vm.$dirty.set(target.__ob__.op, key, val);\n    }\n  }\n  ob.dep.notify();\n  return val;\n}\n\n/**\n * Delete a property and trigger change if necessary.\n */\nfunction del(target, key) {\n  if (Array.isArray(target) && isValidArrayIndex(key)) {\n    target.splice(key, 1);\n    return;\n  }\n\n  var ob = target.__ob__;\n  if (target._isVue || (ob && ob.vmCount)) {\n    \"development\" !== 'production' &&\n      warn('Avoid deleting properties on a Vue instance or its root $data ' + '- just set it to null.');\n    return;\n  }\n\n  if (!hasOwn(target, key)) {\n    return;\n  }\n\n  // set $dirty\n  target[key] = null;\n  delete target[key];\n  if (!ob) {\n    return;\n  }\n  ob.dep.notify();\n}\n\n/**\n * Collect dependencies on array elements when the array is touched, since\n * we cannot intercept array element access like property getters.\n */\nfunction dependArray(value) {\n  for (var e = (void 0), i = 0, l = value.length; i < l; i++) {\n    e = value[i];\n    e && e.__ob__ && e.__ob__.dep.depend();\n    if (Array.isArray(e)) {\n      dependArray(e);\n    }\n  }\n}\n\nvar Base = function Base() {\n  this._events = {};\n  this._watchers = [];\n};\n\nBase.prototype.$set = function $set (target, key, val) {\n  return set(this, target, key, val);\n};\n\nBase.prototype.$delete = function $delete (target, key) {\n  return del(target, key);\n};\n\nBase.prototype.$on = function $on (event, fn) {\n    var this$1 = this;\n\n  if (isArr(event)) {\n    event.forEach(function (item) {\n      if (isStr(item)) {\n        this$1.$on(item, fn);\n      } else if (isObj(item)) {\n        this$1.$on(item.event, item.fn);\n      }\n    });\n  } else {\n    (this._events[event] || (this._events[event] = [])).push(fn);\n  }\n  return this;\n};\n\nBase.prototype.$once = function $once () {};\n\nBase.prototype.$off = function $off (event, fn) {\n    var this$1 = this;\n\n  if (!event && !fn) {\n    this._events = Object.create(null);\n    return this;\n  }\n\n  if (isArr(event)) {\n    event.forEach(function (item) {\n      if (isStr(item)) {\n        this$1.$off(item, fn);\n      } else if (isObj(item)) {\n        this$1.$off(item.event, item.fn);\n      }\n    });\n    return this;\n  }\n  if (!this._events[event]) { return this; }\n\n  if (!fn) {\n    this._events[event] = null;\n    return this;\n  }\n\n  if (fn) {\n    var fns = this._events[event];\n    var i = fns.length;\n    while (i--) {\n      var tmp = fns[i];\n      if (tmp === fn || tmp.fn === fn) {\n        fns.splice(i, 1);\n        break;\n      }\n    }\n  }\n  return this;\n};\n\nBase.prototype.$emit = function $emit (event) {\n    var this$1 = this;\n\n  var vm = this;\n  var lowerCaseEvent = event.toLowerCase();\n  var fns = this._events[event] || [];\n  if (lowerCaseEvent !== event && vm._events[lowerCaseEvent]) {\n    // TODO: handler warn\n  }\n  var args = toArray(arguments, 1);\n  fns.forEach(function (fn) {\n    try {\n      fn.apply(this$1, args);\n    } catch (e) {\n      handleError(e, vm, (\"event handler for \\\"\" + event + \"\\\"\"));\n    }\n  });\n  return this;\n};\n\nvar seenObjects = new _Set();\n\n/**\n * Recursively traverse an object to evoke all converted\n * getters, so that every nested property inside the object\n * is collected as a \"deep\" dependency.\n */\nfunction traverse(val) {\n  _traverse(val, seenObjects);\n  seenObjects.clear();\n}\n\nfunction _traverse(val, seen) {\n  var i, keys;\n  var isA = Array.isArray(val);\n  if ((!isA && !isObject(val)) || Object.isFrozen(val)) {\n    return;\n  }\n  if (val.__ob__) {\n    var depId = val.__ob__.dep.id;\n    if (seen.has(depId)) {\n      return;\n    }\n    seen.add(depId);\n  }\n  if (isA) {\n    i = val.length;\n    while (i--) { _traverse(val[i], seen); }\n  } else {\n    keys = Object.keys(val);\n    i = keys.length;\n    while (i--) { _traverse(val[keys[i]], seen); }\n  }\n}\n\n//import { callHook, activateChildComponent } from '../instance/lifecycle';\n\nvar MAX_UPDATE_COUNT = 100;\n\nvar queue = [];\nvar activatedChildren = [];\nvar has = {};\nvar circular = {};\nvar waiting = false;\nvar flushing = false;\nvar index = 0;\n\n/**\n * Reset the scheduler's state.\n */\nfunction resetSchedulerState() {\n  index = queue.length = activatedChildren.length = 0;\n  has = {};\n  {\n    circular = {};\n  }\n  waiting = flushing = false;\n}\n\n/**\n * Flush both queues and run the watchers.\n */\nfunction flushSchedulerQueue(times) {\n  if ( times === void 0 ) times = 0;\n\n  flushing = true;\n  var watcher, id;\n\n  // Sort queue before flush.\n  // This ensures that:\n  // 1. Components are updated from parent to child. (because parent is always\n  //    created before the child)\n  // 2. A component's user watchers are run before its render watcher (because\n  //    user watchers are created before the render watcher)\n  // 3. If a component is destroyed during a parent component's watcher run,\n  //    its watchers can be skipped.\n  times === 0 && queue.sort(function (a, b) { return a.id - b.id; });\n\n  // do not cache length because more watchers might be pushed\n  // as we run existing watchers\n  // there would be mutilple renderWatcher in the queue.\n  var renderWatcher = [];\n  if (times === 0) {\n    index = 0;\n  }\n  for (; index < queue.length; index++) {\n    // if it's renderWatcher, run it in the end\n    watcher = queue[index];\n    if (watcher && watcher.isRenderWatcher) {\n      renderWatcher.push(watcher);\n      continue;\n    }\n    id = watcher.id;\n    has[id] = null;\n    watcher.run();\n    // in dev build, check and stop circular updates.\n    // eslint-disable-next-line\n    if (\"development\" !== 'production' && has[id] != null) {\n      circular[id] = (circular[id] || 0) + 1;\n      if (circular[id] > MAX_UPDATE_COUNT) {\n        warn(\n          'You may have an infinite update loop ' +\n            (watcher.user ? (\"in watcher with expression \\\"\" + (watcher.expression) + \"\\\"\") : \"in a component render function.\"),\n          watcher.vm\n        );\n        resetSchedulerState();\n        return;\n      }\n    }\n  }\n  // Run renderWatcher in the end.\n  if (renderWatcher.length) {\n    renderWatcher.forEach(function (watcher) {\n      has[watcher.id] = null;\n      watcher.run();\n    });\n  }\n\n  // It may added new watcher to the queue in render watcher\n  var pendingQueue = queue.slice(index);\n\n  if (pendingQueue.length) {\n    flushSchedulerQueue(times + 1);\n  } else {\n    // keep copies of post queues before resetting state\n    // const activatedQueue = activatedChildren.slice()\n    // const updatedQueue = queue.slice()\n\n    resetSchedulerState();\n\n    // call component updated and activated hooks\n    // callActivatedHooks(activatedQueue)\n    // callUpdatedHooks(updatedQueue)\n\n    // devtool hook\n    /* istanbul ignore if */\n    /*\n    if (devtools && config.devtools) {\n      devtools.emit('flush')\n    }*/\n  }\n}\n\n/*\nfunction callActivatedHooks(queue) {\n  for (let i = 0; i < queue.length; i++) {\n    queue[i]._inactive = true;\n    activateChildComponent(queue[i], true);\n  }\n}\n*/\n\n/**\n * Push a watcher into the watcher queue.\n * Jobs with duplicate IDs will be skipped unless it's\n * pushed when the queue is being flushed.\n */\nfunction queueWatcher(watcher) {\n  var id = watcher.id;\n  // eslint-disable-next-line\n  if (has[id] == null) {\n    has[id] = true;\n    if (!flushing) {\n      queue.push(watcher);\n    } else {\n      // if already flushing, splice the watcher based on its id\n      // if already past its id, it will be run next immediately.\n      var i = queue.length - 1;\n      while (i > index && queue[i].id > watcher.id) {\n        i--;\n      }\n      queue.splice(i + 1, 0, watcher);\n    }\n    // queue the flush\n    if (!waiting) {\n      waiting = true;\n      nextTick(flushSchedulerQueue);\n    }\n  }\n}\n\n//import { SimpleSet } from '../util/index';\n\nvar uid$1 = 0;\n\n/**\n * A watcher parses an expression, collects dependencies,\n * and fires callback when the expression value changes.\n * This is used for both the $watch() api and directives.\n */\nvar Watcher = function Watcher(vm, expOrFn, cb, options, isRenderWatcher) {\n  this.vm = vm;\n  if (isRenderWatcher) {\n    vm._watcher = this;\n  }\n  vm._watchers.push(this);\n  // options\n  if (options) {\n    this.deep = !!options.deep;\n    this.user = !!options.user;\n    this.computed = !!options.computed;\n    this.sync = !!options.sync;\n  } else {\n    this.deep = this.user = this.computed = this.sync = false;\n  }\n  this.cb = cb;\n  this.id = ++uid$1; // uid for batching\n  this.active = true;\n  this.dirty = this.computed; // for computed watchers\n  this.deps = [];\n  this.newDeps = [];\n  this.depIds = new _Set();\n  this.newDepIds = new _Set();\n  this.isRenderWatcher = isRenderWatcher;\n  this.expression = expOrFn.toString();\n  // parse expression for getter\n  if (typeof expOrFn === 'function') {\n    this.getter = expOrFn;\n  } else {\n    this.getter = parsePath(expOrFn);\n    if (!this.getter) {\n      this.getter = function() {};\n      \"development\" !== 'production' &&\n        warn(\n          \"Failed watching path: \\\"\" + expOrFn + \"\\\" \" +\n            'Watcher only accepts simple dot-delimited paths. ' +\n            'For full control, use a function instead.',\n          vm\n        );\n    }\n  }\n  this.value = this.computed ? undefined : this.get();\n};\n\n/**\n * Evaluate the getter, and re-collect dependencies.\n */\nWatcher.prototype.get = function get () {\n  pushTarget(this);\n  var value;\n  var vm = this.vm;\n  try {\n    value = this.getter.call(vm, vm);\n  } catch (e) {\n    if (this.user) {\n      handleError(e, vm, (\"getter for watcher \\\"\" + (this.expression) + \"\\\"\"));\n    } else {\n      throw e;\n    }\n  } finally {\n    // \"touch\" every property so they are all tracked as\n    // dependencies for deep watching\n    if (this.deep) {\n      traverse(value);\n    }\n    popTarget();\n    if (!this.isRenderWatcher) { this.cleanupDeps(); }\n  }\n  return value;\n};\n\n/**\n * Add a dependency to this directive.\n */\nWatcher.prototype.addDep = function addDep (dep) {\n  var id = dep.id;\n  if (!this.newDepIds.has(id)) {\n    this.newDepIds.add(id);\n    this.newDeps.push(dep);\n    if (!this.depIds.has(id)) {\n      dep.addSub(this);\n    }\n  }\n};\n\n/**\n * Clean up for dependency collection.\n */\nWatcher.prototype.cleanupDeps = function cleanupDeps () {\n  var i = this.deps.length;\n  while (i--) {\n    var dep = this.deps[i];\n    if (!this.newDepIds.has(dep.id)) {\n      dep.removeSub(this);\n    }\n  }\n  var tmp = this.depIds;\n  this.depIds = this.newDepIds;\n  this.newDepIds = tmp;\n  this.newDepIds.clear();\n  tmp = this.deps;\n  this.deps = this.newDeps;\n  this.newDeps = tmp;\n  this.newDeps.length = 0;\n};\n\n/**\n * Subscriber interface.\n * Will be called when a dependency changes.\n */\nWatcher.prototype.update = function update () {\n  /* istanbul ignore else */\n  if (this.computed) {\n    this.dirty = true;\n  } else if (this.sync) {\n    this.run();\n  } else {\n    queueWatcher(this);\n  }\n};\n\n/**\n * Scheduler job interface.\n * Will be called by the scheduler.\n */\nWatcher.prototype.run = function run () {\n  if (this.active) {\n    var value = this.get();\n    if (\n      value !== this.value ||\n      // Deep watchers and watchers on Object/Arrays should fire even\n      // when the value is the same, because the value may\n      // have mutated.\n      isObject(value) ||\n      this.deep\n    ) {\n      // set new value\n      var oldValue = this.value;\n      this.value = value;\n      if (this.user) {\n        try {\n          this.cb.call(this.vm, value, oldValue);\n        } catch (e) {\n          handleError(e, this.vm, (\"callback for watcher \\\"\" + (this.expression) + \"\\\"\"));\n        }\n      } else {\n        this.cb.call(this.vm, value, oldValue);\n      }\n    }\n  }\n};\n\n/**\n * Evaluate the value of the watcher.\n * This only gets called for computed watchers.\n */\nWatcher.prototype.evaluate = function evaluate () {\n  this.value = this.get();\n  if (this.vm.$dirty) {\n    var keyVal =\n      this._computedWatchers && this._computedWatchers[this.key]\n        ? this.vm._computedWatchers[this.key].value\n        : this.value;\n    this.vm.$dirty.push(this.key, this.key, keyVal, this.value);\n  }\n  this.dirty = false;\n  return this.value;\n};\n\n/**\n * Depend on all deps collected by this watcher.\n */\nWatcher.prototype.depend = function depend () {\n  if (Dep.target) {\n    var i = this.deps.length;\n    while (i--) {\n      this.deps[i].depend();\n    }\n  }\n};\n\n/**\n * Remove self from all dependencies' subscriber list.\n */\nWatcher.prototype.teardown = function teardown () {\n  if (this.active) {\n    // remove self from vm's watcher list\n    // this is a somewhat expensive operation so we skip it\n    // if the vm is being destroyed.\n    if (!this.vm._isBeingDestroyed) {\n      remove(this.vm._watchers, this);\n    }\n    var i = this.deps.length;\n    while (i--) {\n      this.deps[i].removeSub(this);\n    }\n    this.active = false;\n  }\n};\n\nvar WepyComponent = /*@__PURE__*/(function (Base$$1) {\n  function WepyComponent () {\n    Base$$1.apply(this, arguments);\n  }\n\n  if ( Base$$1 ) WepyComponent.__proto__ = Base$$1;\n  WepyComponent.prototype = Object.create( Base$$1 && Base$$1.prototype );\n  WepyComponent.prototype.constructor = WepyComponent;\n\n  WepyComponent.prototype.$watch = function $watch (expOrFn, cb, options) {\n    var this$1 = this;\n\n    var vm = this;\n    if (isArr(cb)) {\n      cb.forEach(function (handler) {\n        this$1.$watch(expOrFn, handler, options);\n      });\n    }\n    if (isPlainObject(cb)) {\n      var handler = cb;\n      options = handler;\n      handler = handler.handler;\n      if (typeof handler === 'string') { handler = this[handler]; }\n      return this.$watch(expOrFn, handler, options);\n    }\n\n    options = options || {};\n    options.user = true;\n    var watcher = new Watcher(vm, expOrFn, cb, options);\n    if (options.immediate) {\n      cb.call(vm, watcher.value);\n    }\n    return function unwatchFn() {\n      watcher.teardown();\n    };\n  };\n\n  WepyComponent.prototype.$forceUpdate = function $forceUpdate () {\n    if (this._watcher) {\n      this._watcher.update();\n    }\n  };\n\n  WepyComponent.prototype.$emit = function $emit (event) {\n    var args = [], len = arguments.length - 1;\n    while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];\n\n    var fns = this._events[event];\n\n    if (fns) {\n      Base$$1.prototype.$emit.apply(this, arguments);\n    } else {\n      this.$wx.triggerEvent(event, { arguments: args });\n    }\n\n    return this;\n  };\n\n  WepyComponent.prototype.$trigger = function $trigger (event, data, option) {\n    this.$wx.triggerEvent(event, { arguments: [data] }, option);\n  };\n\n  return WepyComponent;\n}(Base));\n\nWepyComponent.prototype.$nextTick = renderNextTick;\n\nvar sharedPropertyDefinition = {\n  enumerable: true,\n  configurable: true,\n  get: noop,\n  set: noop\n};\n\nfunction proxy(target, sourceKey, key) {\n  sharedPropertyDefinition.get = function proxyGetter() {\n    return this[sourceKey][key];\n  };\n  sharedPropertyDefinition.set = function proxySetter(val) {\n    this[sourceKey][key] = val;\n  };\n  Object.defineProperty(target, key, sharedPropertyDefinition);\n}\n\n/*\n * patch data option\n */\nfunction patchData(output, data) {\n  if (!data) {\n    data = {};\n  }\n  output.data = data;\n}\n\n/*\n * init data\n */\nfunction initData(vm, data) {\n  if (!data) {\n    data = {};\n  }\n  var _data;\n  if (typeof data === 'function') {\n    _data = data.call(vm);\n  } else {\n    _data = clone(data);\n  }\n  vm._data = _data;\n  Object.keys(_data).forEach(function (key) {\n    proxy(vm, '_data', key);\n  });\n\n  observe({\n    vm: vm,\n    key: '',\n    value: _data,\n    parent: '',\n    root: true\n  });\n  //observe(vm, _data, null, true);\n}\n\nfunction initWatch(vm, watch) {\n  if (watch) {\n    Object.keys(watch).forEach(function (key) {\n      vm.$watch(key, watch[key]);\n    });\n  }\n}\n\nfunction createComputedGetter(key) {\n  return function computedGetter() {\n    var watcher = this._computedWatchers && this._computedWatchers[key];\n    if (watcher) {\n      watcher.key = key;\n      if (watcher.dirty) {\n        watcher.evaluate();\n      }\n      if (Dep.target) {\n        watcher.depend();\n      }\n      return watcher.value;\n    }\n  };\n}\n\n/*\n * init computed\n */\nfunction initComputed(vm, computed) {\n  if (!computed) {\n    return;\n  }\n  var watchers = (vm._computedWatchers = Object.create(null));\n  var computedWatcherOptions = { computed: true };\n\n  Object.keys(computed).forEach(function (key) {\n    var def = computed[key];\n    var getter = typeof def === 'object' ? def.get : def;\n\n    if (!getter || typeof getter !== 'function') {\n      // eslint-disable-next-line\n      console.error((\"Getter is missing for computed property \\\"\" + key + \"\\\"\"));\n    }\n\n    // push to dirty after dep called.\n    watchers[key] = new Watcher(\n      vm,\n      getter || function() {},\n      function() {\n        // evaluate will set dirty\n        // vm.$dirty.push(key, key, newv);\n      },\n      computedWatcherOptions\n    );\n\n    if (typeof def === 'function') {\n      sharedPropertyDefinition.get = createComputedGetter(key);\n      sharedPropertyDefinition.set = function() {};\n    } else {\n      sharedPropertyDefinition.get = def.cache !== false ? createComputedGetter(key) : def.get;\n      sharedPropertyDefinition.set = def.set;\n    }\n\n    Object.defineProperty(vm, key, sharedPropertyDefinition);\n  });\n}\n\nvar WepyConstructor = /*@__PURE__*/(function (WepyComponent$$1) {\n  function WepyConstructor(opt) {\n    if ( opt === void 0 ) opt = {};\n\n    WepyComponent$$1.call(this);\n    var vm = new WepyComponent$$1();\n\n    // Only need data and watchers for a empty WepyComponent\n    if (opt.data) {\n      initData(vm, opt.data);\n    }\n    initWatch(vm);\n\n    initComputed(vm, opt.computed);\n    return vm;\n  }\n\n  if ( WepyComponent$$1 ) WepyConstructor.__proto__ = WepyComponent$$1;\n  WepyConstructor.prototype = Object.create( WepyComponent$$1 && WepyComponent$$1.prototype );\n  WepyConstructor.prototype.constructor = WepyConstructor;\n\n  return WepyConstructor;\n}(WepyComponent));\n\nvar $global = Object.create(null);\n\nfunction use(plugin) {\n  var args = [], len = arguments.length - 1;\n  while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];\n\n  if (plugin.installed) {\n    return this;\n  }\n\n  var install = plugin.install || plugin;\n\n  if (isFunc(install)) {\n    install.apply(plugin, [this].concat(args));\n  }\n\n  plugin.installed = 1;\n}\n\nfunction mixin(options) {\n  if ( options === void 0 ) options = {};\n\n  $global.mixin = ($global.mixin || []).concat(options);\n}\n\nvar WepyApp = /*@__PURE__*/(function (Base$$1) {\n  function WepyApp() {\n    Base$$1.call(this);\n  }\n\n  if ( Base$$1 ) WepyApp.__proto__ = Base$$1;\n  WepyApp.prototype = Object.create( Base$$1 && Base$$1.prototype );\n  WepyApp.prototype.constructor = WepyApp;\n\n  return WepyApp;\n}(Base));\n\nvar WepyComponent$1 = /*@__PURE__*/(function (Base$$1) {\n  function WepyComponent () {\n    Base$$1.apply(this, arguments);\n  }\n\n  if ( Base$$1 ) WepyComponent.__proto__ = Base$$1;\n  WepyComponent.prototype = Object.create( Base$$1 && Base$$1.prototype );\n  WepyComponent.prototype.constructor = WepyComponent;\n\n  WepyComponent.prototype.$watch = function $watch (expOrFn, cb, options) {\n    var this$1 = this;\n\n    var vm = this;\n    if (isArr(cb)) {\n      cb.forEach(function (handler) {\n        this$1.$watch(expOrFn, handler, options);\n      });\n    }\n    if (isPlainObject(cb)) {\n      var handler = cb;\n      options = handler;\n      handler = handler.handler;\n      if (typeof handler === 'string') { handler = this[handler]; }\n      return this.$watch(expOrFn, handler, options);\n    }\n\n    options = options || {};\n    options.user = true;\n    var watcher = new Watcher(vm, expOrFn, cb, options);\n    if (options.immediate) {\n      cb.call(vm, watcher.value);\n    }\n    return function unwatchFn() {\n      watcher.teardown();\n    };\n  };\n\n  WepyComponent.prototype.$forceUpdate = function $forceUpdate () {\n    if (this._watcher) {\n      this._watcher.update();\n    }\n  };\n\n  return WepyComponent;\n}(Base));\n\nWepyComponent$1.prototype.$nextTick = renderNextTick;\n\n// eslint-disable-next-line\nvar wx = my;\nvar WepyPage = /*@__PURE__*/(function (WepyComponent) {\n  function WepyPage () {\n    WepyComponent.apply(this, arguments);\n  }\n\n  if ( WepyComponent ) WepyPage.__proto__ = WepyComponent;\n  WepyPage.prototype = Object.create( WepyComponent && WepyComponent.prototype );\n  WepyPage.prototype.constructor = WepyPage;\n\n  WepyPage.prototype.$launch = function $launch (url, params) {\n    this.$route('reLaunch', url, params);\n  };\n  WepyPage.prototype.$navigate = function $navigate (url, params) {\n    this.$route('navigate', url, params);\n  };\n\n  WepyPage.prototype.$redirect = function $redirect (url, params) {\n    this.$route('redirect', url, params);\n  };\n\n  WepyPage.prototype.$back = function $back (p) {\n    if ( p === void 0 ) p = {};\n\n    if (isNum(p)) { p = { delta: p }; }\n\n    if (!p.delta) { p.delta = 1; }\n\n    return wx.navigateBack(p);\n  };\n\n  WepyPage.prototype.$route = function $route (type, url, params) {\n    if ( params === void 0 ) params = {};\n\n    var wxparams;\n    if (isStr(url)) {\n      var paramsList = [];\n      if (isObj(params)) {\n        for (var k in params) {\n          if (!isUndef(params[k])) {\n            paramsList.push((k + \"=\" + (encodeURIComponent(params[k]))));\n          }\n        }\n      }\n      if (paramsList.length) { url = url + '?' + paramsList.join('&'); }\n\n      wxparams = { url: url };\n    } else {\n      wxparams = url;\n    }\n    var fn = wx[type] || wx[type + 'To'];\n    if (isFunc(fn)) {\n      return fn(wxparams);\n    }\n  };\n\n  return WepyPage;\n}(WepyComponent$1));\n\nfunction callUserHook(vm, hookName, arg) {\n  var pageHook = vm.hooks ? vm.hooks[hookName] : null;\n  var appHook = vm.$app && vm.$app.hooks ? vm.$app.hooks[hookName] : null;\n\n  if (!vm.$app) {\n    warn('$app is not initialized in this Component', vm);\n  }\n\n  var result = arg;\n\n  // First run page hook, and then run app hook\n  // Pass page hook result to app hook\n  // If return undefined, then return default argument\n  [pageHook, appHook].forEach(function (fn) {\n    if (isFunc(fn)) {\n      result = fn.call(vm, result);\n      if (isUndef(result)) {\n        result = arg;\n      }\n    }\n  });\n\n  return result;\n}\n\nfunction initHooks(vm, hooks) {\n  if ( hooks === void 0 ) hooks = {};\n\n  vm.hooks = hooks;\n}\n\nvar observerFn = function() {\n  return function(newVal, oldVal, changedPaths) {\n    var vm = this.$wepy;\n\n    // changedPaths 长度大于 1，说明是由内部赋值改变的 prop\n    if (changedPaths.length > 1) {\n      return;\n    }\n    var _data = newVal;\n    if (typeof _data === 'function') {\n      _data = _data.call(vm);\n    }\n    vm[changedPaths[0]] = _data;\n  };\n};\n/*\n * patch props option\n */\nfunction patchProps(output, props) {\n  var newProps = {};\n  if (isStr(props)) {\n    newProps = [props];\n  }\n  if (isArr(props)) {\n    props.forEach(function (prop) {\n      newProps[prop] = {\n        type: null,\n        observer: observerFn(output, props, prop)\n      };\n    });\n  } else if (isObj(props)) {\n    for (var k in props) {\n      var prop = props[k];\n\n      // notsupport obj\n      if (!isObj(prop)) {\n        newProps[k] = prop;\n      } else {\n        newProps[k] = prop.default ? prop.default : '';\n      }\n    }\n  }\n\n  newProps['onInit'] = '';\n  output.properties = newProps;\n}\n\n/*\n * init props\n */\nfunction initProps(vm, properties) {\n  vm._props = {};\n\n  if (!properties) {\n    return;\n  }\n\n  Object.keys(properties).forEach(function (key) {\n    vm._props[key] = properties[key].value;\n    proxy(vm, '_props', key);\n  });\n\n  observe({\n    vm: vm,\n    key: '',\n    value: vm._props,\n    root: true\n  });\n}\n\nfunction initRender(vm, keys, computedKeys) {\n  vm._init = false;\n  var dirtyFromAttach = null;\n  return new Watcher(\n    vm,\n    function() {\n      if (!vm._init) {\n        keys.forEach(function (key) { return clone(vm[key]); });\n      }\n\n      if (vm.$dirty.length() || dirtyFromAttach) {\n        var keys$1 = vm.$dirty.get('key');\n        computedKeys.forEach(function (key) { return vm[key]; });\n        var dirty = vm.$dirty.pop();\n\n        // TODO: reset subs\n        Object.keys(keys$1).forEach(function (key) { return clone(vm[key]); });\n\n        if (vm._init) {\n          dirty = callUserHook(vm, 'before-setData', dirty);\n        }\n\n        // vm._fromSelf = true;\n        if (dirty || dirtyFromAttach) {\n          // init render is in lifecycle, setData in lifecycle will not work, so cacheData is needed.\n          if (!vm._init) {\n            if (dirtyFromAttach === null) {\n              dirtyFromAttach = {};\n            }\n            Object.assign(dirtyFromAttach, dirty);\n          } else if (dirtyFromAttach) {\n            // setData in attached\n            vm.$wx.setData(Object.assign(dirtyFromAttach, dirty || {}), renderFlushCallbacks);\n            dirtyFromAttach = null;\n          } else {\n            vm.$wx.setData(dirty, renderFlushCallbacks);\n          }\n        }\n      }\n      vm._init = true;\n    },\n    function() {},\n    null,\n    true\n  );\n}\n\nvar Event = function Event(e) {\n  var detail = e.detail;\n  var target = e.target;\n  var currentTarget = e.currentTarget;\n  this.$wx = e;\n  this.type = e.type;\n  this.timeStamp = e.timeStamp;\n  if (detail) {\n    this.x = detail.x;\n    this.y = detail.y;\n  }\n\n  this.target = target;\n  this.currentTarget = currentTarget;\n  this.touches = e.touches;\n  this.changedTouches = e.changedTouches;\n};\n\n/**\n * Transform wxml data-xx params to an array\n */\nfunction transformParams(dataset, type, hasModel) {\n  if ( hasModel === void 0 ) hasModel = false;\n\n  var i = 0;\n  var params = [];\n  var modelParams = [];\n\n  var noParams = false;\n  var noModelParams = !hasModel;\n\n  var camelizedType = camelize(type);\n  while (i++ < 26 && (!noParams || !noModelParams)) {\n    var alpha = String.fromCharCode(64 + i);\n    if (!noParams) {\n      var key = 'wpy' + camelizedType + alpha;\n      if (!(key in dataset)) {\n        // it can be undefined;\n        noParams = true;\n      } else {\n        params.push(dataset[key]);\n      }\n    }\n    if (!noModelParams && hasModel) {\n      var modelKey = 'model' + alpha;\n      if (!(modelKey in dataset)) {\n        noModelParams = true;\n      } else {\n        modelParams.push(dataset[modelKey]);\n      }\n    }\n  }\n\n  return {\n    handler: params,\n    model: modelParams\n  };\n}\n\nvar dispatcher = function(e) {\n  var vm = this.$wepy;\n  var type = e.type;\n  // touchstart do not have currentTarget\n  var dataset = (e.currentTarget || e.target).dataset || {};\n  var evtid = dataset.wpyEvt;\n  var modelId = dataset.modelId;\n  var rel = vm.$rel || {};\n  var handler = rel.handlers && rel.handlers[evtid] && rel.handlers[evtid][type];\n  var model = rel.models && rel.models[modelId];\n\n  if (!handler && !model) {\n    return;\n  }\n\n  var params = transformParams(dataset, type, !!model);\n\n  // Call model method\n  if (model && type === model.type && isFunc(model.handler)) {\n    model.handler.call(vm, e.detail.value, params.model);\n  }\n\n  // Call handler method\n  if (isFunc(handler)) {\n    var $event = new Event(e);\n    var paramsWithEvent = params.handler.concat($event);\n    var args = (e.detail && e.detail.arguments) || [];\n\n    var hookRes = callUserHook(vm, 'before-event', {\n      event: $event,\n      params: paramsWithEvent,\n      args: args\n    });\n\n    if (hookRes === false) {\n      // Event cancelled.\n      return;\n    }\n    return handler.apply(vm, paramsWithEvent);\n  } else if (!model) {\n    throw new Error('Unrecognized event');\n  }\n};\n\n/*\n * initialize page methods, also the app\n */\nfunction initMethods(vm, methods) {\n  if (methods) {\n    Object.keys(methods).forEach(function (method) {\n      vm[method] = methods[method];\n    });\n  }\n}\n\n/*\n * patch method option\n */\nfunction patchMethods(output, methods, isComponent) {\n  output.methods = {};\n  var target = isComponent ? output.methods : output;\n\n  target.__initComponent = function(e) {\n    var child = e;\n    var ref = e.$wx.props['data-ref'];\n    var wpyEvt = e.$wx.props['data-wpy-evt'];\n\n    var vm = this.$wepy;\n    vm.$children.push(child);\n    if (ref) {\n      if (vm.$refs[ref]) {\n        warn('duplicate ref \"' + ref + '\" will be covered by the last instance.\\n', vm);\n      }\n      vm.$refs[ref] = child;\n    }\n    child.$evtId = wpyEvt;\n    child.$parent = vm;\n    child.$app = vm.$app;\n    child.$root = vm.$root;\n    // 支付宝组件嵌套时，子组件执行早已组件\n    if (e.$children && e.$children.length) {\n      e.$children.forEach(function (x) {\n        x.$app = vm.$app;\n        x.$root = vm.$root;\n      });\n    }\n    return vm;\n  };\n  target.__dispatcher = dispatcher;\n\n  // TODO: perf\n  // Only orginal component method goes to target. no need to add all methods.\n  if (methods) {\n    Object.keys(methods).forEach(function (method) {\n      target[method] = methods[method];\n    });\n  }\n}\n\n/*\n * initialize events\n */\nfunction initEvents(vm) {\n  var parent = vm.$parent;\n  var rel = parent.$rel;\n  vm._events = {};\n  var on = rel.info.on;\n  var evtId = vm.$evtId;\n  if (!evtId) { return; }\n\n  var evtNames = on[evtId];\n\n  evtNames.forEach(function (evtName) {\n    vm.$on(evtName, function() {\n      var fn = rel.handlers[evtId][evtName];\n      fn.apply(parent, arguments);\n    });\n  });\n}\n\nvar Dirty = function Dirty(type) {\n  this.reset();\n\n  // path||key\n  this.type = type || 'path';\n};\n\nDirty.prototype.push = function push (key, path, keyValue, pathValue) {\n  if (pathValue === undefined) {\n    return;\n  }\n  this._keys[key] = keyValue;\n  this._path[path] = pathValue;\n  this._length++;\n};\n\nDirty.prototype.pop = function pop () {\n  var data = Object.create(null);\n  if (this.type === 'path') {\n    data = this._path;\n  } else if (this.type === 'key') {\n    data = this._keys;\n  }\n  this.reset();\n  return data;\n};\n\nDirty.prototype.get = function get (type) {\n  return type === 'path' ? this._path : this._keys;\n};\n\n/**\n * Set dirty from a ObserverPath\n */\nDirty.prototype.set = function set (op, key, value) {\n  var pathMap;\n  var pathKeys;\n  // eslint-disable-next-line eqeqeq\n  if (key != null) {\n    var ref = getPathMap(key, op.pathKeys, op.pathMap);\n      var combinePathKeys = ref.combinePathKeys;\n      var combinePathMap = ref.combinePathMap;\n    pathKeys = combinePathKeys;\n    pathMap = combinePathMap;\n  } else {\n    pathKeys = op.pathKeys;\n    pathMap = op.pathMap;\n  }\n  /**\n   * 出于性能考虑，使用 usingComponents 时， setData 内容不会被直接深复制，\n   * 即 this.setData({ field: obj }) 后 this.data.field === obj 。\n   * 因此不需要所有 path 都 setData 。\n   */\n  var ref$1 = pathMap[pathKeys[0]];\n    var root = ref$1.root;\n    var path = ref$1.path;\n  this.push(root, path, root === path ? value : op.ob.vm[root], value);\n};\n\nDirty.prototype.reset = function reset () {\n  this._keys = {};\n  this._path = {};\n  this._length = 0;\n  return this;\n};\n\nDirty.prototype.length = function length () {\n  return this._length;\n};\n\nvar comid = 0;\nvar app;\n\nvar callUserMethod = function(vm, userOpt, method, args) {\n  var result;\n  var methods = userOpt[method];\n  if (isFunc(methods)) {\n    result = userOpt[method].apply(vm, args);\n  } else if (isArr(methods)) {\n    for (var i in methods) {\n      if (isFunc(methods[i])) {\n        result = methods[i].apply(vm, args);\n      }\n    }\n  }\n  return result;\n};\n\nvar getLifecycycle = function (defaultLifecycle, rel, type) {\n  var lifecycle = defaultLifecycle.concat([]);\n  if (rel && rel.lifecycle && rel.lifecycle[type]) {\n    var userDefinedLifecycle = [];\n    if (isFunc(rel.lifecycle[type])) {\n      userDefinedLifecycle = rel.lifecycle[type].call(null, lifecycle);\n    }\n    userDefinedLifecycle.forEach(function (u) {\n      if (lifecycle.indexOf(u) > -1) {\n        warn((\"'\" + u + \"' is already implemented in current version, please remove it from your lifecycel config\"));\n      } else {\n        lifecycle.push(u);\n      }\n    });\n  }\n  return lifecycle;\n};\n\n/*\n * patch app lifecyle\n */\nfunction patchAppLifecycle(appConfig, options, rel) {\n  if ( rel === void 0 ) rel = {};\n\n  appConfig.onLaunch = function() {\n    var args = [], len = arguments.length;\n    while ( len-- ) args[ len ] = arguments[ len ];\n\n    var vm = new WepyApp();\n    app = vm;\n    vm.$options = options;\n    vm.$route = {};\n    vm.$rel = rel;\n\n    vm.$wx = this;\n    this.$wepy = vm;\n\n    initHooks(vm, options.hooks);\n\n    initMethods(vm, options.methods);\n\n    return callUserMethod(vm, vm.$options, 'onLaunch', args);\n  };\n\n  var lifecycle = getLifecycycle(WEAPP_APP_LIFECYCLE, rel, 'app');\n\n  lifecycle.forEach(function (k) {\n    // it's not defined aready && user defined it && it's an array or function\n    if (!appConfig[k] && options[k] && (isFunc(options[k]) || isArr(options[k]))) {\n      appConfig[k] = function() {\n        var args = [], len = arguments.length;\n        while ( len-- ) args[ len ] = arguments[ len ];\n\n        return callUserMethod(app, app.$options, k, args);\n      };\n    }\n  });\n}\n\nfunction patchLifecycle(output, options, rel, isComponent) {\n  var initClass = isComponent ? WepyComponent : WepyPage;\n  var initLifecycle = function() {\n    var args = [], len = arguments.length;\n    while ( len-- ) args[ len ] = arguments[ len ];\n\n    var vm = new initClass();\n\n    vm.$dirty = new Dirty('path');\n    vm.$children = [];\n    vm.$refs = {};\n\n    this.$wepy = vm;\n    vm.$wx = this;\n    vm.$is = this.is;\n    vm.$options = options;\n    vm.$rel = rel;\n    vm._watchers = [];\n    if (!isComponent) {\n      vm.$root = vm;\n      vm.$app = app;\n    }\n    if (this.is === 'custom-tab-bar/index') {\n      vm.$app = app;\n      vm.$parent = app;\n    }\n\n    vm.$id = ++comid + (isComponent ? '.1' : '.0');\n\n    callUserMethod(vm, vm.$options, 'beforeCreate', args);\n\n    initHooks(vm, options.hooks);\n\n    initProps(vm, output.properties);\n\n    initData(vm, output.data, isComponent);\n\n    initMethods(vm, options.methods);\n\n    initComputed(vm, options.computed, true);\n\n    initWatch(vm, options.watch);\n\n    // create render watcher\n    initRender(\n      vm,\n      Object.keys(vm._data)\n        .concat(Object.keys(vm._props))\n        .concat(Object.keys(vm._computedWatchers || {})),\n      Object.keys(vm._computedWatchers || {})\n    );\n\n    callUserMethod(vm, vm.$options, 'created', args);\n    return callUserMethod(vm, vm.$options, 'onLoad', args);\n  };\n\n  if (isComponent) {\n    output.onInit = initLifecycle; // 组件生命周期函数，组件创建时触发\n  } else {\n    output.onLoad = initLifecycle; // 页面加载时触发\n  }\n\n  if (isComponent) {\n    output.didMount = function() {\n      var args = [], len = arguments.length;\n      while ( len-- ) args[ len ] = arguments[ len ];\n\n      // Component attached  组件生命周期函数，组件创建完毕时触发\n      var outProps = output.properties || {};\n\n      // this.propperties are includes datas\n      var vm = this.$wepy;\n      var acceptProps = vm.$wx.props;\n\n      // let target = isComponent ? output.methods: output;\n      // target.__initComponent(vm);\n      vm.$wx.props.onInit(vm);\n      // let parent = this.triggerEvent('_init', vm);\n\n      // created 不能调用 setData，如果有 dirty 在此更新\n      vm.$forceUpdate();\n\n      initEvents(vm);\n\n      Object.keys(outProps).forEach(function (k) { return (vm[k] = acceptProps[k]); });\n\n      return callUserMethod(vm, vm.$options, 'didMount', args);\n    };\n  } else {\n    output.onShow = function() {\n      var args = [], len = arguments.length;\n      while ( len-- ) args[ len ] = arguments[ len ];\n\n      // Page attached\n      var vm = this.$wepy;\n      var app = vm.$app;\n      // eslint-disable-next-line\n      var pages = getCurrentPages();\n      var currentPage = pages[pages.length - 1];\n      var path = currentPage.__route__;\n      var webViewId = currentPage.__wxWebviewId__;\n\n      // created 不能调用 setData，如果有 dirty 在此更新\n      vm.$forceUpdate();\n\n      if (app.$route.path !== path) {\n        app.$route.path = path;\n        app.$route.webViewId = webViewId;\n        vm.routed && vm.routed();\n      }\n\n      // TODO: page attached\n      return callUserMethod(vm, vm.$options, 'onShow', args);\n    };\n    // Page lifecycle will be called under methods\n    // e.g:\n    // Component({\n    //   methods: {\n    //     onLoad () {\n    //       console.log('page onload')\n    //     }\n    //   }\n    // })\n\n    var lifecycle$1 = getLifecycycle(WEAPP_PAGE_LIFECYCLE, rel, 'page');\n\n    lifecycle$1.forEach(function (k) {\n      if (!output[k] && options[k] && (isFunc(options[k]) || isArr(options[k]))) {\n        output.methods[k] = function() {\n          var args = [], len = arguments.length;\n          while ( len-- ) args[ len ] = arguments[ len ];\n\n          return callUserMethod(this.$wepy, this.$wepy.$options, k, args);\n        };\n      }\n    });\n  }\n  var lifecycle = getLifecycycle(WEAPP_COMPONENT_LIFECYCLE, rel, 'component');\n\n  lifecycle.forEach(function (k) {\n    // beforeCreate is not a real lifecycle\n    if (!output[k] && k !== 'beforeCreate' && (isFunc(options[k]) || isArr(options[k]))) {\n      output[k] = function() {\n        var args = [], len = arguments.length;\n        while ( len-- ) args[ len ] = arguments[ len ];\n\n        return callUserMethod(this.$wepy, this.$wepy.$options, k, args);\n      };\n    }\n  });\n}\n\nvar config$1 = {\n  optionMergeStrategies: {},\n  constants: {\n    WEAPP_LIFECYCLE: WEAPP_LIFECYCLE,\n    WEAPP_APP_LIFECYCLE: WEAPP_APP_LIFECYCLE,\n    WEAPP_PAGE_LIFECYCLE: WEAPP_PAGE_LIFECYCLE,\n    WEAPP_COMPONENT_LIFECYCLE: WEAPP_COMPONENT_LIFECYCLE\n  }\n};\n\n// [Default Strategy]\n// Update if it's not exist in output. Can be replaced by option[key].\n// e.g.\n// export default {\n//   myCustomMethod () {\n//     // doSomething\n//   }\n// }\n//\n// [Merge Strategy]\n// Replaced by the latest mixins property.\n// e.g.\n// export default {\n//   data: {\n//     a: 1\n//   }\n// }\n//\n// [Lifecycle Strategy]\n// Extend lifecycle. update lifecycle to an array.\n// e.g.\n// export default {\n//   onShow: {\n//     console.log('onShow');\n//   }\n// }\nvar globalMixinPatched = false;\n\nvar strats = null;\n\nfunction getStrategy(key) {\n  if (!strats) {\n    initStrats();\n  }\n  if (strats[key]) {\n    return strats[key];\n  } else {\n    return defaultStrat;\n  }\n}\nfunction defaultStrat(output, option, key, data) {\n  if (!output[key]) {\n    output[key] = data;\n  }\n}\n\nfunction simpleMerge(parentVal, childVal) {\n  return !parentVal || !childVal ? parentVal || childVal : Object.assign({}, parentVal, childVal);\n}\n\nfunction initStrats() {\n  if (strats) { return strats; }\n\n  strats = config$1.optionMergeStrategies;\n\n  strats.data = strats.props = strats.methods = strats.computed = strats.watch = strats.hooks = function mergeStrategy(\n    output,\n    option,\n    key,\n    data\n  ) {\n    option[key] = simpleMerge(option[key], data);\n  };\n\n  WEAPP_LIFECYCLE.forEach(function (lifecycle) {\n    if (!strats[lifecycle]) {\n      strats[lifecycle] = function lifeCycleStrategy(output, option, key, data) {\n        if (!option[key]) {\n          option[key] = isArr(data) ? data : [data];\n        } else {\n          option[key] = [data].concat(option[key]);\n        }\n      };\n    }\n  });\n}\n\nfunction patchMixins(output, option, mixins) {\n  if (!mixins && !$global.mixin) {\n    return;\n  }\n\n  if (!globalMixinPatched) {\n    var globalMixin = $global.mixin || [];\n\n    mixins = globalMixin.concat(mixins);\n    globalMixinPatched = true;\n  }\n\n  if (isArr(mixins)) {\n    mixins.forEach(function (mixin) { return patchMixins(output, option, mixin); });\n    globalMixinPatched = false;\n  } else {\n    if (!strats) {\n      initStrats();\n    }\n    for (var k in mixins) {\n      strat = getStrategy(k);\n      var strat = strats[k] || defaultStrat;\n      strat(output, option, k, mixins[k]);\n    }\n  }\n}\n\nfunction patchRelations(output, relations) {\n  if (!relations) {\n    relations = {};\n  }\n  output.relations = relations;\n}\n\nfunction app$1(option, rel) {\n  var appConfig = {};\n\n  patchMixins(appConfig, option, option.mixins);\n  patchAppLifecycle(appConfig, option, rel);\n\n  return App(appConfig);\n}\n\nfunction component(opt, rel) {\n  if ( opt === void 0 ) opt = {};\n\n  var compConfig = {\n    externalClasses: opt.externalClasses || [],\n    // support component options property\n    // example: options: {addGlobalClass:true}\n    options: opt.options || {}\n  };\n\n  patchMixins(compConfig, opt, opt.mixins);\n\n  if (opt.properties) {\n    compConfig.props = opt.properties;\n    if (opt.props) {\n      // eslint-disable-next-line no-console\n      console.warn(\"props will be ignore, if properties is set\");\n    }\n  } else if (opt.props) {\n    patchProps(compConfig, opt.props);\n  }\n\n  compConfig.props = compConfig.properties;\n\n  patchMethods(compConfig, opt.methods, true);\n\n  patchData(compConfig, opt.data, true);\n\n  patchRelations(compConfig, opt.relations);\n\n  patchLifecycle(compConfig, opt, rel, true);\n\n  return Component(compConfig);\n}\n\nfunction page(opt, rel) {\n  if ( opt === void 0 ) opt = {};\n\n  var pageConfig = {\n    externalClasses: opt.externalClasses || [],\n    // support component options property\n    // example: options: {addGlobalClass:true}\n    options: opt.options || {}\n  };\n\n  patchMixins(pageConfig, opt, opt.mixins);\n\n  if (opt.properties) {\n    pageConfig.properties = opt.properties;\n    if (opt.props) {\n      // eslint-disable-next-line\n      console.warn(\"props will be ignore, if properties is set\");\n    }\n  } else if (opt.props) {\n    patchProps(pageConfig, opt.props);\n  }\n\n  patchMethods(pageConfig, opt.methods);\n\n  patchData(pageConfig, opt.data);\n\n  patchLifecycle(pageConfig, opt, rel);\n\n  return Page(pageConfig);\n}\n\nfunction initGlobalAPI(wepy) {\n  wepy.use = use;\n  wepy.mixin = mixin;\n\n  wepy.set = function(target, key, val) {\n    set.apply(wepy, [undefined, target, key, val]);\n  };\n\n  wepy.delete = del;\n\n  wepy.observe = observe;\n\n  wepy.nextTick = renderNextTick;\n\n  wepy.app = app$1;\n  wepy.page = page;\n  wepy.component = component;\n\n  return wepy;\n}\n\nvar wepy = initGlobalAPI(WepyConstructor);\n\nwepy.config = config$1;\nwepy.global = $global;\nwepy.version = \"2.0.0-alpha.16\";\n\nmodule.exports = wepy;\n"
  },
  {
    "path": "packages/core/dist/wepy.js",
    "content": "'use strict';\n\n// can we use __proto__?\nfunction getHasProto() {\n  var hasProto = false;\n  if ('__proto__' in {}) {\n    var fn = function () {};\n    var arr = [];\n    arr.__proto__ = { push: fn };\n    hasProto = fn === arr.push;\n  }\n  return hasProto;\n}\nvar hasProto = getHasProto();\n\nvar _Set; // $flow-disable-line\n/* istanbul ignore if */ if (typeof Set !== 'undefined' && isNative(Set)) {\n  // use native Set when available.\n  _Set = Set;\n} else {\n  // a non-standard Set polyfill that only works with primitive keys.\n  _Set = /*@__PURE__*/(function () {\n    function Set() {\n      this.set = Object.create(null);\n    }\n    Set.prototype.has = function has (key) {\n      return this.set[key] === true;\n    };\n    Set.prototype.add = function add (key) {\n      this.set[key] = true;\n    };\n    Set.prototype.clear = function clear () {\n      this.set = Object.create(null);\n    };\n\n    return Set;\n  }());\n}\n\n/* istanbul ignore next */\nfunction isNative(Ctor) {\n  return typeof Ctor === 'function' && /native code/.test(Ctor.toString());\n}\n\n/**\n * String type check\n */\nvar isStr = function (v) { return typeof v === 'string'; };\n/**\n * Number type check\n */\nvar isNum = function (v) { return typeof v === 'number'; };\n/**\n * Array type check\n */\nvar isArr = Array.isArray;\n/**\n * undefined type check\n */\nvar isUndef = function (v) { return v === undefined; };\n/**\n * Function type check\n */\nvar isFunc = function (v) { return typeof v === 'function'; };\n/**\n * Quick object check - this is primarily used to tell\n * Objects from primitive values when we know the value\n * is a JSON-compliant type.\n */\nfunction isObject(obj) {\n  return obj !== null && typeof obj === 'object';\n}\n\nvar isObj = isObject;\n/**\n * Strict object type check. Only returns true\n * for plain JavaScript objects.\n */\nvar _toString = Object.prototype.toString;\nfunction isPlainObject(obj) {\n  return _toString.call(obj) === '[object Object]';\n}\n\n/**\n * Check whether the object has the property.\n */\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\nfunction hasOwn(obj, key) {\n  return hasOwnProperty.call(obj, key);\n}\n\n/**\n * Perform no operation.\n * Stubbing args to make Flow happy without leaving useless transpiled code\n * with ...rest (https://flow.org/blog/2017/05/07/Strict-Function-Call-Arity/)\n */\n// eslint-disable-next-line\nfunction noop(a, b, c) {}\n\n/**\n * Check if val is a valid array index.\n */\nfunction isValidArrayIndex(val) {\n  var n = parseFloat(String(val));\n  return n >= 0 && Math.floor(n) === n && isFinite(val);\n}\n\n/**\n * Convert an Array-lik object to a real Array\n */\nfunction toArray(list, start) {\n  if ( start === void 0 ) start = 0;\n\n  var i = list.length - start;\n  var rst = new Array(i);\n  while (i--) {\n    rst[i] = list[i + start];\n  }\n  return rst;\n}\n\n/**\n * Cached simply key function return\n */\nvar cached = function (fn) {\n  var cache = {};\n  return function (str) { return cache[str] || (cache[str] = fn(str)); };\n};\n\nvar camelizeRE = /-(\\w)/g;\n\n/**\n * camelize words\n * e.g. my-key => myKey\n */\nvar camelize = cached(function (str) { return str.replace(camelizeRE, function (_, c) { return (c ? c.toUpperCase() : ''); }); });\n\n/*\n * extend objects\n * e.g.\n * extend({}, {a: 1}) : extend {a: 1} to {}\n * extend(true, [], [1,2,3]) : deep extend [1,2,3] to an empty array\n * extend(true, {}, {a: 1}, {b: 2}) : deep extend two objects to {}\n */\nfunction extend() {\n  var arguments$1 = arguments;\n\n  var options,\n    name,\n    src,\n    copy,\n    copyIsArray,\n    clone,\n    target = arguments[0] || {},\n    i = 1,\n    length = arguments.length,\n    deep = false;\n\n  // Handle a deep copy situation\n  if (typeof target === 'boolean') {\n    deep = target;\n\n    // Skip the boolean and the target\n    target = arguments[i] || {};\n    i++;\n  }\n\n  // Handle case when target is a string or something (possible in deep copy)\n  if (typeof target !== 'object' && !(typeof target === 'function')) {\n    target = {};\n  }\n\n  // Extend jQuery itself if only one argument is passed\n  if (i === length) {\n    target = this;\n    i--;\n  }\n\n  for (; i < length; i++) {\n    // Only deal with non-null/undefined values\n    if ((options = arguments$1[i])) {\n      // Extend the base object\n      for (name in options) {\n        src = target[name];\n        copy = options[name];\n\n        // Prevent never-ending loop\n        if (target === copy) {\n          continue;\n        }\n\n        // Recurse if we're merging plain objects or arrays\n        if (deep && copy && (isPlainObject(copy) || (copyIsArray = Array.isArray(copy)))) {\n          if (copyIsArray) {\n            copyIsArray = false;\n            clone = src && Array.isArray(src) ? src : [];\n          } else {\n            clone = src && isPlainObject(src) ? src : {};\n          }\n\n          // Never move original objects, clone them\n          target[name] = extend(deep, clone, copy);\n\n          // Don't bring in undefined values => bring undefined values\n        } else {\n          target[name] = copy;\n        }\n      }\n    }\n  }\n\n  // Return the modified object\n  return target;\n}\n\n/*\n * clone objects, return a cloned object default to use deep clone\n * e.g.\n * clone({a: 1})\n * clone({a: b: {c : 1}}, false);\n */\nfunction clone(sth, deep) {\n  if ( deep === void 0 ) deep = true;\n\n  if (isArr(sth)) {\n    return extend(deep, [], sth);\n  } else if ('' + sth === 'null') {\n    return sth;\n  } else if (isPlainObject(sth)) {\n    return extend(deep, {}, sth);\n  } else {\n    return sth;\n  }\n}\n\nvar WEAPP_APP_LIFECYCLE = ['onLaunch', 'onShow', 'onHide', 'onError', 'onPageNotFound'];\n\nvar WEAPP_PAGE_LIFECYCLE = [\n  'onLoad',\n  'onShow',\n  'onReady',\n  'onHide',\n  'onUnload',\n  'onPullDownRefresh',\n  'onReachBottom',\n  'onShareAppMessage',\n  'onPageScroll',\n  'onTabItemTap',\n  'onResize'\n];\n\nvar WEAPP_COMPONENT_LIFECYCLE = ['beforeCreate', 'created', 'attached', 'ready', 'moved', 'detached'];\n\nvar WEAPP_LIFECYCLE = []\n  .concat(WEAPP_APP_LIFECYCLE)\n  .concat(WEAPP_PAGE_LIFECYCLE)\n  .concat(WEAPP_COMPONENT_LIFECYCLE);\n\nvar config = {};\n\nvar warn = noop;\n\nvar generateComponentTrace = function(vm) {\n  return (\"Found in component: \\\"\" + (vm.$is) + \"\\\"\");\n};\n\n{\n  var hasConsole = typeof console !== 'undefined';\n  // TODO\n  warn = function (msg, vm) {\n    if (hasConsole && !config.silent) {\n      // eslint-disable-next-line\n      console.error(\"[WePY warn]: \" + msg + (vm ? generateComponentTrace(vm) : ''));\n    }\n  };\n}\n\nfunction handleError(err, vm, info) {\n  if (vm) {\n    var cur = vm;\n    while ((cur = cur.$parent)) {\n      var hooks = cur.$options.errorCaptured;\n      if (hooks) {\n        for (var i = 0; i < hooks.length; i++) {\n          try {\n            var capture = hooks[i].call(cur, err, vm, info) === false;\n            if (capture) { return; }\n          } catch (e) {\n            globalHandleError(e, cur, 'errorCaptured hook');\n          }\n        }\n      }\n    }\n  }\n  globalHandleError(err, vm, info);\n}\n\nfunction globalHandleError(err, vm, info) {\n  if (config.errorHandler) {\n    try {\n      return config.errorHandler.call(null, err, vm, info);\n    } catch (e) {\n      logError(e, null, 'config.errorHandler');\n    }\n  }\n  logError(err, vm, info);\n}\n\nfunction logError(err, vm, info) {\n  {\n    warn((\"Error in \" + info + \": \\\"\" + (err.toString()) + \"\\\"\"), vm);\n  }\n  /* istanbul ignore else */\n  if (typeof console !== 'undefined') {\n    // eslint-disable-next-line\n    console.error(err);\n  } else {\n    throw err;\n  }\n}\n\nvar callbacks = [];\nvar pending = false;\n\nfunction flushCallbacks() {\n  pending = false;\n  var copies = callbacks.slice(0);\n  callbacks.length = 0;\n  for (var i = 0; i < copies.length; i++) {\n    copies[i]();\n  }\n}\n\n// Here we have async deferring wrappers using both micro and macro tasks.\n// In < 2.4 we used micro tasks everywhere, but there are some scenarios where\n// micro tasks have too high a priority and fires in between supposedly\n// sequential events (e.g. #4521, #6690) or even between bubbling of the same\n// event (#6566). However, using macro tasks everywhere also has subtle problems\n// when state is changed right before repaint (e.g. #6813, out-in transitions).\n// Here we use micro task by default, but expose a way to force macro task when\n// needed (e.g. in event handlers attached by v-on).\nvar microTimerFunc;\nvar macroTimerFunc;\nvar useMacroTask = false;\n\n// Determine (macro) Task defer implementation.\n// Technically setImmediate should be the ideal choice, but it's only available\n// in IE. The only polyfill that consistently queues the callback after all DOM\n// events triggered in the same loop is by using MessageChannel.\n/* istanbul ignore if */\nif (typeof setImmediate !== 'undefined' && isNative(setImmediate)) {\n  macroTimerFunc = function () {\n    setImmediate(flushCallbacks);\n  };\n} else if (\n  /* eslint-disable no-undef */\n  typeof MessageChannel !== 'undefined' &&\n  (isNative(MessageChannel) ||\n    // PhantomJS\n    MessageChannel.toString() === '[object MessageChannelConstructor]')\n) {\n  var channel = new MessageChannel();\n  var port = channel.port2;\n  channel.port1.onmessage = flushCallbacks;\n  macroTimerFunc = function () {\n    port.postMessage(1);\n  };\n  /* eslint-enable no-undef */\n} else {\n  /* istanbul ignore next */\n  macroTimerFunc = function () {\n    setTimeout(flushCallbacks, 0);\n  };\n}\n\n// Determine MicroTask defer implementation.\n/* istanbul ignore next, $flow-disable-line */\nif (typeof Promise !== 'undefined' && isNative(Promise)) {\n  var p = Promise.resolve();\n  microTimerFunc = function () {\n    p.then(flushCallbacks);\n    // in problematic UIWebViews, Promise.then doesn't completely break, but\n    // it can get stuck in a weird state where callbacks are pushed into the\n    // microtask queue but the queue isn't being flushed, until the browser\n    // needs to do some other work, e.g. handle a timer. Therefore we can\n    // \"force\" the microtask queue to be flushed by adding an empty timer.\n    // if (isIOS) setTimeout(noop)\n  };\n} else {\n  // fallback to macro\n  microTimerFunc = macroTimerFunc;\n}\n\nfunction nextTick(cb, ctx) {\n  var _resolve;\n  callbacks.push(function () {\n    if (cb) {\n      try {\n        cb.call(ctx);\n      } catch (e) {\n        handleError(e, ctx, 'nextTick');\n      }\n    } else if (_resolve) {\n      _resolve(ctx);\n    }\n  });\n  if (!pending) {\n    pending = true;\n    if (useMacroTask) {\n      macroTimerFunc();\n    } else {\n      microTimerFunc();\n    }\n  }\n  // $flow-disable-line\n  if (!cb && typeof Promise !== 'undefined') {\n    return new Promise(function (resolve) {\n      _resolve = resolve;\n    });\n  }\n}\n\nvar renderCallbacks = [];\n\nfunction renderFlushCallbacks() {\n  var copies = renderCallbacks.slice(0);\n  renderCallbacks.length = 0;\n  for (var i = 0; i < copies.length; i++) {\n    copies[i]();\n  }\n}\n\nfunction renderNextTick(cb, ctx) {\n  var _resolve;\n  renderCallbacks.push(function () {\n    if (cb) {\n      try {\n        cb.call(ctx);\n      } catch (e) {\n        handleError(e, ctx, 'nextTick');\n      }\n    } else if (_resolve) {\n      _resolve(ctx);\n    }\n  });\n\n  if (!cb && typeof Promise !== 'undefined') {\n    return new Promise(function (resolve) {\n      _resolve = resolve;\n    });\n  }\n}\n\n/**\n * Parse a v-model expression into a base path and a final key segment.\n * Handles both dot-path and possible square brackets.\n *\n * Possible cases:\n *\n * - test\n * - test[key]\n * - test[test1[key]]\n * - test[\"a\"][key]\n * - xxx.test[a[a].test1[key]]\n * - test.xxx.a[\"asa\"][test1[key]]\n *\n */\n\n/**\n * Remove an item from an array\n */\nfunction remove(arr, item) {\n  if (arr.length) {\n    var index = arr.indexOf(item);\n    if (index > -1) {\n      return arr.splice(index, 1);\n    }\n  }\n}\n\n/**\n * Define a property.\n */\nfunction def(obj, key, val, enumerable) {\n  Object.defineProperty(obj, key, {\n    value: val,\n    enumerable: !!enumerable,\n    writable: true,\n    configurable: true\n  });\n}\n\n/**\n * Parse simple path.\n */\nvar bailRE = /[^\\w.$]/;\nfunction parsePath(path) {\n  if (bailRE.test(path)) {\n    return;\n  }\n  var segments = path.split('.');\n  return function(obj) {\n    for (var i = 0; i < segments.length; i++) {\n      if (!obj) { return; }\n      obj = obj[segments[i]];\n    }\n    return obj;\n  };\n}\n\n// import type Watcher from './watcher'\n\nvar uid = 0;\n\n/**\n * A dep is an observable that can have multiple\n * directives subscribing to it.\n */\nvar Dep = function Dep() {\n  this.id = uid++;\n  this.subs = [];\n};\n\nDep.prototype.addSub = function addSub (sub) {\n  this.subs.push(sub);\n};\n\nDep.prototype.removeSub = function removeSub (sub) {\n  remove(this.subs, sub);\n};\n\nDep.prototype.depend = function depend () {\n  if (Dep.target) {\n    Dep.target.addDep(this);\n  }\n};\n\nDep.prototype.notify = function notify () {\n  // stabilize the subscriber list first\n  var subs = this.subs.slice();\n  for (var i = 0, l = subs.length; i < l; i++) {\n    subs[i].update();\n  }\n};\n\n// the current target watcher being evaluated.\n// this is globally unique because there could be only one\n// watcher being evaluated at any time.\nDep.target = null;\nvar targetStack = [];\n\nfunction pushTarget(_target) {\n  if (Dep.target) { targetStack.push(Dep.target); }\n  Dep.target = _target;\n}\n\nfunction popTarget() {\n  Dep.target = targetStack.pop();\n}\n\n/**\n * @desc ObserverPath 类以及相关处理函数\n * Observer 所在位置对应在整棵 data tree 的路径集合\n * @createDate 2019-07-21\n */\n\n/**\n * 生成完整路径\n * @param key  {String|Number} 当为字符串时，说明是属性名，当为数字时，说明是索引\n * @param parentPath {String} 父路径\n * @return {string}\n */\nvar setPath = function (key, parentPath) {\n  return isNum(key) ? (parentPath + \"[\" + key + \"]\") : (parentPath + \".\" + key);\n};\n\n/**\n * 得到 ObserverPath\n * @param value 被观察对象\n * @return {ObserverPath|null}\n */\nvar pickOp = function (value) {\n  return isObject(value) && hasOwn(value, '__ob__') ? value.__ob__.op : null;\n};\n\nvar ObserverPath = function ObserverPath(key, ob, parentOp) {\n  this.ob = ob;\n  // eslint-disable-next-line eqeqeq\n  if (parentOp) {\n    var ref = getPathMap(key, parentOp.pathKeys, parentOp.pathMap);\n    var combinePathKeys = ref.combinePathKeys;\n    var combinePathMap = ref.combinePathMap;\n    this.pathKeys = combinePathKeys;\n    this.pathMap = combinePathMap;\n  } else {\n    this.pathKeys = null;\n    this.pathMap = null;\n  }\n};\n\nObserverPath.prototype.traverseOp = function traverseOp (key, pathKeys, pathMap, handler) {\n  // 得到 newKey 和 pathMap 组合的路径集合\n  var ref = getPathMap(key, pathKeys, pathMap);\n    var combinePathMap = ref.combinePathMap;\n    var combinePathKeys = ref.combinePathKeys;\n  var handlePathKeys = [];\n  var handlePathMap = {};\n  var hasChange = false;\n\n  // 遍历 combinePathMap\n  for (var i = 0; i < combinePathKeys.length; i++) {\n    var pathObj = handler(combinePathMap[combinePathKeys[i]], this);\n    if (pathObj) {\n      hasChange = true;\n      handlePathKeys.push(pathObj.path);\n      handlePathMap[pathObj.path] = pathObj;\n    }\n  }\n\n  if (hasChange) {\n    var value = this.ob.value;\n    if (Array.isArray(value)) {\n      for (var i$1 = 0; i$1 < value.length; i$1++) {\n        var op = pickOp(value[i$1]);\n        op && op.traverseOp(i$1, handlePathKeys, handlePathMap, handler);\n      }\n    } else {\n      var keys = Object.keys(value);\n      for (var i$2 = 0; i$2 < keys.length; i$2++) {\n        var key$1 = keys[i$2];\n        var op$1 = pickOp(value[key$1]);\n        op$1 && op$1.traverseOp(key$1, handlePathKeys, handlePathMap, handler);\n      }\n    }\n  }\n};\n\nObserverPath.prototype.addPath = function addPath (pathObj) {\n  this.pathKeys.push(pathObj.path);\n  this.pathMap[pathObj.path] = pathObj;\n};\n\nObserverPath.prototype.delPath = function delPath (path) {\n  remove(this.pathKeys, path);\n  delete this.pathMap[path];\n};\n\n/**\n * 添加新的 __ob__ 的 path\n */\nfunction addPaths(newKey, op, parentOp) {\n  op.traverseOp(newKey, parentOp.pathKeys, parentOp.pathMap, handler);\n\n  function handler(pathObj, op) {\n    if (!(pathObj.path in op.pathMap)) {\n      // 新增一条 path\n      op.addPath(pathObj);\n      return pathObj;\n    } else {\n      return null;\n    }\n  }\n}\n\n/**\n * 删除指定的 __ob__ 的 path\n */\nfunction cleanPaths(oldKey, op, parentOp) {\n  op.traverseOp(oldKey, parentOp.pathKeys, parentOp.pathMap, handler);\n\n  function handler(pathObj, op) {\n    // 删除一条 path\n    op.delPath(pathObj.path);\n    return pathObj;\n  }\n}\n\n/**\n * 得到 pathMap 与 key 组合后的路径集合\n */\nfunction getPathMap(key, pathKeys, pathMap) {\n  var obj;\n\n  if (pathMap) {\n    // console.log('pathMap', pathMap)\n    var combinePathKeys = [];\n    var combinePathMap = {};\n    for (var i = 0; i < pathKeys.length; i++) {\n      var path = setPath(key, pathMap[pathKeys[i]].path);\n      combinePathKeys.push(path);\n      combinePathMap[path] = { key: key, root: pathMap[pathKeys[i]].root, path: path };\n    }\n    return { combinePathKeys: combinePathKeys, combinePathMap: combinePathMap };\n  } else {\n    return {\n      combinePathKeys: [key],\n      combinePathMap: ( obj = {}, obj[key] = { key: key, root: key, path: key }, obj)\n    };\n  }\n}\n\n/*\n * not type checking this file because flow doesn't play well with\n * dynamically accessing methods on Array prototype\n */\n\nvar arrayProto = Array.prototype;\nvar arrayMethods = Object.create(arrayProto);\n\nvar methodsToPatch = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'];\n\n/**\n * Intercept mutating methods and emit events\n */\nmethodsToPatch.forEach(function(method) {\n  // cache original method\n  var original = arrayProto[method];\n  def(arrayMethods, method, function mutator() {\n    var args = [], len$1 = arguments.length;\n    while ( len$1-- ) args[ len$1 ] = arguments[ len$1 ];\n\n    var len = this.length;\n    // 清除已经失效的 paths\n    if (len > 0) {\n      switch (method) {\n        case 'pop':\n          delInvalidPaths(len - 1, this[len - 1], this);\n          break;\n        case 'shift':\n          delInvalidPaths(0, this[0], this);\n          break;\n        case 'splice':\n        case 'sort':\n        case 'reverse':\n          for (var i = 0; i < this.length; i++) {\n            delInvalidPaths(i, this[i], this);\n          }\n      }\n    }\n\n    var result = original.apply(this, args);\n    var ob = this.__ob__;\n    var vm = ob.vm;\n\n    // push parent key to dirty, wait to setData\n    if (vm.$dirty) {\n      if (method === 'push') {\n        var lastIndex = ob.value.length - 1;\n        vm.$dirty.set(ob.op, lastIndex, ob.value[lastIndex]);\n      } else {\n        vm.$dirty.set(ob.op, null, ob.value);\n      }\n    }\n\n    // 这里和 vue 不一样，所有变异方法都需要更新 path\n    ob.observeArray(ob.key, ob.value);\n\n    // notify change\n    ob.dep.notify();\n    return result;\n  });\n});\n\nfunction delInvalidPaths(key, value, parent) {\n  if (isObject(value) && hasOwn(value, '__ob__')) {\n    // delete invalid paths\n    cleanPaths(key, value.__ob__.op, parent.__ob__.op);\n  }\n}\n\nvar arrayKeys = Object.getOwnPropertyNames(arrayMethods);\n\n/**\n * By default, when a reactive property is set, the new value is\n * also converted to become reactive. However when passing down props,\n * we don't want to force conversion because the value may be a nested value\n * under a frozen data structure. Converting it would defeat the optimization.\n */\nvar observerState = {\n  shouldConvert: true\n};\n\n/**\n * Observer class that are attached to each observed\n * object. Once attached, the observer converts target\n * object's property keys into getter/setters that\n * collect dependencies and dispatches updates.\n */\nvar Observer = function Observer(ref) {\n  var vm = ref.vm;\n  var key = ref.key;\n  var value = ref.value;\n  var parent = ref.parent;\n\n  this.value = value;\n  this.dep = new Dep();\n  this.vmCount = 0;\n  this.vm = vm;\n  this.op = new ObserverPath(key, this, parent && parent.__ob__ && parent.__ob__.op);\n\n  def(value, '__ob__', this);\n  if (Array.isArray(value)) {\n    var augment = hasProto ? protoAugment : copyAugment;\n    augment(value, arrayMethods, arrayKeys);\n    this.observeArray(key, value);\n  } else {\n    this.walk(key, value);\n  }\n};\n\n/**\n * Walk through each property and convert them into\n * getter/setters. This method should only be called when\n * value type is Object.\n */\nObserver.prototype.walk = function walk (key, obj) {\n  var keys = Object.keys(obj);\n  for (var i = 0; i < keys.length; i++) {\n    defineReactive({ vm: this.vm, obj: obj, key: keys[i], value: obj[keys[i]], parent: obj });\n    //defineReactive(this.vm, obj, keys[i], obj[keys[i]]);\n  }\n};\n\n/**\n * Observe a list of Array items.\n */\nObserver.prototype.observeArray = function observeArray (key, items) {\n  for (var i = 0, l = items.length; i < l; i++) {\n    observe({ vm: this.vm, key: i, value: items[i], parent: items });\n  }\n};\n\n/**\n * Check if path exsit in vm\n */\nObserver.prototype.hasPath = function hasPath (path) {\n  var value = this.vm;\n  var key = '';\n  var i = 0;\n  while (i < path.length) {\n    if (path[i] !== '.' && path[i] !== '[' && path[i] !== ']') {\n      key += path[i];\n    } else if (key.length !== 0) {\n      value = value[key];\n      key = '';\n      if (!isObject(value)) {\n        return false;\n      }\n    }\n    i++;\n  }\n  return true;\n};\n\n/**\n * Is this path value equal\n */\nObserver.prototype.isPathEq = function isPathEq (path, value) {\n  var objValue = this.vm;\n  var key = '';\n  var i = 0;\n  while (i < path.length) {\n    if (path[i] !== '.' && path[i] !== '[' && path[i] !== ']') {\n      key += path[i];\n    } else if (key.length !== 0) {\n      objValue = objValue[key];\n      key = '';\n      if (!isObject(objValue)) {\n        return false;\n      }\n    }\n    i++;\n  }\n  if (key.length !== 0) {\n    objValue = objValue[key];\n  }\n  return value === objValue;\n};\n\n// helpers\n\n/**\n * Augment an target Object or Array by intercepting\n * the prototype chain using __proto__\n */\nfunction protoAugment(target, src) {\n  /* eslint-disable no-proto */\n  target.__proto__ = src;\n  /* eslint-enable no-proto */\n}\n\n/**\n * Augment an target Object or Array by defining\n * hidden properties.\n */\n/* istanbul ignore next */\nfunction copyAugment(target, src, keys) {\n  for (var i = 0, l = keys.length; i < l; i++) {\n    var key = keys[i];\n    def(target, key, src[key]);\n  }\n}\n\n/**\n * Attempt to create an observer instance for a value,\n * returns the new observer if successfully observed,\n * or the existing observer if the value already has one.\n */\nfunction observe(ref) {\n  var vm = ref.vm;\n  var key = ref.key;\n  var value = ref.value;\n  var parent = ref.parent;\n  var root = ref.root;\n\n  if (!isObject(value)) {\n    return;\n  }\n  var ob;\n  if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {\n    ob = value.__ob__;\n    var op = ob.op;\n    addPaths(key, op, parent.__ob__.op);\n  } else if (\n    observerState.shouldConvert &&\n    (Array.isArray(value) || isPlainObject(value)) &&\n    Object.isExtensible(value) &&\n    !value._isVue\n  ) {\n    ob = new Observer({ vm: vm, key: key, value: value, parent: parent });\n  }\n  if (root && ob) {\n    ob.vmCount++;\n  }\n  return ob;\n}\n\n/**\n * Define a reactive property on an Object.\n */\nfunction defineReactive(ref) {\n  var vm = ref.vm;\n  var obj = ref.obj;\n  var key = ref.key;\n  var value = ref.value;\n  var parent = ref.parent;\n  var customSetter = ref.customSetter;\n  var shallow = ref.shallow;\n\n  var dep = new Dep();\n\n  var property = Object.getOwnPropertyDescriptor(obj, key);\n  if (property && property.configurable === false) {\n    return;\n  }\n\n  // cater for pre-defined getter/setters\n  var getter = property && property.get;\n  if (!getter && arguments.length === 2) {\n    value = obj[key];\n  }\n  var setter = property && property.set;\n\n  var childOb = !shallow && observe({ vm: vm, key: key, value: value, parent: obj });\n  Object.defineProperty(obj, key, {\n    enumerable: true,\n    configurable: true,\n    get: function reactiveGetter() {\n      var val = getter ? getter.call(obj) : value;\n      if (Dep.target) {\n        dep.depend();\n        if (childOb) {\n          childOb.dep.depend();\n          if (Array.isArray(val)) {\n            dependArray(val);\n          }\n        }\n      }\n      return val;\n    },\n    set: function reactiveSetter(newVal) {\n      var val = getter ? getter.call(obj) : value;\n      /* eslint-disable no-self-compare */\n      if (newVal === val || (newVal !== newVal && val !== val)) {\n        return;\n      }\n\n      if (isObject(value) && hasOwn(value, '__ob__')) {\n        /**\n         * 删掉无效的 paths\n         * 注意：即使 path 只有一个也要删掉，因为其子节点可能有多个 path\n         */\n        cleanPaths(key, value.__ob__.op, parent.__ob__.op);\n      }\n\n      /* eslint-enable no-self-compare */\n      if (\"development\" !== 'production' && customSetter) {\n        customSetter();\n      }\n      if (setter) {\n        setter.call(obj, newVal);\n      } else {\n        value = newVal;\n      }\n\n      // Have to set dirty after value assigned, otherwise the dirty key is incrrect.\n      if (vm) {\n        // push parent key to dirty, wait to setData\n        if (vm.$dirty) {\n          vm.$dirty.set(obj.__ob__.op, key, newVal);\n        }\n      }\n      childOb = !shallow && observe({ vm: vm, key: key, value: newVal, parent: parent });\n      dep.notify();\n    }\n  });\n}\n\n/**\n * Set a property on an object. Adds the new property and\n * triggers change notification if the property doesn't\n * already exist.\n */\nfunction set(vm, target, key, val) {\n  if (Array.isArray(target) && isValidArrayIndex(key)) {\n    target.length = Math.max(target.length, key);\n    target.splice(key, 1, val);\n    return val;\n  }\n\n  if (key in target && !(key in Object.prototype)) {\n    target[key] = val;\n    return val;\n  }\n\n  var ob = target.__ob__;\n  if (target._isVue || (ob && ob.vmCount)) {\n    \"development\" !== 'production' &&\n      warn(\n        'Avoid adding reactive properties to a Vue instance or its root $data ' +\n          'at runtime - declare it upfront in the data option.'\n      );\n    return val;\n  }\n\n  if (!ob) {\n    target[key] = val;\n    return val;\n  }\n\n  if (isObject(target[key]) && hasOwn(target[key], '__ob__')) {\n    // delete invalid paths\n    cleanPaths(key, target[key].__ob__.op, ob.op);\n  }\n  defineReactive({ vm: vm, obj: ob.value, key: key, value: val, parent: ob.value });\n  if (vm) {\n    // push parent key to dirty, wait to setData\n    if (vm.$dirty && hasOwn(target, '__ob__')) {\n      vm.$dirty.set(target.__ob__.op, key, val);\n    }\n  }\n  ob.dep.notify();\n  return val;\n}\n\n/**\n * Delete a property and trigger change if necessary.\n */\nfunction del(target, key) {\n  if (Array.isArray(target) && isValidArrayIndex(key)) {\n    target.splice(key, 1);\n    return;\n  }\n\n  var ob = target.__ob__;\n  if (target._isVue || (ob && ob.vmCount)) {\n    \"development\" !== 'production' &&\n      warn('Avoid deleting properties on a Vue instance or its root $data ' + '- just set it to null.');\n    return;\n  }\n\n  if (!hasOwn(target, key)) {\n    return;\n  }\n\n  // set $dirty\n  target[key] = null;\n  delete target[key];\n  if (!ob) {\n    return;\n  }\n  ob.dep.notify();\n}\n\n/**\n * Collect dependencies on array elements when the array is touched, since\n * we cannot intercept array element access like property getters.\n */\nfunction dependArray(value) {\n  for (var e = (void 0), i = 0, l = value.length; i < l; i++) {\n    e = value[i];\n    e && e.__ob__ && e.__ob__.dep.depend();\n    if (Array.isArray(e)) {\n      dependArray(e);\n    }\n  }\n}\n\nvar Base = function Base() {\n  this._events = {};\n  this._watchers = [];\n};\n\nBase.prototype.$set = function $set (target, key, val) {\n  return set(this, target, key, val);\n};\n\nBase.prototype.$delete = function $delete (target, key) {\n  return del(target, key);\n};\n\nBase.prototype.$on = function $on (event, fn) {\n    var this$1 = this;\n\n  if (isArr(event)) {\n    event.forEach(function (item) {\n      if (isStr(item)) {\n        this$1.$on(item, fn);\n      } else if (isObj(item)) {\n        this$1.$on(item.event, item.fn);\n      }\n    });\n  } else {\n    (this._events[event] || (this._events[event] = [])).push(fn);\n  }\n  return this;\n};\n\nBase.prototype.$once = function $once () {};\n\nBase.prototype.$off = function $off (event, fn) {\n    var this$1 = this;\n\n  if (!event && !fn) {\n    this._events = Object.create(null);\n    return this;\n  }\n\n  if (isArr(event)) {\n    event.forEach(function (item) {\n      if (isStr(item)) {\n        this$1.$off(item, fn);\n      } else if (isObj(item)) {\n        this$1.$off(item.event, item.fn);\n      }\n    });\n    return this;\n  }\n  if (!this._events[event]) { return this; }\n\n  if (!fn) {\n    this._events[event] = null;\n    return this;\n  }\n\n  if (fn) {\n    var fns = this._events[event];\n    var i = fns.length;\n    while (i--) {\n      var tmp = fns[i];\n      if (tmp === fn || tmp.fn === fn) {\n        fns.splice(i, 1);\n        break;\n      }\n    }\n  }\n  return this;\n};\n\nBase.prototype.$emit = function $emit (event) {\n    var this$1 = this;\n\n  var vm = this;\n  var lowerCaseEvent = event.toLowerCase();\n  var fns = this._events[event] || [];\n  if (lowerCaseEvent !== event && vm._events[lowerCaseEvent]) {\n    // TODO: handler warn\n  }\n  var args = toArray(arguments, 1);\n  fns.forEach(function (fn) {\n    try {\n      fn.apply(this$1, args);\n    } catch (e) {\n      handleError(e, vm, (\"event handler for \\\"\" + event + \"\\\"\"));\n    }\n  });\n  return this;\n};\n\nvar seenObjects = new _Set();\n\n/**\n * Recursively traverse an object to evoke all converted\n * getters, so that every nested property inside the object\n * is collected as a \"deep\" dependency.\n */\nfunction traverse(val) {\n  _traverse(val, seenObjects);\n  seenObjects.clear();\n}\n\nfunction _traverse(val, seen) {\n  var i, keys;\n  var isA = Array.isArray(val);\n  if ((!isA && !isObject(val)) || Object.isFrozen(val)) {\n    return;\n  }\n  if (val.__ob__) {\n    var depId = val.__ob__.dep.id;\n    if (seen.has(depId)) {\n      return;\n    }\n    seen.add(depId);\n  }\n  if (isA) {\n    i = val.length;\n    while (i--) { _traverse(val[i], seen); }\n  } else {\n    keys = Object.keys(val);\n    i = keys.length;\n    while (i--) { _traverse(val[keys[i]], seen); }\n  }\n}\n\n//import { callHook, activateChildComponent } from '../instance/lifecycle';\n\nvar MAX_UPDATE_COUNT = 100;\n\nvar queue = [];\nvar activatedChildren = [];\nvar has = {};\nvar circular = {};\nvar waiting = false;\nvar flushing = false;\nvar index = 0;\n\n/**\n * Reset the scheduler's state.\n */\nfunction resetSchedulerState() {\n  index = queue.length = activatedChildren.length = 0;\n  has = {};\n  {\n    circular = {};\n  }\n  waiting = flushing = false;\n}\n\n/**\n * Flush both queues and run the watchers.\n */\nfunction flushSchedulerQueue(times) {\n  if ( times === void 0 ) times = 0;\n\n  flushing = true;\n  var watcher, id;\n\n  // Sort queue before flush.\n  // This ensures that:\n  // 1. Components are updated from parent to child. (because parent is always\n  //    created before the child)\n  // 2. A component's user watchers are run before its render watcher (because\n  //    user watchers are created before the render watcher)\n  // 3. If a component is destroyed during a parent component's watcher run,\n  //    its watchers can be skipped.\n  times === 0 && queue.sort(function (a, b) { return a.id - b.id; });\n\n  // do not cache length because more watchers might be pushed\n  // as we run existing watchers\n  // there would be mutilple renderWatcher in the queue.\n  var renderWatcher = [];\n  if (times === 0) {\n    index = 0;\n  }\n  for (; index < queue.length; index++) {\n    // if it's renderWatcher, run it in the end\n    watcher = queue[index];\n    if (watcher && watcher.isRenderWatcher) {\n      renderWatcher.push(watcher);\n      continue;\n    }\n    id = watcher.id;\n    has[id] = null;\n    watcher.run();\n    // in dev build, check and stop circular updates.\n    // eslint-disable-next-line\n    if (\"development\" !== 'production' && has[id] != null) {\n      circular[id] = (circular[id] || 0) + 1;\n      if (circular[id] > MAX_UPDATE_COUNT) {\n        warn(\n          'You may have an infinite update loop ' +\n            (watcher.user ? (\"in watcher with expression \\\"\" + (watcher.expression) + \"\\\"\") : \"in a component render function.\"),\n          watcher.vm\n        );\n        resetSchedulerState();\n        return;\n      }\n    }\n  }\n  // Run renderWatcher in the end.\n  if (renderWatcher.length) {\n    renderWatcher.forEach(function (watcher) {\n      has[watcher.id] = null;\n      watcher.run();\n    });\n  }\n\n  // It may added new watcher to the queue in render watcher\n  var pendingQueue = queue.slice(index);\n\n  if (pendingQueue.length) {\n    flushSchedulerQueue(times + 1);\n  } else {\n    // keep copies of post queues before resetting state\n    // const activatedQueue = activatedChildren.slice()\n    // const updatedQueue = queue.slice()\n\n    resetSchedulerState();\n\n    // call component updated and activated hooks\n    // callActivatedHooks(activatedQueue)\n    // callUpdatedHooks(updatedQueue)\n\n    // devtool hook\n    /* istanbul ignore if */\n    /*\n    if (devtools && config.devtools) {\n      devtools.emit('flush')\n    }*/\n  }\n}\n\n/*\nfunction callActivatedHooks(queue) {\n  for (let i = 0; i < queue.length; i++) {\n    queue[i]._inactive = true;\n    activateChildComponent(queue[i], true);\n  }\n}\n*/\n\n/**\n * Push a watcher into the watcher queue.\n * Jobs with duplicate IDs will be skipped unless it's\n * pushed when the queue is being flushed.\n */\nfunction queueWatcher(watcher) {\n  var id = watcher.id;\n  // eslint-disable-next-line\n  if (has[id] == null) {\n    has[id] = true;\n    if (!flushing) {\n      queue.push(watcher);\n    } else {\n      // if already flushing, splice the watcher based on its id\n      // if already past its id, it will be run next immediately.\n      var i = queue.length - 1;\n      while (i > index && queue[i].id > watcher.id) {\n        i--;\n      }\n      queue.splice(i + 1, 0, watcher);\n    }\n    // queue the flush\n    if (!waiting) {\n      waiting = true;\n      nextTick(flushSchedulerQueue);\n    }\n  }\n}\n\n//import { SimpleSet } from '../util/index';\n\nvar uid$1 = 0;\n\n/**\n * A watcher parses an expression, collects dependencies,\n * and fires callback when the expression value changes.\n * This is used for both the $watch() api and directives.\n */\nvar Watcher = function Watcher(vm, expOrFn, cb, options, isRenderWatcher) {\n  this.vm = vm;\n  if (isRenderWatcher) {\n    vm._watcher = this;\n  }\n  vm._watchers.push(this);\n  // options\n  if (options) {\n    this.deep = !!options.deep;\n    this.user = !!options.user;\n    this.computed = !!options.computed;\n    this.sync = !!options.sync;\n  } else {\n    this.deep = this.user = this.computed = this.sync = false;\n  }\n  this.cb = cb;\n  this.id = ++uid$1; // uid for batching\n  this.active = true;\n  this.dirty = this.computed; // for computed watchers\n  this.deps = [];\n  this.newDeps = [];\n  this.depIds = new _Set();\n  this.newDepIds = new _Set();\n  this.isRenderWatcher = isRenderWatcher;\n  this.expression = expOrFn.toString();\n  // parse expression for getter\n  if (typeof expOrFn === 'function') {\n    this.getter = expOrFn;\n  } else {\n    this.getter = parsePath(expOrFn);\n    if (!this.getter) {\n      this.getter = function() {};\n      \"development\" !== 'production' &&\n        warn(\n          \"Failed watching path: \\\"\" + expOrFn + \"\\\" \" +\n            'Watcher only accepts simple dot-delimited paths. ' +\n            'For full control, use a function instead.',\n          vm\n        );\n    }\n  }\n  this.value = this.computed ? undefined : this.get();\n};\n\n/**\n * Evaluate the getter, and re-collect dependencies.\n */\nWatcher.prototype.get = function get () {\n  pushTarget(this);\n  var value;\n  var vm = this.vm;\n  try {\n    value = this.getter.call(vm, vm);\n  } catch (e) {\n    if (this.user) {\n      handleError(e, vm, (\"getter for watcher \\\"\" + (this.expression) + \"\\\"\"));\n    } else {\n      throw e;\n    }\n  } finally {\n    // \"touch\" every property so they are all tracked as\n    // dependencies for deep watching\n    if (this.deep) {\n      traverse(value);\n    }\n    popTarget();\n    if (!this.isRenderWatcher) { this.cleanupDeps(); }\n  }\n  return value;\n};\n\n/**\n * Add a dependency to this directive.\n */\nWatcher.prototype.addDep = function addDep (dep) {\n  var id = dep.id;\n  if (!this.newDepIds.has(id)) {\n    this.newDepIds.add(id);\n    this.newDeps.push(dep);\n    if (!this.depIds.has(id)) {\n      dep.addSub(this);\n    }\n  }\n};\n\n/**\n * Clean up for dependency collection.\n */\nWatcher.prototype.cleanupDeps = function cleanupDeps () {\n  var i = this.deps.length;\n  while (i--) {\n    var dep = this.deps[i];\n    if (!this.newDepIds.has(dep.id)) {\n      dep.removeSub(this);\n    }\n  }\n  var tmp = this.depIds;\n  this.depIds = this.newDepIds;\n  this.newDepIds = tmp;\n  this.newDepIds.clear();\n  tmp = this.deps;\n  this.deps = this.newDeps;\n  this.newDeps = tmp;\n  this.newDeps.length = 0;\n};\n\n/**\n * Subscriber interface.\n * Will be called when a dependency changes.\n */\nWatcher.prototype.update = function update () {\n  /* istanbul ignore else */\n  if (this.computed) {\n    this.dirty = true;\n  } else if (this.sync) {\n    this.run();\n  } else {\n    queueWatcher(this);\n  }\n};\n\n/**\n * Scheduler job interface.\n * Will be called by the scheduler.\n */\nWatcher.prototype.run = function run () {\n  if (this.active) {\n    var value = this.get();\n    if (\n      value !== this.value ||\n      // Deep watchers and watchers on Object/Arrays should fire even\n      // when the value is the same, because the value may\n      // have mutated.\n      isObject(value) ||\n      this.deep\n    ) {\n      // set new value\n      var oldValue = this.value;\n      this.value = value;\n      if (this.user) {\n        try {\n          this.cb.call(this.vm, value, oldValue);\n        } catch (e) {\n          handleError(e, this.vm, (\"callback for watcher \\\"\" + (this.expression) + \"\\\"\"));\n        }\n      } else {\n        this.cb.call(this.vm, value, oldValue);\n      }\n    }\n  }\n};\n\n/**\n * Evaluate the value of the watcher.\n * This only gets called for computed watchers.\n */\nWatcher.prototype.evaluate = function evaluate () {\n  this.value = this.get();\n  if (this.vm.$dirty) {\n    var keyVal =\n      this._computedWatchers && this._computedWatchers[this.key]\n        ? this.vm._computedWatchers[this.key].value\n        : this.value;\n    this.vm.$dirty.push(this.key, this.key, keyVal, this.value);\n  }\n  this.dirty = false;\n  return this.value;\n};\n\n/**\n * Depend on all deps collected by this watcher.\n */\nWatcher.prototype.depend = function depend () {\n  if (Dep.target) {\n    var i = this.deps.length;\n    while (i--) {\n      this.deps[i].depend();\n    }\n  }\n};\n\n/**\n * Remove self from all dependencies' subscriber list.\n */\nWatcher.prototype.teardown = function teardown () {\n  if (this.active) {\n    // remove self from vm's watcher list\n    // this is a somewhat expensive operation so we skip it\n    // if the vm is being destroyed.\n    if (!this.vm._isBeingDestroyed) {\n      remove(this.vm._watchers, this);\n    }\n    var i = this.deps.length;\n    while (i--) {\n      this.deps[i].removeSub(this);\n    }\n    this.active = false;\n  }\n};\n\nvar WepyComponent = /*@__PURE__*/(function (Base$$1) {\n  function WepyComponent () {\n    Base$$1.apply(this, arguments);\n  }\n\n  if ( Base$$1 ) WepyComponent.__proto__ = Base$$1;\n  WepyComponent.prototype = Object.create( Base$$1 && Base$$1.prototype );\n  WepyComponent.prototype.constructor = WepyComponent;\n\n  WepyComponent.prototype.$watch = function $watch (expOrFn, cb, options) {\n    var this$1 = this;\n\n    var vm = this;\n    if (isArr(cb)) {\n      cb.forEach(function (handler) {\n        this$1.$watch(expOrFn, handler, options);\n      });\n    }\n    if (isPlainObject(cb)) {\n      var handler = cb;\n      options = handler;\n      handler = handler.handler;\n      if (typeof handler === 'string') { handler = this[handler]; }\n      return this.$watch(expOrFn, handler, options);\n    }\n\n    options = options || {};\n    options.user = true;\n    var watcher = new Watcher(vm, expOrFn, cb, options);\n    if (options.immediate) {\n      cb.call(vm, watcher.value);\n    }\n    return function unwatchFn() {\n      watcher.teardown();\n    };\n  };\n\n  WepyComponent.prototype.$forceUpdate = function $forceUpdate () {\n    if (this._watcher) {\n      this._watcher.update();\n    }\n  };\n\n  WepyComponent.prototype.$emit = function $emit (event) {\n    var args = [], len = arguments.length - 1;\n    while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];\n\n    var fns = this._events[event];\n\n    if (fns) {\n      Base$$1.prototype.$emit.apply(this, arguments);\n    } else {\n      this.$wx.triggerEvent(event, { arguments: args });\n    }\n\n    return this;\n  };\n\n  WepyComponent.prototype.$trigger = function $trigger (event, data, option) {\n    this.$wx.triggerEvent(event, { arguments: [data] }, option);\n  };\n\n  return WepyComponent;\n}(Base));\n\nWepyComponent.prototype.$nextTick = renderNextTick;\n\nvar sharedPropertyDefinition = {\n  enumerable: true,\n  configurable: true,\n  get: noop,\n  set: noop\n};\n\nfunction proxy(target, sourceKey, key) {\n  sharedPropertyDefinition.get = function proxyGetter() {\n    return this[sourceKey][key];\n  };\n  sharedPropertyDefinition.set = function proxySetter(val) {\n    this[sourceKey][key] = val;\n  };\n  Object.defineProperty(target, key, sharedPropertyDefinition);\n}\n\n/*\n * patch data option\n */\nfunction patchData(output, data) {\n  if (!data) {\n    data = {};\n  }\n  output.data = data;\n}\n\n/*\n * init data\n */\nfunction initData(vm, data) {\n  if (!data) {\n    data = {};\n  }\n  var _data;\n  if (typeof data === 'function') {\n    _data = data.call(vm);\n  } else {\n    _data = clone(data);\n  }\n  vm._data = _data;\n  Object.keys(_data).forEach(function (key) {\n    proxy(vm, '_data', key);\n  });\n\n  observe({\n    vm: vm,\n    key: '',\n    value: _data,\n    parent: '',\n    root: true\n  });\n  //observe(vm, _data, null, true);\n}\n\nfunction initWatch(vm, watch) {\n  if (watch) {\n    Object.keys(watch).forEach(function (key) {\n      vm.$watch(key, watch[key]);\n    });\n  }\n}\n\nfunction createComputedGetter(key) {\n  return function computedGetter() {\n    var watcher = this._computedWatchers && this._computedWatchers[key];\n    if (watcher) {\n      watcher.key = key;\n      if (watcher.dirty) {\n        watcher.evaluate();\n      }\n      if (Dep.target) {\n        watcher.depend();\n      }\n      return watcher.value;\n    }\n  };\n}\n\n/*\n * init computed\n */\nfunction initComputed(vm, computed) {\n  if (!computed) {\n    return;\n  }\n  var watchers = (vm._computedWatchers = Object.create(null));\n  var computedWatcherOptions = { computed: true };\n\n  Object.keys(computed).forEach(function (key) {\n    var def = computed[key];\n    var getter = typeof def === 'object' ? def.get : def;\n\n    if (!getter || typeof getter !== 'function') {\n      // eslint-disable-next-line\n      console.error((\"Getter is missing for computed property \\\"\" + key + \"\\\"\"));\n    }\n\n    // push to dirty after dep called.\n    watchers[key] = new Watcher(\n      vm,\n      getter || function() {},\n      function() {\n        // evaluate will set dirty\n        // vm.$dirty.push(key, key, newv);\n      },\n      computedWatcherOptions\n    );\n\n    if (typeof def === 'function') {\n      sharedPropertyDefinition.get = createComputedGetter(key);\n      sharedPropertyDefinition.set = function() {};\n    } else {\n      sharedPropertyDefinition.get = def.cache !== false ? createComputedGetter(key) : def.get;\n      sharedPropertyDefinition.set = def.set;\n    }\n\n    Object.defineProperty(vm, key, sharedPropertyDefinition);\n  });\n}\n\nvar WepyConstructor = /*@__PURE__*/(function (WepyComponent$$1) {\n  function WepyConstructor(opt) {\n    if ( opt === void 0 ) opt = {};\n\n    WepyComponent$$1.call(this);\n    var vm = new WepyComponent$$1();\n\n    // Only need data and watchers for a empty WepyComponent\n    if (opt.data) {\n      initData(vm, opt.data);\n    }\n    initWatch(vm);\n\n    initComputed(vm, opt.computed);\n    return vm;\n  }\n\n  if ( WepyComponent$$1 ) WepyConstructor.__proto__ = WepyComponent$$1;\n  WepyConstructor.prototype = Object.create( WepyComponent$$1 && WepyComponent$$1.prototype );\n  WepyConstructor.prototype.constructor = WepyConstructor;\n\n  return WepyConstructor;\n}(WepyComponent));\n\nvar $global = Object.create(null);\n\nfunction use(plugin) {\n  var args = [], len = arguments.length - 1;\n  while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];\n\n  if (plugin.installed) {\n    return this;\n  }\n\n  var install = plugin.install || plugin;\n\n  if (isFunc(install)) {\n    install.apply(plugin, [this].concat(args));\n  }\n\n  plugin.installed = 1;\n}\n\nfunction mixin(options) {\n  if ( options === void 0 ) options = {};\n\n  $global.mixin = ($global.mixin || []).concat(options);\n}\n\nvar WepyApp = /*@__PURE__*/(function (Base$$1) {\n  function WepyApp() {\n    Base$$1.call(this);\n  }\n\n  if ( Base$$1 ) WepyApp.__proto__ = Base$$1;\n  WepyApp.prototype = Object.create( Base$$1 && Base$$1.prototype );\n  WepyApp.prototype.constructor = WepyApp;\n\n  return WepyApp;\n}(Base));\n\nvar WepyPage = /*@__PURE__*/(function (WepyComponent$$1) {\n  function WepyPage () {\n    WepyComponent$$1.apply(this, arguments);\n  }\n\n  if ( WepyComponent$$1 ) WepyPage.__proto__ = WepyComponent$$1;\n  WepyPage.prototype = Object.create( WepyComponent$$1 && WepyComponent$$1.prototype );\n  WepyPage.prototype.constructor = WepyPage;\n\n  WepyPage.prototype.$launch = function $launch (url, params) {\n    this.$route('reLaunch', url, params);\n  };\n  WepyPage.prototype.$navigate = function $navigate (url, params) {\n    this.$route('navigate', url, params);\n  };\n\n  WepyPage.prototype.$redirect = function $redirect (url, params) {\n    this.$route('redirect', url, params);\n  };\n\n  WepyPage.prototype.$back = function $back (p) {\n    if ( p === void 0 ) p = {};\n\n    if (isNum(p)) { p = { delta: p }; }\n\n    if (!p.delta) { p.delta = 1; }\n\n    return wx.navigateBack(p);\n  };\n\n  WepyPage.prototype.$route = function $route (type, url, params) {\n    if ( params === void 0 ) params = {};\n\n    var wxparams;\n    if (isStr(url)) {\n      var paramsList = [];\n      if (isObj(params)) {\n        for (var k in params) {\n          if (!isUndef(params[k])) {\n            paramsList.push((k + \"=\" + (encodeURIComponent(params[k]))));\n          }\n        }\n      }\n      if (paramsList.length) { url = url + '?' + paramsList.join('&'); }\n\n      wxparams = { url: url };\n    } else {\n      wxparams = url;\n    }\n    var fn = wx[type] || wx[type + 'To'];\n    if (isFunc(fn)) {\n      return fn(wxparams);\n    }\n  };\n\n  return WepyPage;\n}(WepyComponent));\n\nfunction callUserHook(vm, hookName, arg) {\n  var pageHook = vm.hooks ? vm.hooks[hookName] : null;\n  var appHook = vm.$app && vm.$app.hooks ? vm.$app.hooks[hookName] : null;\n\n  if (!vm.$app) {\n    warn('$app is not initialized in this Component', vm);\n  }\n\n  var result = arg;\n\n  // First run page hook, and then run app hook\n  // Pass page hook result to app hook\n  // If return undefined, then return default argument\n  [pageHook, appHook].forEach(function (fn) {\n    if (isFunc(fn)) {\n      result = fn.call(vm, result);\n      if (isUndef(result)) {\n        result = arg;\n      }\n    }\n  });\n\n  return result;\n}\n\nfunction initHooks(vm, hooks) {\n  if ( hooks === void 0 ) hooks = {};\n\n  vm.hooks = hooks;\n}\n\nvar AllowedTypes = [String, Number, Boolean, Object, Array, null];\n\nvar observerFn = function() {\n  return function(newVal, oldVal, changedPaths) {\n    var vm = this.$wepy;\n\n    // changedPaths 长度大于 1，说明是由内部赋值改变的 prop\n    if (changedPaths.length > 1) {\n      return;\n    }\n    var _data = newVal;\n    if (typeof _data === 'function') {\n      _data = _data.call(vm);\n    }\n    vm[changedPaths[0]] = _data;\n  };\n};\n/*\n * patch props option\n */\nfunction patchProps(output, props) {\n  var newProps = {};\n  if (isStr(props)) {\n    newProps = [props];\n  }\n  if (isArr(props)) {\n    props.forEach(function (prop) {\n      newProps[prop] = {\n        type: null,\n        observer: observerFn(output, props, prop)\n      };\n    });\n  } else if (isObj(props)) {\n    for (var k in props) {\n      var prop = props[k];\n      var newProp = {};\n\n      // props.type\n      if (isUndef(prop.type)) {\n        newProp.type = null;\n      } else if (isArr(prop.type)) {\n        newProp.type = null;\n        // eslint-disable-next-line\n        console.warn((\"In mini-app, mutiple type is not allowed. The type of \\\"\" + k + \"\\\" will changed to \\\"null\\\"\"));\n      } else if (AllowedTypes.indexOf(prop.type) === -1) {\n        newProp.type = null;\n        // eslint-disable-next-line\n        console.warn(\n          (\"Type property of props \\\"\" + k + \"\\\" is invalid. Only String/Number/Boolean/Object/Array/null is allowed in weapp Component\")\n        );\n      } else {\n        newProp.type = prop.type;\n      }\n\n      // props.default\n      if (!isUndef(prop.default)) {\n        if (isFunc(prop.default)) {\n          newProp.value = prop.default.call(output);\n        } else {\n          newProp.value = prop.default;\n        }\n      }\n      // TODO\n      // props.validator\n      // props.required\n\n      newProp.observer = observerFn(output, props, prop);\n\n      newProps[k] = newProp;\n    }\n  }\n\n  // eslint-disable-next-line\n  Object.keys(newProps).forEach(function (prop) {});\n\n  output.properties = newProps;\n}\n\n/*\n * init props\n */\nfunction initProps(vm, properties) {\n  vm._props = {};\n\n  if (!properties) {\n    return;\n  }\n\n  Object.keys(properties).forEach(function (key) {\n    vm._props[key] = properties[key].value;\n    proxy(vm, '_props', key);\n  });\n\n  observe({\n    vm: vm,\n    key: '',\n    value: vm._props,\n    root: true\n  });\n}\n\nfunction initRender(vm, keys, computedKeys) {\n  vm._init = false;\n  var dirtyFromAttach = null;\n  return new Watcher(\n    vm,\n    function() {\n      if (!vm._init) {\n        keys.forEach(function (key) { return clone(vm[key]); });\n      }\n\n      if (vm.$dirty.length() || dirtyFromAttach) {\n        var keys$1 = vm.$dirty.get('key');\n        computedKeys.forEach(function (key) { return vm[key]; });\n        var dirty = vm.$dirty.pop();\n\n        // TODO: reset subs\n        Object.keys(keys$1).forEach(function (key) { return clone(vm[key]); });\n\n        if (vm._init) {\n          dirty = callUserHook(vm, 'before-setData', dirty);\n        }\n\n        // vm._fromSelf = true;\n        if (dirty || dirtyFromAttach) {\n          // init render is in lifecycle, setData in lifecycle will not work, so cacheData is needed.\n          if (!vm._init) {\n            if (dirtyFromAttach === null) {\n              dirtyFromAttach = {};\n            }\n            Object.assign(dirtyFromAttach, dirty);\n          } else if (dirtyFromAttach) {\n            // setData in attached\n            vm.$wx.setData(Object.assign(dirtyFromAttach, dirty || {}), renderFlushCallbacks);\n            dirtyFromAttach = null;\n          } else {\n            vm.$wx.setData(dirty, renderFlushCallbacks);\n          }\n        }\n      }\n      vm._init = true;\n    },\n    function() {},\n    null,\n    true\n  );\n}\n\nvar Event = function Event(e) {\n  var detail = e.detail;\n  var target = e.target;\n  var currentTarget = e.currentTarget;\n  this.$wx = e;\n  this.type = e.type;\n  this.timeStamp = e.timeStamp;\n  if (detail) {\n    this.x = detail.x;\n    this.y = detail.y;\n  }\n\n  this.target = target;\n  this.currentTarget = currentTarget;\n  this.touches = e.touches;\n  this.changedTouches = e.changedTouches;\n};\n\n/**\n * Transform wxml data-xx params to an array\n */\nfunction transformParams(dataset, type, hasModel) {\n  if ( hasModel === void 0 ) hasModel = false;\n\n  var i = 0;\n  var params = [];\n  var modelParams = [];\n\n  var noParams = false;\n  var noModelParams = !hasModel;\n\n  var camelizedType = camelize(type);\n  while (i++ < 26 && (!noParams || !noModelParams)) {\n    var alpha = String.fromCharCode(64 + i);\n    if (!noParams) {\n      var key = 'wpy' + camelizedType + alpha;\n      if (!(key in dataset)) {\n        // it can be undefined;\n        noParams = true;\n      } else {\n        params.push(dataset[key]);\n      }\n    }\n    if (!noModelParams && hasModel) {\n      var modelKey = 'model' + alpha;\n      if (!(modelKey in dataset)) {\n        noModelParams = true;\n      } else {\n        modelParams.push(dataset[modelKey]);\n      }\n    }\n  }\n\n  return {\n    handler: params,\n    model: modelParams\n  };\n}\n\nvar dispatcher = function(e) {\n  var vm = this.$wepy;\n  var type = e.type;\n  // touchstart do not have currentTarget\n  var dataset = (e.currentTarget || e.target).dataset || {};\n  var evtid = dataset.wpyEvt;\n  var modelId = dataset.modelId;\n  var rel = vm.$rel || {};\n  var handler = rel.handlers && rel.handlers[evtid] && rel.handlers[evtid][type];\n  var model = rel.models && rel.models[modelId];\n\n  if (!handler && !model) {\n    return;\n  }\n\n  var params = transformParams(dataset, type, !!model);\n\n  // Call model method\n  if (model && type === model.type && isFunc(model.handler)) {\n    model.handler.call(vm, e.detail.value, params.model);\n  }\n\n  // Call handler method\n  if (isFunc(handler)) {\n    var $event = new Event(e);\n    var paramsWithEvent = params.handler.concat($event);\n    var args = (e.detail && e.detail.arguments) || [];\n\n    var hookRes = callUserHook(vm, 'before-event', {\n      event: $event,\n      params: paramsWithEvent,\n      args: args\n    });\n\n    if (hookRes === false) {\n      // Event cancelled.\n      return;\n    }\n    return handler.apply(vm, paramsWithEvent);\n  } else if (!model) {\n    throw new Error('Unrecognized event');\n  }\n};\n\n/*\n * initialize page methods, also the app\n */\nfunction initMethods(vm, methods) {\n  if (methods) {\n    Object.keys(methods).forEach(function (method) {\n      vm[method] = methods[method];\n    });\n  }\n}\n\n/*\n * patch method option\n */\nfunction patchMethods(output, methods) {\n  output.methods = {};\n  var target = output.methods;\n\n  target.__initComponent = function(e) {\n    var child = e.detail;\n    var ref$1 = e.target.dataset;\n    var ref = ref$1.ref;\n    var wpyEvt = ref$1.wpyEvt;\n    var vm = this.$wepy;\n    vm.$children.push(child);\n    if (ref) {\n      if (vm.$refs[ref]) {\n        warn('duplicate ref \"' + ref + '\" will be covered by the last instance.\\n', vm);\n      }\n      vm.$refs[ref] = child;\n    }\n    child.$evtId = wpyEvt;\n    child.$parent = vm;\n    child.$app = vm.$app;\n    child.$root = vm.$root;\n    return vm;\n  };\n  target.__dispatcher = dispatcher;\n\n  // TODO: perf\n  // Only orginal component method goes to target. no need to add all methods.\n  if (methods) {\n    Object.keys(methods).forEach(function (method) {\n      target[method] = methods[method];\n    });\n  }\n}\n\nvar Dirty = function Dirty(type) {\n  this.reset();\n\n  // path||key\n  this.type = type || 'path';\n};\n\nDirty.prototype.push = function push (key, path, keyValue, pathValue) {\n  if (pathValue === undefined) {\n    return;\n  }\n  this._keys[key] = keyValue;\n  this._path[path] = pathValue;\n  this._length++;\n};\n\nDirty.prototype.pop = function pop () {\n  var data = Object.create(null);\n  if (this.type === 'path') {\n    data = this._path;\n  } else if (this.type === 'key') {\n    data = this._keys;\n  }\n  this.reset();\n  return data;\n};\n\nDirty.prototype.get = function get (type) {\n  return type === 'path' ? this._path : this._keys;\n};\n\n/**\n * Set dirty from a ObserverPath\n */\nDirty.prototype.set = function set (op, key, value) {\n  var pathMap;\n  var pathKeys;\n  // eslint-disable-next-line eqeqeq\n  if (key != null) {\n    var ref = getPathMap(key, op.pathKeys, op.pathMap);\n      var combinePathKeys = ref.combinePathKeys;\n      var combinePathMap = ref.combinePathMap;\n    pathKeys = combinePathKeys;\n    pathMap = combinePathMap;\n  } else {\n    pathKeys = op.pathKeys;\n    pathMap = op.pathMap;\n  }\n  /**\n   * 出于性能考虑，使用 usingComponents 时， setData 内容不会被直接深复制，\n   * 即 this.setData({ field: obj }) 后 this.data.field === obj 。\n   * 因此不需要所有 path 都 setData 。\n   */\n  var ref$1 = pathMap[pathKeys[0]];\n    var root = ref$1.root;\n    var path = ref$1.path;\n  this.push(root, path, root === path ? value : op.ob.vm[root], value);\n};\n\nDirty.prototype.reset = function reset () {\n  this._keys = {};\n  this._path = {};\n  this._length = 0;\n  return this;\n};\n\nDirty.prototype.length = function length () {\n  return this._length;\n};\n\nvar comid = 0;\nvar app;\n\nvar callUserMethod = function(vm, userOpt, method, args) {\n  var result;\n  var methods = userOpt[method];\n  if (isFunc(methods)) {\n    result = userOpt[method].apply(vm, args);\n  } else if (isArr(methods)) {\n    for (var i in methods) {\n      if (isFunc(methods[i])) {\n        result = methods[i].apply(vm, args);\n      }\n    }\n  }\n  return result;\n};\n\nvar getLifeCycle = function (defaultLifecycle, rel, type) {\n  var lifecycle = defaultLifecycle.concat([]);\n  if (rel && rel.lifecycle && rel.lifecycle[type]) {\n    var userDefinedLifecycle = [];\n    if (isFunc(rel.lifecycle[type])) {\n      userDefinedLifecycle = rel.lifecycle[type].call(null, lifecycle);\n    }\n    userDefinedLifecycle.forEach(function (u) {\n      if (lifecycle.indexOf(u) > -1) {\n        warn((\"'\" + u + \"' is already implemented in current version, please remove it from your lifecycel config\"));\n      } else {\n        lifecycle.push(u);\n      }\n    });\n  }\n  return lifecycle;\n};\n\n/*\n * patch app lifecyle\n */\nfunction patchAppLifecycle(appConfig, options, rel) {\n  if ( rel === void 0 ) rel = {};\n\n  appConfig.onLaunch = function() {\n    var args = [], len = arguments.length;\n    while ( len-- ) args[ len ] = arguments[ len ];\n\n    var vm = new WepyApp();\n    app = vm;\n    vm.$options = options;\n    vm.$route = {};\n    vm.$rel = rel;\n\n    vm.$wx = this;\n    this.$wepy = vm;\n\n    initHooks(vm, options.hooks);\n\n    initMethods(vm, options.methods);\n\n    return callUserMethod(vm, vm.$options, 'onLaunch', args);\n  };\n\n  var lifecycle = getLifeCycle(WEAPP_APP_LIFECYCLE, rel, 'app');\n\n  lifecycle.forEach(function (k) {\n    // it's not defined aready && user defined it && it's an array or function\n    if (!appConfig[k] && options[k] && (isFunc(options[k]) || isArr(options[k]))) {\n      appConfig[k] = function() {\n        var args = [], len = arguments.length;\n        while ( len-- ) args[ len ] = arguments[ len ];\n\n        return callUserMethod(app, app.$options, k, args);\n      };\n    }\n  });\n}\n\nfunction patchLifecycle(output, options, rel, isComponent) {\n  var initClass = isComponent ? WepyComponent : WepyPage;\n  var initLifecycle = function() {\n    var args = [], len = arguments.length;\n    while ( len-- ) args[ len ] = arguments[ len ];\n\n    var vm = new initClass();\n\n    vm.$dirty = new Dirty('path');\n    vm.$children = [];\n    vm.$refs = {};\n\n    this.$wepy = vm;\n    vm.$wx = this;\n    vm.$is = this.is;\n    vm.$options = options;\n    vm.$rel = rel;\n    vm._watchers = [];\n    if (!isComponent) {\n      vm.$root = vm;\n    }\n    if (app) {\n      vm.$app = app;\n    }\n    if (this.is === 'custom-tab-bar/index') {\n      vm.$app = app;\n      vm.$parent = app;\n    }\n\n    vm.$id = ++comid + (isComponent ? '.1' : '.0');\n\n    callUserMethod(vm, vm.$options, 'beforeCreate', args);\n\n    initHooks(vm, options.hooks);\n\n    initProps(vm, output.properties);\n\n    initData(vm, output.data, isComponent);\n\n    initMethods(vm, options.methods);\n\n    initComputed(vm, options.computed, true);\n\n    initWatch(vm, options.watch);\n\n    // create render watcher\n    initRender(\n      vm,\n      Object.keys(vm._data)\n        .concat(Object.keys(vm._props))\n        .concat(Object.keys(vm._computedWatchers || {})),\n      Object.keys(vm._computedWatchers || {})\n    );\n\n    return callUserMethod(vm, vm.$options, 'created', args);\n  };\n\n  output.created = initLifecycle;\n  if (isComponent) {\n    output.attached = function() {\n      var args = [], len = arguments.length;\n      while ( len-- ) args[ len ] = arguments[ len ];\n\n      // Component attached\n      var outProps = output.properties || {};\n      // this.propperties are includes datas\n      var acceptProps = this.properties;\n      var vm = this.$wepy;\n\n      this.triggerEvent('_init', vm);\n\n      // created 不能调用 setData，如果有 dirty 在此更新\n      vm.$forceUpdate();\n\n      Object.keys(outProps).forEach(function (k) { return (vm[k] = acceptProps[k]); });\n\n      return callUserMethod(vm, vm.$options, 'attached', args);\n    };\n  } else {\n    output.attached = function() {\n      var args = [], len = arguments.length;\n      while ( len-- ) args[ len ] = arguments[ len ];\n\n      // Page attached\n      var vm = this.$wepy;\n      var app = vm.$app;\n      // eslint-disable-next-line\n      var pages = getCurrentPages();\n      var currentPage = pages[pages.length - 1];\n      var path = currentPage.__route__;\n      var webViewId = currentPage.__wxWebviewId__;\n\n      var refs = rel.refs || [];\n      var query = wx.createSelectorQuery();\n\n      refs.forEach(function (item) {\n        // {\n        //   id: { name: 'hello', bind: true },\n        //   ref: { name: 'value', bind: false }\n        // }\n        var idAttr = item.id;\n        var refAttr = item.ref;\n        var actualAttrIdName = idAttr.name;\n        var actualAttrRefName = refAttr.name;\n        var selector = \"#\" + actualAttrIdName;\n\n        if (idAttr.bind) {\n          // if id is a bind attr\n          actualAttrIdName = vm[idAttr.name];\n          selector = \"#\" + actualAttrIdName;\n          vm.$watch(idAttr.name, function(newAttrName) {\n            actualAttrIdName = newAttrName;\n            selector = \"#\" + actualAttrIdName;\n            vm.$refs[actualAttrRefName] = query.select(selector);\n          });\n        }\n\n        if (refAttr.bind) {\n          // if ref is a bind attr\n          actualAttrRefName = vm[refAttr.name];\n\n          vm.$watch(refAttr.name, function(newAttrName, oldAttrName) {\n            actualAttrRefName = newAttrName;\n            vm.$refs[oldAttrName] = null;\n            vm.$refs[newAttrName] = query.select(selector);\n          });\n        }\n        vm.$refs[actualAttrRefName] = query.select(selector);\n      });\n\n      // created 不能调用 setData，如果有 dirty 在此更新\n      vm.$forceUpdate();\n\n      if (app.$route.path !== path) {\n        app.$route.path = path;\n        app.$route.webViewId = webViewId;\n        vm.routed && vm.routed();\n      }\n\n      // TODO: page attached\n      return callUserMethod(vm, vm.$options, 'attached', args);\n    };\n    // Page lifecycle will be called under methods\n    // e.g:\n    // Component({\n    //   methods: {\n    //     onLoad () {\n    //       console.log('page onload')\n    //     }\n    //   }\n    // })\n\n    var lifecycle$1 = getLifeCycle(WEAPP_PAGE_LIFECYCLE, rel, 'page');\n\n    lifecycle$1.forEach(function (k) {\n      if (!output[k] && options[k] && (isFunc(options[k]) || isArr(options[k]))) {\n        output.methods[k] = function() {\n          var args = [], len = arguments.length;\n          while ( len-- ) args[ len ] = arguments[ len ];\n\n          return callUserMethod(this.$wepy, this.$wepy.$options, k, args);\n        };\n      }\n    });\n  }\n  var lifecycle = getLifeCycle(WEAPP_COMPONENT_LIFECYCLE, rel, 'component');\n\n  lifecycle.forEach(function (k) {\n    // beforeCreate is not a real lifecycle\n    if (!output[k] && k !== 'beforeCreate' && (isFunc(options[k]) || isArr(options[k]))) {\n      output[k] = function() {\n        var args = [], len = arguments.length;\n        while ( len-- ) args[ len ] = arguments[ len ];\n\n        return callUserMethod(this.$wepy, this.$wepy.$options, k, args);\n      };\n    }\n  });\n}\n\nvar config$1 = {\n  optionMergeStrategies: {},\n  constants: {\n    WEAPP_LIFECYCLE: WEAPP_LIFECYCLE,\n    WEAPP_APP_LIFECYCLE: WEAPP_APP_LIFECYCLE,\n    WEAPP_PAGE_LIFECYCLE: WEAPP_PAGE_LIFECYCLE,\n    WEAPP_COMPONENT_LIFECYCLE: WEAPP_COMPONENT_LIFECYCLE\n  }\n};\n\n// [Default Strategy]\n// Update if it's not exist in output. Can be replaced by option[key].\n// e.g.\n// export default {\n//   myCustomMethod () {\n//     // doSomething\n//   }\n// }\n//\n// [Merge Strategy]\n// Replaced by the latest mixins property.\n// e.g.\n// export default {\n//   data: {\n//     a: 1\n//   }\n// }\n//\n// [Lifecycle Strategy]\n// Extend lifecycle. update lifecycle to an array.\n// e.g.\n// export default {\n//   onShow: {\n//     console.log('onShow');\n//   }\n// }\nvar globalMixinPatched = false;\n\nvar strats = null;\n\nfunction getStrategy(key) {\n  if (!strats) {\n    initStrats();\n  }\n  if (strats[key]) {\n    return strats[key];\n  } else {\n    return defaultStrat;\n  }\n}\nfunction defaultStrat(output, option, key, data) {\n  if (!output[key]) {\n    output[key] = data;\n  }\n}\n\nfunction simpleMerge(parentVal, childVal) {\n  return !parentVal || !childVal ? parentVal || childVal : Object.assign({}, parentVal, childVal);\n}\n\nfunction initStrats() {\n  if (strats) { return strats; }\n\n  strats = config$1.optionMergeStrategies;\n\n  strats.data = strats.props = strats.methods = strats.computed = strats.watch = strats.hooks = function mergeStrategy(\n    output,\n    option,\n    key,\n    data\n  ) {\n    option[key] = simpleMerge(option[key], data);\n  };\n\n  WEAPP_LIFECYCLE.forEach(function (lifecycle) {\n    if (!strats[lifecycle]) {\n      strats[lifecycle] = function lifeCycleStrategy(output, option, key, data) {\n        if (!option[key]) {\n          option[key] = isArr(data) ? data : [data];\n        } else {\n          option[key] = [data].concat(option[key]);\n        }\n      };\n    }\n  });\n}\n\nfunction patchMixins(output, option, mixins) {\n  if (!mixins && !$global.mixin) {\n    return;\n  }\n\n  if (!globalMixinPatched) {\n    var globalMixin = $global.mixin || [];\n\n    mixins = globalMixin.concat(mixins);\n    globalMixinPatched = true;\n  }\n\n  if (isArr(mixins)) {\n    mixins.forEach(function (mixin) { return patchMixins(output, option, mixin); });\n    globalMixinPatched = false;\n  } else {\n    if (!strats) {\n      initStrats();\n    }\n    for (var k in mixins) {\n      strat = getStrategy(k);\n      var strat = strats[k] || defaultStrat;\n      strat(output, option, k, mixins[k]);\n    }\n  }\n}\n\nfunction patchRelations(output, relations) {\n  if (!relations) {\n    relations = {};\n  }\n  output.relations = relations;\n}\n\nfunction app$1(option, rel) {\n  var appConfig = {};\n\n  patchMixins(appConfig, option, option.mixins);\n  patchAppLifecycle(appConfig, option, rel);\n\n  return App(appConfig);\n}\n\nfunction component(opt, rel) {\n  if ( opt === void 0 ) opt = {};\n\n  var compConfig = {\n    externalClasses: opt.externalClasses || [],\n    // support component options property\n    // example: options: {addGlobalClass:true}\n    options: opt.options || {}\n  };\n\n  patchMixins(compConfig, opt, opt.mixins);\n\n  if (opt.properties) {\n    compConfig.properties = opt.properties;\n    if (opt.props) {\n      // eslint-disable-next-line no-console\n      console.warn(\"props will be ignore, if properties is set\");\n    }\n  } else if (opt.props) {\n    patchProps(compConfig, opt.props);\n  }\n\n  patchMethods(compConfig, opt.methods, true);\n\n  patchData(compConfig, opt.data, true);\n\n  patchRelations(compConfig, opt.relations);\n\n  patchLifecycle(compConfig, opt, rel, true);\n\n  return Component(compConfig);\n}\n\nfunction page(opt, rel) {\n  if ( opt === void 0 ) opt = {};\n\n  var pageConfig = {\n    externalClasses: opt.externalClasses || [],\n    // support component options property\n    // example: options: {addGlobalClass:true}\n    options: opt.options || {}\n  };\n\n  patchMixins(pageConfig, opt, opt.mixins);\n\n  if (opt.properties) {\n    pageConfig.properties = opt.properties;\n    if (opt.props) {\n      // eslint-disable-next-line\n      console.warn(\"props will be ignore, if properties is set\");\n    }\n  } else if (opt.props) {\n    patchProps(pageConfig, opt.props);\n  }\n\n  patchMethods(pageConfig, opt.methods);\n\n  patchData(pageConfig, opt.data);\n\n  patchLifecycle(pageConfig, opt, rel);\n\n  return Component(pageConfig);\n}\n\nfunction initGlobalAPI(wepy) {\n  wepy.use = use;\n  wepy.mixin = mixin;\n\n  wepy.set = function(target, key, val) {\n    set.apply(wepy, [undefined, target, key, val]);\n  };\n\n  wepy.delete = del;\n\n  wepy.observe = observe;\n\n  wepy.nextTick = renderNextTick;\n\n  wepy.app = app$1;\n  wepy.page = page;\n  wepy.component = component;\n\n  return wepy;\n}\n\nvar wepy = initGlobalAPI(WepyConstructor);\n\nwepy.config = config$1;\nwepy.global = $global;\nwepy.version = \"2.0.0-alpha.16\";\n\nmodule.exports = wepy;\n"
  },
  {
    "path": "packages/core/index.ant.js",
    "content": "import wepy from './ant/wepy';\n\nexport default wepy;\n"
  },
  {
    "path": "packages/core/index.js",
    "content": "import wepy from './weapp/wepy';\n\nexport default wepy;\n"
  },
  {
    "path": "packages/core/package.json",
    "content": "{\n  \"name\": \"@wepy/core\",\n  \"version\": \"2.1.0\",\n  \"main\": \"./dist/wepy.js\",\n  \"typings\": \"types/index.d.ts\",\n  \"scripts\": {\n    \"test:types\": \"tsc -p ./types/test/tsconfig.json\",\n    \"test\": \"_mocha --require esm --recursive\"\n  },\n  \"esm\": {\n    \"cjs\": true\n  },\n  \"author\": \"\",\n  \"license\": \"MIT\",\n  \"readme\": \"ERROR: No README data found!\",\n  \"_id\": \"@wepy/core@2.0.0-alpha.16\",\n  \"_commitid\": \"a78dcb6\",\n  \"devDependencies\": {\n    \"esm\": \"^3.2.25\",\n    \"mocha\": \"^8.0.1\",\n    \"typescript\": \"^3.3.3\"\n  },\n  \"dependencies\": {\n    \"miniprogram-api-typings\": \"^2.10.3-1\"\n  },\n  \"gitHead\": \"5a25776457360bbbbc54a4d059f6bc7c032d5df3\"\n}\n"
  },
  {
    "path": "packages/core/shared/constants.js",
    "content": "export const WEAPP_APP_LIFECYCLE = [\n  'onLaunch',\n  'onShow',\n  'onHide',\n  'onError',\n  'onPageNotFound',\n  'onUnhandledRejection',\n  'onThemeChange'\n];\n\nexport const WEAPP_PAGE_LIFECYCLE = [\n  'onLoad',\n  'onShow',\n  'onReady',\n  'onHide',\n  'onUnload',\n  'onPullDownRefresh',\n  'onReachBottom',\n  'onShareAppMessage',\n  'onAddToFavorites',\n  'onPageScroll',\n  'onResize',\n  'onTabItemTap',\n  'onShareTimeline'\n];\n\nexport const WEAPP_COMPONENT_LIFECYCLE = ['beforeCreate', 'created', 'attached', 'ready', 'moved', 'detached', 'error'];\n\nexport const WEAPP_COMPONENT_PAGE_LIFECYCLE = ['show', 'hide', 'resize'];\n\nexport const WEAPP_LIFECYCLE = []\n  .concat(WEAPP_APP_LIFECYCLE)\n  .concat(WEAPP_PAGE_LIFECYCLE)\n  .concat(WEAPP_COMPONENT_LIFECYCLE)\n  .concat(WEAPP_COMPONENT_PAGE_LIFECYCLE);\n"
  },
  {
    "path": "packages/core/shared/env.js",
    "content": "// can we use __proto__?\nfunction getHasProto() {\n  let hasProto = false;\n  if ('__proto__' in {}) {\n    const fn = () => {};\n    const arr = [];\n    arr.__proto__ = { push: fn };\n    hasProto = fn === arr.push;\n  }\n  return hasProto;\n}\nexport const hasProto = getHasProto();\n\nlet _Set; // $flow-disable-line\n/* istanbul ignore if */ if (typeof Set !== 'undefined' && isNative(Set)) {\n  // use native Set when available.\n  _Set = Set;\n} else {\n  // a non-standard Set polyfill that only works with primitive keys.\n  _Set = class Set {\n    constructor() {\n      this.set = Object.create(null);\n    }\n    has(key) {\n      return this.set[key] === true;\n    }\n    add(key) {\n      this.set[key] = true;\n    }\n    clear() {\n      this.set = Object.create(null);\n    }\n  };\n}\n\nexport { _Set };\n\n/* istanbul ignore next */\nexport function isNative(Ctor) {\n  return typeof Ctor === 'function' && /native code/.test(Ctor.toString());\n}\n"
  },
  {
    "path": "packages/core/shared/extend.js",
    "content": "import { isPlainObject, isArr } from './util';\n\n/*\n * extend objects\n * e.g.\n * extend({}, {a: 1}) : extend {a: 1} to {}\n * extend(true, [], [1,2,3]) : deep extend [1,2,3] to an empty array\n * extend(true, {}, {a: 1}, {b: 2}) : deep extend two objects to {}\n */\nexport function extend() {\n  let options,\n    name,\n    src,\n    copy,\n    copyIsArray,\n    clone,\n    target = arguments[0] || {},\n    i = 1,\n    length = arguments.length,\n    deep = false;\n\n  // Handle a deep copy situation\n  if (typeof target === 'boolean') {\n    deep = target;\n\n    // Skip the boolean and the target\n    target = arguments[i] || {};\n    i++;\n  }\n\n  // Handle case when target is a string or something (possible in deep copy)\n  if (typeof target !== 'object' && !(typeof target === 'function')) {\n    target = {};\n  }\n\n  // Extend jQuery itself if only one argument is passed\n  if (i === length) {\n    target = this;\n    i--;\n  }\n\n  for (; i < length; i++) {\n    // Only deal with non-null/undefined values\n    if ((options = arguments[i])) {\n      // Extend the base object\n      for (name in options) {\n        src = target[name];\n        copy = options[name];\n\n        // Prevent never-ending loop\n        if (target === copy) {\n          continue;\n        }\n\n        // Recurse if we're merging plain objects or arrays\n        if (deep && copy && (isPlainObject(copy) || (copyIsArray = Array.isArray(copy)))) {\n          if (copyIsArray) {\n            copyIsArray = false;\n            clone = src && Array.isArray(src) ? src : [];\n          } else {\n            clone = src && isPlainObject(src) ? src : {};\n          }\n\n          // Never move original objects, clone them\n          target[name] = extend(deep, clone, copy);\n\n          // Don't bring in undefined values => bring undefined values\n        } else {\n          target[name] = copy;\n        }\n      }\n    }\n  }\n\n  // Return the modified object\n  return target;\n}\n\n/*\n * clone objects, return a cloned object default to use deep clone\n * e.g.\n * clone({a: 1})\n * clone({a: b: {c : 1}}, false);\n */\nexport function clone(sth, deep = true) {\n  if (isArr(sth)) {\n    return extend(deep, [], sth);\n  } else if ('' + sth === 'null') {\n    return sth;\n  } else if (isPlainObject(sth)) {\n    return extend(deep, {}, sth);\n  } else {\n    return sth;\n  }\n}\n"
  },
  {
    "path": "packages/core/shared/index.js",
    "content": "export * from './env';\nexport * from './util';\nexport * from './extend';\nexport * from './constants';\n"
  },
  {
    "path": "packages/core/shared/util.js",
    "content": "/**\n * String type check\n */\nexport const isStr = v => typeof v === 'string';\n/**\n * Number type check\n */\nexport const isNum = v => typeof v === 'number';\n/**\n * Array type check\n */\nexport const isArr = Array.isArray;\n/**\n * undefined type check\n */\nexport const isUndef = v => v === undefined;\n/**\n * Function type check\n */\nexport const isFunc = v => typeof v === 'function';\n/**\n * Quick object check - this is primarily used to tell\n * Objects from primitive values when we know the value\n * is a JSON-compliant type.\n */\nexport function isObject(obj) {\n  return obj !== null && typeof obj === 'object';\n}\n\nexport const isObj = isObject;\n/**\n * Strict object type check. Only returns true\n * for plain JavaScript objects.\n */\nconst _toString = Object.prototype.toString;\nexport function isPlainObject(obj) {\n  return _toString.call(obj) === '[object Object]';\n}\n\n/**\n * Check whether the object has the property.\n */\nconst hasOwnProperty = Object.prototype.hasOwnProperty;\nexport function hasOwn(obj, key) {\n  return hasOwnProperty.call(obj, key);\n}\n\n/**\n * Perform no operation.\n * Stubbing args to make Flow happy without leaving useless transpiled code\n * with ...rest (https://flow.org/blog/2017/05/07/Strict-Function-Call-Arity/)\n */\n// eslint-disable-next-line\nexport function noop(a, b, c) {}\n\n/**\n * Check if val is a valid array index.\n */\nexport function isValidArrayIndex(val) {\n  const n = parseFloat(String(val));\n  return n >= 0 && Math.floor(n) === n && isFinite(val);\n}\n\n/**\n * Convert an Array-lik object to a real Array\n */\nexport function toArray(list, start = 0) {\n  let i = list.length - start;\n  let rst = new Array(i);\n  while (i--) {\n    rst[i] = list[i + start];\n  }\n  return rst;\n}\n\n/**\n * Cached simply key function return\n */\nexport const cached = fn => {\n  let cache = {};\n  return str => cache[str] || (cache[str] = fn(str));\n};\n\nconst camelizeRE = /-(\\w)/g;\nconst hyphenateRE = /([^-])([A-Z])/g;\n\n/**\n * hyphenate words\n * e.g. myKey => my-key\n */\nexport const hyphenate = cached(str =>\n  str\n    .replace(hyphenateRE, '$1-$2')\n    .replace(hyphenateRE, '$1-$2')\n    .toLowerCase()\n);\n\n/**\n * camelize words\n * e.g. my-key => myKey\n */\nexport const camelize = cached(str => str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : '')));\n"
  },
  {
    "path": "packages/core/src/bar.js",
    "content": "const bar = num => {\n  return num - 1;\n};\n\nexport { bar };\n"
  },
  {
    "path": "packages/core/src/foo.js",
    "content": "import { bar } from './bar';\n\nconst foo = num => {\n  return num + 1;\n};\n\nconst foobar = num => {\n  return foo(bar(num));\n};\n\nexport { foo, foobar };\n"
  },
  {
    "path": "packages/core/src/index.js",
    "content": "export { foo } from './foo';\n"
  },
  {
    "path": "packages/core/test/.istanbul.yml",
    "content": ""
  },
  {
    "path": "packages/core/test/bar.spec.js",
    "content": "import { bar } from '../src/bar';\n\nimport { expect } from 'chai';\n\ndescribe('bar', function() {\n  describe('bar()', function() {\n    it('should return number minus one', function() {\n      expect(bar(1)).to.equal(0);\n    });\n  });\n});\n"
  },
  {
    "path": "packages/core/test/foo.spec.js",
    "content": "import { foo, foobar } from '../src/foo';\n\nimport { expect } from 'chai';\n\ndescribe('foo', function() {\n  describe('foo()', function() {\n    it('should return number plus one', function() {\n      expect(foo(1)).to.equal(2);\n    });\n  });\n\n  describe('foobar()', function() {\n    it('should return same number', function() {\n      expect(foobar(1)).to.equal(1);\n    });\n  });\n});\n"
  },
  {
    "path": "packages/core/test/index.test.js",
    "content": ""
  },
  {
    "path": "packages/core/test/mock/api/createSelectorQuery.js",
    "content": "module.exports = function createSelectorQuery() {\n  return {\n    query(selector) {\n      return {\n        mock: true,\n        selector\n      };\n    }\n  };\n};\n"
  },
  {
    "path": "packages/core/test/mock/wxapi.js",
    "content": "const fs = require('fs');\nconst path = require('path');\n\nclass MockWxAPI {\n  constructor() {\n    this._wx = {};\n    this.init();\n  }\n\n  init() {\n    const files = fs.readdirSync(path.join(__dirname, 'api'));\n    files.forEach(file => {\n      const api = file.replace('.js', '');\n      this._wx[api] = require('./api/' + api);\n    });\n    return this;\n  }\n\n  mock(api, fn) {\n    if (arguments.length === 2) {\n      this._wx[api] = fn;\n    }\n    global.wx = this._wx;\n    return this;\n  }\n\n  unmock(api) {\n    if (api) {\n      delete this._wx[api];\n      global.wx = this._wx;\n    } else {\n      this._wx = {};\n      delete global.wx;\n    }\n    return this;\n  }\n}\n\nmodule.exports = MockWxAPI;\n"
  },
  {
    "path": "packages/core/test/weapp/class/Dirty.js",
    "content": "import { initData } from '../../../weapp/init/data';\nimport Dirty from '../../../weapp/class/Dirty';\n\nconst expect = require('chai').expect;\n\ndescribe('weapp class Dirty', function() {\n  it('test dirty path', () => {\n    const vm = {};\n    vm.$dirty = new Dirty('path');\n\n    initData(vm, { list: [], num: 1, arr: [1, 2], complex: { a: 1, arr: [100, { x: [0, 1, { b: 1 }] }] } });\n\n    vm.num = 2;\n    expect(vm.$dirty.length()).to.be.equal(1);\n\n    let dirty;\n\n    dirty = vm.$dirty.pop();\n    expect(vm.$dirty.length()).to.be.equal(0);\n    expect(dirty).to.deep.equal({ num: 2 });\n\n    vm.num = 100;\n    vm.complex.arr[1].x[2].b = 2;\n\n    expect(vm.$dirty.length()).to.be.equal(2);\n    dirty = vm.$dirty.pop();\n    expect(vm.$dirty.length()).to.be.equal(0);\n    expect(dirty).to.be.deep.equal({ num: 100, 'complex.arr[1].x[2].b': 2 });\n\n    vm.list.push({ a: 1 });\n    dirty = vm.$dirty.pop();\n    expect(JSON.stringify(dirty)).to.be.equal('{\"list[0]\":{\"a\":1}}');\n\n    vm.list.push({ b: 1 });\n    dirty = vm.$dirty.pop();\n    expect(JSON.stringify(dirty)).to.be.equal('{\"list[1]\":{\"b\":1}}');\n\n    vm.complex.arr.push(200);\n    expect(vm.$dirty.length()).to.be.equal(1);\n    dirty = vm.$dirty.pop();\n    expect(vm.$dirty.length()).to.be.equal(0);\n    expect(dirty).to.be.deep.equal({ 'complex.arr[2]': 200 });\n\n    vm.complex.arr.splice(1, 1, 233);\n    expect(vm.$dirty.length()).to.be.equal(1);\n    dirty = vm.$dirty.pop();\n    expect(vm.$dirty.length()).to.be.equal(0);\n    expect(dirty).to.be.deep.equal({ 'complex.arr': [100, 233, 200] });\n  });\n\n  it('test dirty key', () => {\n    const vm = {};\n    vm.$dirty = new Dirty('key');\n\n    initData(vm, { num: 1, arr: [1, 2], complex: { a: 1, arr: [100, { x: [0, 1, { b: 1 }] }] } });\n\n    vm.num = 2;\n    expect(vm.$dirty.length()).to.be.equal(1);\n\n    let dirty;\n\n    dirty = vm.$dirty.pop();\n    expect(vm.$dirty.length()).to.be.equal(0);\n    expect(dirty).to.deep.equal({ num: 2 });\n\n    vm.num = 100;\n    vm.complex.arr[1].x[2].b = 2;\n\n    expect(vm.$dirty.length()).to.be.equal(2);\n    dirty = vm.$dirty.pop();\n    expect(vm.$dirty.length()).to.be.equal(0);\n    expect(dirty).to.be.deep.equal({ num: 100, complex: vm.complex });\n  });\n});\n"
  },
  {
    "path": "packages/core/test/weapp/dispatcher/index.test.js",
    "content": "import { expect } from 'chai';\nimport { dispatcher } from '../../../weapp/dispatcher/index';\nimport { addEventListener, createOriginalPage, simulateOriginalWePYEvent } from '../helper/index';\n\ndescribe('weapp dispatcher', function() {\n  it('Create Page', done => {\n    const page = createOriginalPage();\n\n    const params = [1, 2];\n\n    const evtid = addEventListener(page, 'tap', function(...args) {\n      expect(args[0]).is.equal(params[0]);\n      expect(args[1]).is.equal(params[1]);\n      expect(args[2].type).is.equal('tap');\n      done();\n    });\n\n    const e = simulateOriginalWePYEvent('tap', evtid, params);\n    dispatcher.call(page, e);\n  });\n});\n"
  },
  {
    "path": "packages/core/test/weapp/helper/index.js",
    "content": "import Page from './libs/Page';\nimport WepyPage from '../../../weapp/class/WepyPage';\nimport WepyApp from '../../../weapp/class/WepyApp';\n\nexport function createApp(opt = {}) {\n  const wepyApp = new WepyApp(opt);\n  wepyApp.hooks = {};\n  return wepyApp;\n}\nexport function createPage(opt = {}) {\n  const wepy = new WepyPage(opt);\n  wepy.__pageid = 1;\n  wepy.__events = 0;\n\n  wepy.$app = createApp({});\n  return wepy;\n}\n\nexport function createOriginalApp(opt) {\n  const app = new App();\n  const wepyApp = createApp(opt);\n  app.$wepy = wepyApp;\n  return app;\n}\n\nexport function createOriginalPage(opt) {\n  const wepy = createPage(opt);\n  const page = new Page();\n  page.$wepy = wepy;\n\n  return page;\n}\n\nexport function simulateOriginalEvent(type, opt) {\n  if (!opt) {\n    opt = {};\n  }\n  if (!opt.currentTarget || !opt.currentTarget.dataset) {\n    opt.currentTarget = {\n      dataset: {}\n    };\n  }\n  if (!opt.detail) {\n    opt.detail = {};\n  }\n  opt.type = type;\n  return opt;\n}\n\nexport function simulateOriginalWePYEvent(type, evtid, params) {\n  const e = simulateOriginalEvent(type);\n\n  params.forEach((p, i) => {\n    const key = 'wpy' + type.toLowerCase() + String.fromCharCode(97 + i).toUpperCase();\n    e.currentTarget.dataset[key] = p;\n  });\n\n  e.currentTarget.dataset.wpyEvt = evtid;\n  return e;\n}\n\nexport function addEventListener(comp, type, handler) {\n  const wepy = comp.$wepy;\n  wepy.__events++;\n  const evtid = wepy.__pageid + '-' + wepy.__events;\n\n  if (!wepy.$rel) {\n    wepy.$rel = { handlers: {} };\n  }\n\n  const handlers = wepy.$rel.handlers;\n  if (!handlers[evtid]) {\n    handlers[evtid] = {};\n  }\n  handlers[evtid][type] = handler;\n  return evtid;\n}\n"
  },
  {
    "path": "packages/core/test/weapp/helper/libs/App.js",
    "content": "export default class App {}\n"
  },
  {
    "path": "packages/core/test/weapp/helper/libs/Component.js",
    "content": "export default class Page {\n  setData() {}\n}\n"
  },
  {
    "path": "packages/core/test/weapp/helper/libs/Page.js",
    "content": "export default class Page {\n  setData() {}\n}\n"
  },
  {
    "path": "packages/core/test/weapp/init/data.js",
    "content": "import { patchData, initData } from '../../../weapp/init/data';\n\nconst expect = require('chai').expect;\n\ndescribe('weapp init data', function() {\n  it('patch data', () => {\n    const output = {};\n\n    patchData(output, false);\n\n    expect(output.data).to.be.an('object');\n\n    patchData(output, { a: 1 });\n\n    expect(output.data.a).to.equal(1);\n  });\n\n  it('init data', () => {\n    const vm = {};\n\n    initData(vm, { num: 1, str: 'string', arr: [1, 2], obj: { a: 1 }, deepobj: { node: { a: 1 } } });\n\n    expect(vm.num).to.be.equal(vm._data.num);\n    expect(vm.str).to.be.equal(vm._data.str);\n    expect(vm.arr).to.be.equal(vm._data.arr);\n    expect(vm.obj).to.be.equal(vm._data.obj);\n    expect(vm.deepobj).to.be.equal(vm._data.deepobj);\n    expect(vm.obj.__ob__).to.be.an('object');\n    expect(vm.deepobj.node.__ob__).to.be.an('object');\n  });\n\n  it('init data from function', () => {\n    const vm = {};\n\n    initData(vm, function() {\n      return {\n        a: 1\n      };\n    });\n\n    expect(vm.a).to.be.equal(1);\n  });\n});\n"
  },
  {
    "path": "packages/core/test/weapp/init/lifecycle.test.js",
    "content": "const expect = require('chai').expect;\nimport { getLifeCycle, patchAppLifecycle, patchLifecycle } from '../../../weapp/init';\nimport { WEAPP_APP_LIFECYCLE } from '../../../shared';\n\nimport MockWxAPI from '../../mock/wxapi';\n\nconst mockapi = new MockWxAPI();\n\nconst allPages = [];\nconst pageIndex = -1;\n\ndescribe('weapp life cycles', () => {\n  before(() => {\n    mockapi.mock();\n\n    global.getCurrentPages = function() {\n      return allPages;\n    };\n  });\n  after(() => {\n    mockapi.unmock();\n  });\n\n  it('should add wepy.app life cycles for string', () => {\n    const rel = {\n      lifecycle: {\n        app: 'onSomeNewFeature'\n      }\n    };\n    const lifeCycles = getLifeCycle(WEAPP_APP_LIFECYCLE, rel, 'app');\n    expect(lifeCycles).to.deep.equal([...WEAPP_APP_LIFECYCLE, 'onSomeNewFeature']);\n  });\n\n  it('should add wepy.app life cycles for array', () => {\n    const rel = {\n      lifecycle: {\n        app: ['onSomeNewFeature1', 'onSomeNewFeature2']\n      }\n    };\n    const lifeCycles = getLifeCycle(WEAPP_APP_LIFECYCLE, rel, 'app');\n    expect(lifeCycles).to.deep.equal([...WEAPP_APP_LIFECYCLE, 'onSomeNewFeature1', 'onSomeNewFeature2']);\n  });\n\n  it('should modify wepy.app life cycles for function', () => {\n    const rel = {\n      lifecycle: {\n        app: function(lifecycles) {\n          const newLifeCycles = lifecycles.filter(l => l !== 'onError');\n          return [...newLifeCycles, 'onSomeNewFeature'];\n        }\n      }\n    };\n    const lifeCycles = getLifeCycle(WEAPP_APP_LIFECYCLE, rel, 'app');\n    expect(lifeCycles).to.deep.equal([...WEAPP_APP_LIFECYCLE.filter(l => l !== 'onError'), 'onSomeNewFeature']);\n  });\n\n  it('patchAppLifecycle', () => {\n    const runState = {\n      onLaunch1: false,\n      onLaunch2: false,\n      onShow: false\n    };\n    const appInstance = {};\n    const appConfig = {};\n    const options = {\n      onShow() {\n        runState.onShow = true;\n      },\n      onLaunch: [\n        () => {\n          runState.onLaunch1 = true;\n        },\n        () => {\n          runState.onLaunch2 = true;\n        }\n      ]\n    };\n    const rel = {};\n\n    patchAppLifecycle(appConfig, options, rel);\n\n    expect(appConfig.onLaunch).is.a('function');\n    expect(appConfig.onShow).is.a('function');\n\n    expect(appConfig.onError).is.a('undefined');\n\n    appConfig.onLaunch.call(appInstance);\n\n    appConfig.onShow.call(appInstance);\n\n    for (const k in runState) {\n      expect(runState[k]).to.be.equal(true);\n    }\n  });\n\n  it('patchLifecycle componennt', () => {\n    const runState = {\n      ready: false\n    };\n    const compInstance = {};\n    const output = { methods: {} };\n    const options = {\n      ready() {\n        runState.ready = true;\n      }\n    };\n    const rel = {};\n\n    patchLifecycle(output, options, rel, true);\n\n    expect(output.created).is.a('function');\n\n    output.created.call(compInstance);\n\n    output.ready.call(compInstance);\n\n    expect(runState.ready).to.equal(true);\n  });\n\n  it('patchLifecycle page', () => {\n    const runState = {\n      routed: false,\n      testPageRouted: false\n    };\n    const indexPage = {\n      is: 'somepage',\n      route: 'pages/index',\n      __wxExparserNodeId__: '29d1dad1',\n      __wxWebviewId__: 1\n    };\n    const output = { methods: {} };\n    const options = {\n      routed(oldRoute, newRoute) {\n        expect(oldRoute).to.equal(null);\n        expect(newRoute.path).to.equal(indexPage.route);\n        runState.routed = true;\n      }\n    };\n    const rel = {};\n\n    patchLifecycle(output, options, rel, false);\n\n    expect(output.created).is.a('function');\n    expect(output.attached).is.a('function');\n\n    output.created.call(indexPage);\n    output.attached.call(indexPage);\n\n    allPages.push(indexPage);\n\n    output.methods.onShow.call(indexPage);\n\n    expect(runState.routed).to.equal(true);\n\n    const testPage = {\n      is: 'testpage',\n      route: 'pages/test',\n      __wxExparserNodeId__: '29d2dad2',\n      __wxWebviewId__: 2\n    };\n    const testOutput = { methods: {} };\n    const testOutputOptions = {\n      routed(oldRoute, newRoute) {\n        expect(oldRoute.path).to.equal(indexPage.route);\n        expect(newRoute.path).to.equal(testPage.route);\n        runState.testPageRouted = true;\n      }\n    };\n\n    patchLifecycle(testOutput, testOutputOptions, rel, false);\n\n    testOutput.created.call(testPage);\n    testOutput.attached.call(testPage);\n\n    allPages.push(testPage);\n\n    testOutput.methods.onShow.call(testPage);\n\n    for (const k in runState) {\n      expect(runState[k]).to.be.equal(true);\n    }\n  });\n});\n"
  },
  {
    "path": "packages/core/test/weapp/observer/index.test.js",
    "content": ""
  },
  {
    "path": "packages/core/test/weapp/observer/observerPath.test.js",
    "content": "import { initData } from '../../../weapp/init/data';\nimport { set } from '../../../weapp/observer';\nimport { getPathMap } from '../../../weapp/observer/observerPath';\n\nconst expect = require('chai').expect;\nconst _getPathMap = (obj, key) =>\n  key !== undefined\n    ? getPathMap(key, obj.__ob__.op.pathKeys, obj.__ob__.op.pathMap).combinePathMap\n    : obj.__ob__.op.pathMap;\n\ndescribe('weapp observer observerPath', function() {\n  it('only path', function() {\n    const vm = {};\n\n    initData(vm, { num: 1, str: 'string', arr: [1, 2], obj: { a: 1 }, deepObj: { node: { a: 1 } } });\n\n    const data = vm._data;\n    expect(_getPathMap(data, 'num')).to.be.deep.equal({ num: { key: 'num', root: 'num', path: 'num' } });\n    expect(_getPathMap(data, 'str')).to.be.deep.equal({ str: { key: 'str', root: 'str', path: 'str' } });\n    expect(_getPathMap(data, 'arr')).to.be.deep.equal({ arr: { key: 'arr', root: 'arr', path: 'arr' } });\n    expect(_getPathMap(data, 'obj')).to.be.deep.equal({ obj: { key: 'obj', root: 'obj', path: 'obj' } });\n    expect(_getPathMap(data, 'deepObj')).to.be.deep.equal({\n      deepObj: {\n        key: 'deepObj',\n        root: 'deepObj',\n        path: 'deepObj'\n      }\n    });\n  });\n\n  it('only deep path', function() {\n    const vm = {};\n\n    initData(vm, { arr: [1, 2], obj: { a: 1 }, deepObj: { node: { a: 1 } } });\n\n    const data = vm._data;\n    expect(_getPathMap(data.arr, 0)).to.be.deep.equal({ 'arr[0]': { key: 0, root: 'arr', path: 'arr[0]' } });\n    expect(_getPathMap(data.obj, 'a')).to.be.deep.equal({ 'obj.a': { key: 'a', root: 'obj', path: 'obj.a' } });\n    expect(_getPathMap(data.deepObj.node, 'a')).to.be.deep.equal({\n      'deepObj.node.a': { key: 'a', root: 'deepObj', path: 'deepObj.node.a' }\n    });\n\n    set(vm, vm.deepObj, 'parent', { child: 233 });\n    expect(_getPathMap(data.deepObj, 'parent')).to.be.deep.equal({\n      'deepObj.parent': { key: 'parent', root: 'deepObj', path: 'deepObj.parent' }\n    });\n    expect(_getPathMap(data.deepObj.parent, 'child')).to.be.deep.equal({\n      'deepObj.parent.child': { key: 'child', root: 'deepObj', path: 'deepObj.parent.child' }\n    });\n  });\n\n  it('complex path: Object', function() {\n    const vm = {};\n\n    initData(vm, { a: { b: { c: { d: 123 } } }, x: {}, y: {} });\n\n    // eslint-disable-next-line\n    const data = vm._data;\n    data.x = data.a.b.c;\n    data.y = data.x;\n\n    expect(_getPathMap(data.a.b.c, 'd')).to.be.deep.equal({\n      'x.d': { key: 'd', root: 'x', path: 'x.d' },\n      'y.d': { key: 'd', root: 'y', path: 'y.d' },\n      'a.b.c.d': { key: 'd', root: 'a', path: 'a.b.c.d' }\n    });\n    expect(_getPathMap(data.x, 'd')).to.be.deep.equal({\n      'x.d': { key: 'd', root: 'x', path: 'x.d' },\n      'y.d': { key: 'd', root: 'y', path: 'y.d' },\n      'a.b.c.d': { key: 'd', root: 'a', path: 'a.b.c.d' }\n    });\n    expect(_getPathMap(data.y, 'd')).to.be.deep.equal({\n      'x.d': { key: 'd', root: 'x', path: 'x.d' },\n      'y.d': { key: 'd', root: 'y', path: 'y.d' },\n      'a.b.c.d': { key: 'd', root: 'a', path: 'a.b.c.d' }\n    });\n\n    data.x = { d: 123 };\n\n    expect(_getPathMap(data.a.b.c, 'd')).to.be.deep.equal({\n      'y.d': { key: 'd', root: 'y', path: 'y.d' },\n      'a.b.c.d': { key: 'd', root: 'a', path: 'a.b.c.d' }\n    });\n    expect(_getPathMap(data.x, 'd')).to.be.deep.equal({\n      'x.d': { key: 'd', root: 'x', path: 'x.d' }\n    });\n    expect(_getPathMap(data.y, 'd')).to.be.deep.equal({\n      'y.d': { key: 'd', root: 'y', path: 'y.d' },\n      'a.b.c.d': { key: 'd', root: 'a', path: 'a.b.c.d' }\n    });\n  });\n\n  it('complex path: Array', function() {\n    const vm = {};\n\n    initData(vm, { arr1: [], arr2: [], arr3: [] });\n\n    const data = vm._data;\n    const obj = { a: 123 };\n    data.arr1.push(obj);\n    data.arr2.splice(0, 0, obj);\n    data.arr3.unshift(obj);\n\n    expect(_getPathMap(data.arr1[0], 'a')).to.be.deep.equal({\n      'arr1[0].a': { key: 'a', root: 'arr1', path: 'arr1[0].a' },\n      'arr2[0].a': { key: 'a', root: 'arr2', path: 'arr2[0].a' },\n      'arr3[0].a': { key: 'a', root: 'arr3', path: 'arr3[0].a' }\n    });\n    expect(_getPathMap(data.arr2[0], 'a')).to.be.deep.equal({\n      'arr1[0].a': { key: 'a', root: 'arr1', path: 'arr1[0].a' },\n      'arr2[0].a': { key: 'a', root: 'arr2', path: 'arr2[0].a' },\n      'arr3[0].a': { key: 'a', root: 'arr3', path: 'arr3[0].a' }\n    });\n    expect(_getPathMap(data.arr3[0], 'a')).to.be.deep.equal({\n      'arr1[0].a': { key: 'a', root: 'arr1', path: 'arr1[0].a' },\n      'arr2[0].a': { key: 'a', root: 'arr2', path: 'arr2[0].a' },\n      'arr3[0].a': { key: 'a', root: 'arr3', path: 'arr3[0].a' }\n    });\n\n    data.arr2.splice(0, 1);\n\n    expect(_getPathMap(data.arr1[0], 'a')).to.be.deep.equal({\n      'arr1[0].a': { key: 'a', root: 'arr1', path: 'arr1[0].a' },\n      'arr3[0].a': { key: 'a', root: 'arr3', path: 'arr3[0].a' }\n    });\n    expect(_getPathMap(data.arr3[0], 'a')).to.be.deep.equal({\n      'arr1[0].a': { key: 'a', root: 'arr1', path: 'arr1[0].a' },\n      'arr3[0].a': { key: 'a', root: 'arr3', path: 'arr3[0].a' }\n    });\n  });\n});\n"
  },
  {
    "path": "packages/core/test/weapp/util/debug.test.js",
    "content": "import { warn, tip } from '../../../weapp/util/debug';\nconst expect = require('chai').expect;\n\ndescribe('debug test', function () {\n    it('warn test', function () {\n        const app = {\n            data: 24\n        };\n        expect(warn('SyntaxError', app)).to.deep.equal(undefined);\n    });\n    \n    it('tip test', function () {\n        const app = {\n            data: 24\n        };\n        expect(tip('ReferenceError', app)).to.deep.equal(undefined);\n    })\n});\n/*\n*原文件中应该在 Found in component 之前加一个空格效果比较好？\n*/"
  },
  {
    "path": "packages/core/test/weapp/util/error.test.js",
    "content": "const expect = require('chai').expect;\nimport { handleError } from '../../../weapp/util/error';\n\ndescribe('handleError test', () => {\n    it('error test', () => {\n        const app = {\n            data: 24\n        };\n        const func = handleError('ReferenceError', app, 'render');\n        expect(func).to.deep.equal(undefined)\n    });\n});"
  },
  {
    "path": "packages/core/test/weapp/util/index.test.js",
    "content": "\nconst expect = require('chai').expect;\n//var remove = require('../../../weapp/util/index').remove;\nimport { remove, isReserved, def, parsePath } from '../../../weapp/util/index';\nimport { obj } from 'through2';\n\ndescribe('remove test', () => {\n    it('arr remove 2', () => {\n        const arr1 = [2, 3, 7, 5, 6, 7, 8, 1];\n        const removearr = remove(arr1, 2);\n        expect(removearr).to.deep.equal([2]);\n    });\n\n    it('arr remove 4', () => {\n        const arr2 = [2, 3, 7, 5, 6, 7, 8, 1];\n        expect(remove(arr2, 4)).to.deep.equal(undefined);\n    });\n\n    it('arr is null', () => {\n        const arr3 = [];\n        expect(remove(arr3, 2)).to.deep.equal(undefined);\n    })\n});\n\ndescribe('isReserved test', () => {\n    it('Check if a string starts with _', () => {\n        expect(isReserved('_static')).to.be.true;\n    });\n    it('Check if a string starts with $ ', () => {\n        expect(isReserved('$key')).to.be.true;\n    });\n    it('Check if a string starts without $ or _ ', () => {\n        expect(isReserved('dhdff')).to.be.false;\n    })\n});\n\ndescribe('def test', () => {\n    it('add property', () => {\n        const obj = {};\n        def(obj, 'color', 'white', true);\n        expect(obj).to.deep.equal({ color: 'white' });\n    });\n\n    it('modified property', () => {\n        const obj = {\n            eat: 'fish',\n            color: 'white'\n        };\n        def(obj, 'color', 'black', true);\n        expect(obj).to.deep.equal({\n            eat: 'fish',\n            color: 'black'\n        });\n    });\n});\n\n\ndescribe('parsePath test', () => {\n    it('parsePath test: return an property value', () => {\n        const path = 'wepy.test';\n        let a = parsePath(path);\n        const b = a({ wepy: { test: 1 } });\n        expect(b).to.deep.equal(1);\n    });\n\n    it('parsePath test: return an object', () => {\n        const path = 'wepy.test';\n        let a = parsePath(path);\n        const b = a({ wepy: { test: { test2: 'test3' } } });\n        expect(b).to.deep.equal({ test2: 'test3' });\n    });\n\n    it('parsePath test: Don\\'t satisfy regular expression', () => {\n        const path = 'wepy.';\n        let a = parsePath(path);\n        const b = a({ wepy: { test: { test2: 'test3' } } });\n        expect(b).to.deep.equal(undefined);\n    });\n\n    it('parsePath test: Don\\'t satisfy regular expression', () => {\n        const path = 'wepy.test';\n        let a = parsePath(path);\n        const b = a({ wepy1: { test1: { test2: 'test3' } } });\n        expect(b).to.deep.equal(undefined);\n    });\n});\n"
  },
  {
    "path": "packages/core/test/weapp/util/model.test.js",
    "content": "\nconst expect = require('chai').expect;\nimport { parseModel } from '../../../weapp/util/model';\n\ndescribe('parseModel test', () => {\n    it('there are no square brackets and dots :', () => {\n        var str = '  test  ';\n        expect(parseModel(str)).to.deep.equal({\n            expr: 'test',\n            key: null\n        })\n    });\n\n\n    it('there are only dots :', () => {\n        var str = ' test.key ';\n        expect(parseModel(str)).to.deep.equal({\n            expr: 'test',\n            key: 'key'\n        })\n    });\n\n    it(' there are only brackets :', () => {\n        var str = '  test[key]  ';\n        expect(parseModel(str)).to.deep.equal({\n            expr: 'test',\n            key: 'key'\n        })\n    });\n\n    it('there are multiple square brackets nesting :', () => {\n        var str = ' test[test1[key]]  ';\n        expect(parseModel(str)).to.deep.equal({\n            expr: 'test',\n            key: 'test1[key]'\n        })\n    });\n\n    it('there are double quotation marks ：', () => {\n        var str = ' test[\"a\"][key]  ';\n        expect(parseModel(str)).to.deep.equal({\n            expr: 'test[\\\"a\\\"]',\n            key: 'key'\n        })\n    });\n\n    it('there are points and brackets nesting :', () => {\n        var str = ' xxx.test[a[a].test1[key]]  ';\n        expect(parseModel(str)).to.deep.equal({\n            expr: 'xxx.test',\n            key: 'a[a].test1[key]'\n        })\n    });\n\n    it('there are multiple dots and brackets :', () => {\n        var str = ' test.xxx.a[\"asa\"][test1[key]]  ';\n        expect(parseModel(str)).to.deep.equal({\n            expr: 'test.xxx.a[\\\"asa\\\"]',\n            key: 'test1[key]'\n        })\n    });\n\n\n});\n\n"
  },
  {
    "path": "packages/core/test/weapp/util/next-tick.test.js",
    "content": "import { withMacroTask, nextTick, renderFlushCallbacks, renderNextTick} from '../../../weapp/util/next-tick';\nconst expect = require('chai').expect;\n\ndescribe('next-tick test', function () {\n  it('macro task with normal function', function () {\n    const fn = () => 1;\n    expect(withMacroTask(fn)).is.an('function');\n  });\n});\n"
  },
  {
    "path": "packages/core/types/index.d.ts",
    "content": "/// <reference path=\"./wx/index.d.ts\" />\n\nimport { wepy } from './wepy';\n\nexport default wepy;\n\nexport as namespace wepy;\n\nexport {\n  WepyConstructor\n} from './wepy';\n\nexport {\n  ComponentOptions,\n  PropType,\n  PropOptions,\n  ComputedOptions,\n  WatchHandler,\n  WatchOptions,\n  WatchOptionsWithHandler,\n} from \"./options\";\n\nexport {\n  PluginFunction,\n  PluginObject\n} from \"./plugin\";\n\n"
  },
  {
    "path": "packages/core/types/options.d.ts",
    "content": "import { wepy, CombineWepyInstance, WepyInstace, WepyApp } from \"./wepy\";\n\n\ntype Constructor = {\n  new (...args: any[]): any;\n}\n\n/**\n * When the `Computed` type parameter on `ComponentOptions` is inferred,\n * it should have a property with the return type of every get-accessor.\n * Since there isn't a way to query for the return type of a function, we allow TypeScript\n * to infer from the shape of `Accessors<Computed>` and work backwards.\n */\nexport type Accessors<T> = {\n  [K in keyof T]: (() => T[K]) | ComputedOptions<T[K]>\n}\n\ntype DataDef<Data, Props, V> = Data | ((this: Readonly<Props> & V) => Data)\n/**\n * This type should be used when an array of strings is used for a component's `props` value.\n */\nexport type ThisTypedComponentOptionsWithArrayProps<V extends WepyInstace, Data, Methods, Hooks, Computed, PropNames extends string> =\n  object &\n  ComponentOptions<V, DataDef<Data, Record<PropNames, any>, V>, Methods, Hooks, Computed, PropNames[], Record<PropNames, any>> &\n  ThisType<CombineWepyInstance<V, Data, Methods, Hooks, Computed, Readonly<Record<PropNames, any>>>>;\n\n/**\n * This type should be used when an object mapped to `PropOptions` is used for a component's `props` value.\n */\nexport type ThisTypedComponentOptionsWithRecordProps<V extends WepyInstace, Data, Methods, Hooks, Computed, Props> =\n  object &\n  ComponentOptions<V, DataDef<Data, Props, V>, Methods, Hooks, Computed, RecordPropsDefinition<Props>, Props> &\n  ThisType<CombineWepyInstance<V, Data, Methods, Hooks, Computed, Readonly<Props>>>;\n\ntype DefaultData<V> =  object | ((this: V) => object);\ntype DefaultProps = Record<string, any>;\ntype DefaultMethods<V> =  { [key: string]: (this: V, ...args: any[]) => any };\ntype DefaultHooks<V> =  { [key: string]: (this: V, ...args: any[]) => any };\ntype DefaultComputed = { [key: string]: any };\n\n\n\nexport interface AppOptions<\n  A extends WepyApp,\n  Hooks=DefaultHooks<A>> extends wepy.App.AppInstance {\n    hooks?: Hooks;\n}\n\nexport interface ComponentOptions<\n  V extends WepyInstace,\n  Data=DefaultData<V>,\n  Methods=DefaultMethods<V>,\n  Hooks=DefaultHooks<V>,\n  Computed=DefaultComputed,\n  PropsDef=PropsDefinition<DefaultProps>,\n  Props=DefaultProps> extends wepy.Page.PageInstance {\n  data?: Data;\n  props?: PropsDef;\n  propsData?: object;\n  hooks?: Hooks;\n  computed?: Accessors<Computed>;\n  methods?: Methods;\n  watch?: Record<string, WatchOptionsWithHandler<any> | WatchHandler<any> | string>;\n\n  relations?: Record<string, any>;\n\n  el?: Element | string;\n  template?: string;\n  // hack is for functional component type inference, should not be used in user code\n\n  created?(): void;\n  attached?(): void;\n  ready?(): void;\n  moved?(): void;\n  detached?(): void;\n\n}\n\nexport interface RenderContext<Props=DefaultProps> {\n  props: Props;\n  slots(): any;\n  listeners: { [key: string]: Function | Function[] };\n  injections: any\n}\n\nexport type Prop<T> = { (): T } | { new(...args: any[]): T & object }\n\nexport type PropType<T> = Prop<T> | Prop<T>[];\n\nexport type PropValidator<T> = PropOptions<T> | PropType<T>;\n\nexport interface PropOptions<T=any> {\n  type?: PropType<T>;\n  required?: boolean;\n  default?: T | null | undefined | (() => T | null | undefined);\n  validator?(value: T): boolean;\n}\n\nexport type RecordPropsDefinition<T> = {\n  [K in keyof T]: PropValidator<T[K]>\n}\nexport type ArrayPropsDefinition<T> = (keyof T)[];\nexport type PropsDefinition<T> = ArrayPropsDefinition<T> | RecordPropsDefinition<T>;\n\nexport interface ComputedOptions<T> {\n  get?(): T;\n  set?(value: T): void;\n  cache?: boolean;\n}\n\nexport type WatchHandler<T> = (val: T, oldVal: T) => void;\n\nexport interface WatchOptions {\n  deep?: boolean;\n  immediate?: boolean;\n}\n\nexport interface WatchOptionsWithHandler<T> extends WatchOptions {\n  handler: WatchHandler<T>;\n}\nexport type InjectKey = string | symbol;\n\nexport type InjectOptions = {\n  [key: string]: InjectKey | { from?: InjectKey, default?: any }\n} | string[];\n"
  },
  {
    "path": "packages/core/types/plugin.d.ts",
    "content": "import { wepy as _wepy } from './wepy';\n\nexport type PluginFunction<T> = (wepy: typeof _wepy, options?: T) => void;\n\nexport interface PluginObject<T> {\n  install: PluginFunction<T>;\n  [key: string]: any;\n}\n"
  },
  {
    "path": "packages/core/types/test/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"es5\",\n    \"experimentalDecorators\": true,\n    \"lib\": [\n      \"dom\",\n      \"es2015\"\n    ],\n    \"types\": [\n      \"miniprogram-api-typings\"\n    ],\n    \"module\": \"commonjs\",\n    \"strict\": true,\n    \"noEmit\": true,\n    \"baseUrl\": \".\",\n    \"paths\": {\n      \"wepy\": [\"../index.d.ts\"]\n    }\n  },\n  \"files\": [\n    \"../index.d.ts\",\n    \"../options.d.ts\",\n    \"../plugin.d.ts\",\n    \"../wepy.d.ts\",\n    \"wepy.test.ts\",\n    \"wepy.app.test.ts\",\n    \"wepy.page.test.ts\",\n    \"wepy.component.test.ts\"\n  ],\n  \"compileOnSave\": false\n}\n"
  },
  {
    "path": "packages/core/types/test/wepy.app.test.ts",
    "content": "import wepy from '../index';\n\nwepy.app({\n  hooks: {\n    'before-setData': function (data) {\n      data.item = 1;\n      return data;\n    }\n  },\n  onLaunch(option) {\n    if (option)\n      console.log(option.query);\n  },\n  onError(e) {\n    console.log(e);\n  }\n})"
  },
  {
    "path": "packages/core/types/test/wepy.component.test.ts",
    "content": "import wepy from '../index';\n\n\nwepy.component({\n\n  relations: {\n    './child': {\n      type: ''\n    }\n  },\n  hooks: {\n    'hi' : function (v: number) {\n      console.log(this);\n    },\n    'before-setData': function (dirty: object): object {\n      console.log('setData dirty: ', dirty);\n      return dirty;\n    }\n  },\n  \n  created() {\n    this.initData();\n  },\n\n  data: {\n    d: 'string'\n  },\n\n  onLoad (option) {\n    console.log(option);\n  },\n\n  onShow() {\n\n  }, \n  \n  methods: {\n    bindtap () {\n    },\n\n    initData () {\n      wx.request({\n        method: 'POST',\n        url: 'http://www.baidu.com'\n      })\n    }\n  }\n});"
  },
  {
    "path": "packages/core/types/test/wepy.page.test.ts",
    "content": "import wepy from '../index';\n\n\nwepy.page({\n  hooks: {\n    'hi' : function (v: number) {\n      console.log(this);\n    },\n    'before-setData': function (dirty: object): object {\n      console.log('setData dirty: ', dirty);\n      return dirty;\n    }\n  },\n  \n  created() {\n    console.log(this);\n  },\n\n  data: {\n    d: 'string'\n  },\n\n  onLoad (option) {\n    console.log(option);\n    this.sleep(10);\n  },\n\n  onShow() {\n\n  }, \n  \n  onPageScroll () {\n\n  },\n\n  onReachBottom () {\n\n  },\n\n  onPullDownRefresh () {\n\n  },\n  onShareAppMessage (): Page.ICustomShareContent {\n    return <Page.ICustomShareContent>{\n      title: 'share title',\n      imageUrl: 'http://www.baidu.com',\n      path: '/a/b/c'\n    }\n  },\n  onShareTimeline (): Page.IAddToFavoritesContent {\n    return <Page.IAddToFavoritesContent>{\n      title: 'share title',\n      imageUrl: 'http://www.baidu.com',\n      query: '/a/b/c'\n    }\n  },\n  onAddToFavorites (): Page.IAddToFavoritesContent {\n    return <Page.IAddToFavoritesContent>{\n      title: 'share title',\n      imageUrl: 'http://www.baidu.com',\n      query: '/a/b/c'\n    }\n  },\n\n  methods: {\n    bindtap () {\n    },\n\n    sleep (s: number) {\n      console.log(this.testAsync);\n      return new Promise((resolve) => {\n        setTimeout(() => {\n          resolve('promise resolved')\n        }, s * 1000)\n      })\n    },\n\n    async testAsync () {\n      console.log(this);\n      let d = await this.sleep(3);\n    }\n  }\n});"
  },
  {
    "path": "packages/core/types/test/wepy.test.ts",
    "content": "import wepy from '../index';\nimport { WepyInstace } from '../wepy';\nimport { PluginObject, PluginFunction } from '../plugin';\n\nlet eventBus = new wepy();\n\neventBus.$on('test', function(a: any, b: any, c: any) {\n  console.log(a, b, c)\n});\n\neventBus.$emit('test', 1, 2, 3);\n\nconst installer: PluginFunction<Array<string>> = function (wepy, option) {\n  if (option) {\n    console.log(option.length);\n  }\n};\n\nconst plugin: PluginObject<Array<string>> = {\n  install: installer,\n  useDefinedMethod (): string {\n    return '' + Math.random();\n  }\n}\n\nwepy.mixin({\n  data: {\n    a: 1\n  },\n  methods: {\n    commonFunc () {\n      console.log(this);\n    }\n  }\n});\n\n\nwepy.nextTick().then(res => {\n  console.log(res);\n});\n\nwepy.nextTick(function (): void {\n  console.log(this);\n})\nwepy.nextTick(function (): void {\n  console.log(this.ctx === 'efc');\n}, { ctx: 'abc'})"
  },
  {
    "path": "packages/core/types/tsconfig.json",
    "content": "{\r\n    \"compilerOptions\": {\r\n        \"strict\": true,\r\n        \"lib\": [\r\n            \"es2015\", \"dom\"\r\n        ],\r\n        \"types\": [\r\n            \"miniprogram-api-typings\"\r\n        ]\r\n    },\r\n    \"include\": [\r\n        \"./*.ts\"\r\n    ]\r\n}"
  },
  {
    "path": "packages/core/types/typings.json",
    "content": "{\n  \"name\": \"wepy\",\n  \"main\": \"index.d.ts\"\n}\n"
  },
  {
    "path": "packages/core/types/wepy.d.ts",
    "content": "import {\n  ComponentOptions,\n  WatchOptionsWithHandler,\n  WatchHandler,\n  RecordPropsDefinition,\n  ThisTypedComponentOptionsWithArrayProps,\n  ThisTypedComponentOptionsWithRecordProps,\n  WatchOptions,\n  AppOptions,\n} from \"./options\";\nimport { PluginFunction, PluginObject } from \"./plugin\";\n\nexport interface Base {\n  new (): Base;\n\n  $set: (target: string, key: string, value: string) => void;\n  $delete: (target: string, key: string) => void;\n  $on(event: string | string[] | Record<string, Function>, callback?: Function): this;\n  $off(event: string | string[] | Record<string, Function>, callback?: Function): this;\n  $emit(event: string, ...args: any[]): this;\n}\n\nexport interface WepyApp extends Base {\n}\n\nexport interface WepyComponent extends Base {\n  readonly $refs: { [ key: string ]: WepyComponent | WepyComponent[] };\n\n  $watch(\n    expOrFn: string,\n    callback: (this: this, n: any, o: any) => void,\n  ): (() => void);\n  $watch<T>(\n    expOrFn: (this: this) => T,\n    callback: (this: this, n: T, o: T) => void,\n  ): (() => void);\n  $trigger(event: string, data: any, option: object): this;\n}\nexport interface WepyPage extends WepyComponent {\n  $launch(url: string, params: object): void;\n  $navigate(url: string, params: object): void;\n  $redirect(url: string, params: object): void;\n  $back(p: number | { delta: number }): void;\n  $route(type: string, url: string, params: object): void;\n}\n\nexport type WepyInstace = WepyPage | WepyComponent;\n\nexport interface Vue {\n  /*\n  readonly $options: ComponentOptions<Vue>;\n  readonly $parent: Vue;\n  readonly $root: Vue;\n  readonly $children: Vue[];\n  readonly $refs: { [key: string]: Vue | Element | Vue[] | Element[] };\n  */\n  readonly $data: Record<string, any>;\n  readonly $props: Record<string, any>;\n  readonly $ssrContext: any;\n  readonly $attrs: Record<string, string>;\n  readonly $listeners: Record<string, Function | Function[]>;\n\n  $mount(elementOrSelector?: Element | string, hydrating?: boolean): this;\n  $forceUpdate(): void;\n  $destroy(): void;\n  $set: (traget: object, key: string, value: string) => void;\n  $delete: (traget: object, key: string) => void;\n  $on(event: string | string[] | Record<string, Function>, callback?: Function): this;\n  $off(event: string | string[] | Record<string, Function>, callback?: Function): this;\n  $emit(event: string, ...args: any[]): this;\n  $watch(\n    expOrFn: string,\n    callback: (this: this, n: any, o: any) => void,\n    options?: WatchOptions\n  ): (() => void);\n  $watch<T>(\n    expOrFn: (this: this) => T,\n    callback: (this: this, n: T, o: T) => void,\n    options?: WatchOptions\n  ): (() => void);\n  $on(event: string | string[], callback: Function): this;\n  $once(event: string | string[], callback: Function): this;\n  $off(event?: string | string[], callback?: Function): this;\n  $emit(event: string, ...args: any[]): this;\n  $nextTick(callback: (this: this) => void): void;\n  $nextTick(): Promise<void>;\n}\n\nexport type CombineWepyInstance<Instance extends WepyInstace, Data, Methods, Hooks, Computed, Props> =  Data & Methods & Hooks & Computed & Props & Instance;\n\nexport interface WepyConfiguration {\n  silent: boolean;\n}\n\nexport interface WepyConstructor<V extends WepyInstace = WepyInstace, P extends WepyPage = WepyPage, C extends WepyComponent = WepyComponent, A extends WepyApp = WepyApp> {\n  new (): Base;\n\n  app(options: AppOptions<WepyApp>): void;\n\n  page<Data, Methods, Hooks, Computed, PropNames extends string = never>(options?: ThisTypedComponentOptionsWithArrayProps<P, Data, Methods, Hooks, Computed, PropNames>): wepy.Page.PageInstance;\n  page<Data, Methods, Hooks, Computed, Props>(options?: ThisTypedComponentOptionsWithRecordProps<P, Data, Methods, Hooks, Computed, Props>): wepy.Page.PageInstance;\n  page(options?: ComponentOptions<P>): wepy.Page.PageInstance;\n\n  component<Data, Methods, Hooks, Computed, PropNames extends string = never>(options?: ThisTypedComponentOptionsWithArrayProps<C, Data, Methods, Hooks, Computed, PropNames>): wepy.Page.PageInstance;\n  component<Data, Methods, Hooks, Computed, Props>(options?: ThisTypedComponentOptionsWithRecordProps<C, Data, Methods, Hooks, Computed, Props>): wepy.Page.PageInstance;\n  component(options?: ComponentOptions<C>): wepy.Page.PageInstance;\n\n  nextTick<T>(callback: (this: T) => void, context?: T): void;\n  nextTick(): Promise<void>\n  set<T>(object: object, key: string | number, value: T): T;\n  set<T>(array: T[], key: number, value: T): T;\n  delete(object: object, key: string | number): void;\n  delete<T>(array: T[], key: number): void;\n\n  use<T>(plugin: PluginObject<T> | PluginFunction<T>, options?: T): WepyConstructor<V>;\n  use(plugin: PluginObject<any> | PluginFunction<any>, ...options: any[]): WepyConstructor<V>;\n  mixin(mixin: WepyConstructor | ComponentOptions<WepyPage>): WepyConstructor<V>;\n\n  observable<T>(obj: T): T;\n\n  config: WepyConfiguration;\n  version: string;\n}\n\nexport const wepy: WepyConstructor;\n"
  },
  {
    "path": "packages/core/types/wx/index.d.ts",
    "content": "/*! *****************************************************************************\nCopyright (c) 2018 Tencent, Inc. All rights reserved. \n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n***************************************************************************** */\n\n/// <reference path=\"lib.wx.api.d.ts\" />\n/// <reference path=\"lib.wx.app.d.ts\" />\n/// <reference path=\"lib.wx.behavior.d.ts\" />\n/// <reference path=\"lib.wx.cloud.d.ts\" />\n/// <reference path=\"lib.wx.component.d.ts\" />\n/// <reference path=\"lib.wx.page.d.ts\" />"
  },
  {
    "path": "packages/core/types/wx/lib.wx.api.d.ts",
    "content": "/*! *****************************************************************************\nCopyright (c) 2018 Tencent, Inc. All rights reserved. \n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n***************************************************************************** */\n\n// @ts-ignore\n/// <reference path=\"../../node_modules/miniprogram-api-typings/types/wx/lib.wx.api.d.ts\" />\n// @ts-ignore\n/// <reference path=\"../../../node_modules/miniprogram-api-typings/types/wx/lib.wx.api.d.ts\" />"
  },
  {
    "path": "packages/core/types/wx/lib.wx.app.d.ts",
    "content": "/*! *****************************************************************************\nCopyright (c) 2018 Tencent, Inc. All rights reserved. \n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n***************************************************************************** */\n\n// @ts-ignore\n/// <reference path=\"../../node_modules/miniprogram-api-typings/types/wx/lib.wx.app.d.ts\" />\n// @ts-ignore\n/// <reference path=\"../../../node_modules/miniprogram-api-typings/types/wx/lib.wx.app.d.ts\" />\n\ndeclare namespace wepy {\n  namespace App {\n    interface AppInstance<T extends WechatMiniprogram.IAnyObject = {}> {   \n      onLaunch?(options?: WechatMiniprogram.App.LaunchShowOption): void;\n    \n      onShow?(options?: WechatMiniprogram.App.LaunchShowOption): void;\n      \n      onHide?(): void;\n      \n      onError?(error?: string): void;\n\n      onPageNotFound?(options?: WechatMiniprogram.App.PageNotFoundOption): void;\n    }\n  \n    interface AppConstructor {\n      <T extends WechatMiniprogram.IAnyObject & AppInstance>(\n        options: AppInstance<T> & T\n      ): void\n    }\n  }\n}"
  },
  {
    "path": "packages/core/types/wx/lib.wx.behavior.d.ts",
    "content": "// @ts-ignore\n/// <reference path=\"../../node_modules/miniprogram-api-typings/types/wx/lib.wx.behavior.d.ts\" />\n// @ts-ignore\n/// <reference path=\"../../../node_modules/miniprogram-api-typings/types/wx/lib.wx.app.d.ts\" />"
  },
  {
    "path": "packages/core/types/wx/lib.wx.cloud.d.ts",
    "content": "/*! *****************************************************************************\nCopyright (c) 2018 Tencent, Inc. All rights reserved. \n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n***************************************************************************** */\n\n// @ts-ignore\n/// <reference path=\"../../node_modules/miniprogram-api-typings/types/wx/lib.wx.cloud.d.ts\" />\n// @ts-ignore\n/// <reference path=\"../../../node_modules/miniprogram-api-typings/types/wx/lib.wx.cloud.d.ts\" />"
  },
  {
    "path": "packages/core/types/wx/lib.wx.component.d.ts",
    "content": "// @ts-ignore\n/// <reference path=\"../../node_modules/miniprogram-api-typings/types/wx/lib.wx.component.d.ts\" />\n// @ts-ignore\n/// <reference path=\"../../node_modules/miniprogram-api-typings/types/wx/lib.wx.component.d.ts\" />"
  },
  {
    "path": "packages/core/types/wx/lib.wx.page.d.ts",
    "content": "/*! *****************************************************************************\nCopyright (c) 2018 Tencent, Inc. All rights reserved. \n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n***************************************************************************** */\n\n// @ts-ignore\n/// <reference path=\"../../node_modules/miniprogram-api-typings/types/wx/lib.wx.page.d.ts\" />\n// @ts-ignore\n/// <reference path=\"../../../node_modules/miniprogram-api-typings/types/wx/lib.wx.page.d.ts\" />\n\ndeclare namespace wepy {\n  namespace Page {\n    interface PageInstanceBaseProps<D extends WechatMiniprogram.IAnyObject = any> {\n    /** 页面的初始数据\n     * \n     * `data` 是页面第一次渲染使用的**初始数据**。\n     * \n     * 页面加载时，`data` 将会以`JSON`字符串的形式由逻辑层传至渲染层，因此`data`中的数据必须是可以转成`JSON`的类型：字符串，数字，布尔值，对象，数组。\n     * \n     * 渲染层可以通过 `WXML` 对数据进行绑定。\n    */\n    data?: D\n\n    /** `setData` 函数用于将数据从逻辑层发送到视图层（异步），同时改变对应的 `this.data` 的值（同步）。\n     *\n     * **注意：**\n     *\n     * 1. **直接修改 this.data 而不调用 this.setData 是无法改变页面的状态的，还会造成数据不一致**。\n     * 1. 仅支持设置可 JSON 化的数据。\n     * 1. 单次设置的数据不能超过1024kB，请尽量避免一次设置过多的数据。\n     * 1. 请不要把 data 中任何一项的 value 设为 `undefined` ，否则这一项将不被设置并可能遗留一些潜在问题。\n     */\n\n    setData?<K extends keyof D>(\n      /** 这次要改变的数据\n       *\n       * 以 `key: value` 的形式表示，将 `this.data` 中的 `key` 对应的值改变成 `value`。\n       *\n       * 其中 `key` 可以以数据路径的形式给出，支持改变数组中的某一项或对象的某个属性，如 `array[2].message`，`a.b.c.d`，并且不需要在 this.data 中预先定义。\n       */\n      data: D | Pick<D, K> | WechatMiniprogram.IAnyObject,\n      /** setData引起的界面更新渲染完毕后的回调函数，最低基础库： `1.5.0` */\n      callback?: () => void\n    ): void\n\n    /** 到当前页面的路径，类型为`String`。最低基础库： `1.2.0` */\n    route?: string\n    }\n  \n    interface PageInstance<D extends WechatMiniprogram.IAnyObject = any, T extends WechatMiniprogram.IAnyObject = any> extends PageInstanceBaseProps<D> {\n      onLoad?(query?: { [queryKey: string]: string }): void;\n      \n      onShow?(): void;\n      \n      onReady?(): void;\n      \n      onHide?(): void;\n\n      onUnload?(): void;\n\n      onPullDownRefresh?(): void;\n      \n      onReachBottom?(): void\n      \n      onShareAppMessage?(options?: WechatMiniprogram.Page.IShareAppMessageOption): WechatMiniprogram.Page.ICustomShareContent\n\n      onShareTimeline?(): WechatMiniprogram.Page.IAddToFavoritesContent\n\n      onAddToFavorites?(): WechatMiniprogram.Page.IAddToFavoritesContent\n      \n      onPageScroll?(options?: WechatMiniprogram.Page.IPageScrollOption): void\n  \n      onTabItemTap?(options?: WechatMiniprogram.Page.ITabItemTapOption): void\n    }\n  \n    interface PageConstructor {\n      <D extends WechatMiniprogram.IAnyObject, T extends WechatMiniprogram.IAnyObject & PageInstance>(\n        options: PageInstance<D, T> & T\n      ): void\n    }\n  \n    interface GetCurrentPages {\n      <D extends WechatMiniprogram.IAnyObject = {}, T extends WechatMiniprogram.IAnyObject = {}>(): (PageInstance<D, T> & T)[]\n    }\n  }\n}"
  },
  {
    "path": "packages/core/weapp/apis/index.js",
    "content": "import { use } from './use';\nimport { mixin } from './mixin';\nimport { set, del, observe } from '../observer/index';\nimport { renderNextTick } from '../util/next-tick';\nimport { app, page, component } from '../native/index';\n\nexport function initGlobalAPI(wepy) {\n  wepy.use = use;\n  wepy.mixin = mixin;\n\n  wepy.set = function(target, key, val) {\n    set.apply(wepy, [undefined, target, key, val]);\n  };\n\n  wepy.delete = del;\n\n  wepy.observe = observe;\n\n  wepy.nextTick = renderNextTick;\n\n  wepy.app = app;\n  wepy.page = page;\n  wepy.component = component;\n\n  return wepy;\n}\n"
  },
  {
    "path": "packages/core/weapp/apis/mixin.js",
    "content": "import $global from '../global';\n\nexport function mixin(options = {}) {\n  $global.mixin = ($global.mixin || []).concat(options);\n}\n"
  },
  {
    "path": "packages/core/weapp/apis/use.js",
    "content": "import { isFunc } from '../../shared/index';\n\nexport function use(plugin, ...args) {\n  if (plugin.installed) {\n    return this;\n  }\n\n  let install = plugin.install || plugin;\n\n  if (isFunc(install)) {\n    install.apply(plugin, [this].concat(args));\n  }\n\n  plugin.installed = 1;\n}\n"
  },
  {
    "path": "packages/core/weapp/class/Base.js",
    "content": "import { isArr, isStr, isObj, toArray, handleError } from './../util/index';\nimport { set, del } from '../observer/index';\n\nexport default class Base {\n  constructor() {\n    this._events = {};\n    this._watchers = [];\n  }\n\n  $set(target, key, val) {\n    return set(this, target, key, val);\n  }\n\n  $delete(target, key) {\n    return del(target, key);\n  }\n\n  $on(event, fn) {\n    if (isArr(event)) {\n      event.forEach(item => {\n        if (isStr(item)) {\n          this.$on(item, fn);\n        } else if (isObj(item)) {\n          this.$on(item.event, item.fn);\n        }\n      });\n    } else {\n      (this._events[event] || (this._events[event] = [])).push(fn);\n    }\n    return this;\n  }\n\n  $once() {}\n\n  $off(event, fn) {\n    if (!event && !fn) {\n      this._events = Object.create(null);\n      return this;\n    }\n\n    if (isArr(event)) {\n      event.forEach(item => {\n        if (isStr(item)) {\n          this.$off(item, fn);\n        } else if (isObj(item)) {\n          this.$off(item.event, item.fn);\n        }\n      });\n      return this;\n    }\n    if (!this._events[event]) return this;\n\n    if (!fn) {\n      this._events[event] = null;\n      return this;\n    }\n\n    if (fn) {\n      let fns = this._events[event];\n      let i = fns.length;\n      while (i--) {\n        let tmp = fns[i];\n        if (tmp === fn || tmp.fn === fn) {\n          fns.splice(i, 1);\n          break;\n        }\n      }\n    }\n    return this;\n  }\n\n  $emit(event) {\n    let vm = this;\n    let lowerCaseEvent = event.toLowerCase();\n    let fns = this._events[event] || [];\n    if (lowerCaseEvent !== event && vm._events[lowerCaseEvent]) {\n      // TODO: handler warn\n    }\n    let args = toArray(arguments, 1);\n    fns.forEach(fn => {\n      try {\n        fn.apply(this, args);\n      } catch (e) {\n        handleError(e, vm, `event handler for \"${event}\"`);\n      }\n    });\n    return this;\n  }\n}\n"
  },
  {
    "path": "packages/core/weapp/class/Dirty.js",
    "content": "import { getPathMap } from '../observer/observerPath';\n\nexport default class Dirty {\n  constructor(type) {\n    this.reset();\n\n    // path||key\n    this.type = type || 'path';\n  }\n\n  push(key, path, keyValue, pathValue) {\n    if (pathValue === undefined) {\n      return;\n    }\n    this._keys[key] = keyValue;\n    this._path[path] = pathValue;\n    this._length++;\n  }\n\n  pop() {\n    let data = Object.create(null);\n    if (this.type === 'path') {\n      data = this._path;\n    } else if (this.type === 'key') {\n      data = this._keys;\n    }\n    this.reset();\n    return data;\n  }\n\n  get(type) {\n    return type === 'path' ? this._path : this._keys;\n  }\n\n  /**\n   * Set dirty from a ObserverPath\n   */\n  set(op, key, value) {\n    let pathMap;\n    let pathKeys;\n    // eslint-disable-next-line eqeqeq\n    if (key != null) {\n      const { combinePathKeys, combinePathMap } = getPathMap(key, op.pathKeys, op.pathMap);\n      pathKeys = combinePathKeys;\n      pathMap = combinePathMap;\n    } else {\n      pathKeys = op.pathKeys;\n      pathMap = op.pathMap;\n    }\n    /**\n     * 出于性能考虑，使用 usingComponents 时， setData 内容不会被直接深复制，\n     * 即 this.setData({ field: obj }) 后 this.data.field === obj 。\n     * 因此不需要所有 path 都 setData 。\n     */\n    const { root, path } = pathMap[pathKeys[0]];\n    this.push(root, path, root === path ? value : op.ob.vm[root], value);\n  }\n\n  reset() {\n    this._keys = {};\n    this._path = {};\n    this._length = 0;\n    return this;\n  }\n\n  length() {\n    return this._length;\n  }\n}\n"
  },
  {
    "path": "packages/core/weapp/class/Event.js",
    "content": "export default class Event {\n  constructor(e) {\n    const { detail, target, currentTarget } = e;\n    this.$wx = e;\n    this.type = e.type;\n    this.timeStamp = e.timeStamp;\n    if (detail) {\n      this.x = detail.x;\n      this.y = detail.y;\n    }\n\n    this.target = target;\n    this.currentTarget = currentTarget;\n    this.touches = e.touches;\n    this.changedTouches = e.changedTouches;\n  }\n}\n"
  },
  {
    "path": "packages/core/weapp/class/WepyApp.js",
    "content": "import Base from './Base';\n\nexport default class WepyApp extends Base {\n  constructor() {\n    super();\n  }\n}\n"
  },
  {
    "path": "packages/core/weapp/class/WepyComponent.js",
    "content": "import Base from './Base';\nimport Watcher from '../observer/watcher';\nimport { isArr, isPlainObject } from '../../shared/index';\n\nimport { renderNextTick } from '../util/next-tick';\n\nexport default class WepyComponent extends Base {\n  $watch(expOrFn, cb, options) {\n    let vm = this;\n    if (isArr(cb)) {\n      cb.forEach(handler => {\n        this.$watch(expOrFn, handler, options);\n      });\n    }\n    if (isPlainObject(cb)) {\n      let handler = cb;\n      options = handler;\n      handler = handler.handler;\n      if (typeof handler === 'string') handler = this[handler];\n      return this.$watch(expOrFn, handler, options);\n    }\n\n    options = options || {};\n    options.user = true;\n    let watcher = new Watcher(vm, expOrFn, cb, options);\n    if (options.immediate) {\n      cb.call(vm, watcher.value);\n    }\n    return function unwatchFn() {\n      watcher.teardown();\n    };\n  }\n\n  $forceUpdate() {\n    if (this._watcher) {\n      this._watcher.update();\n    }\n  }\n\n  $emit(event, ...args) {\n    const fns = this._events[event];\n\n    if (fns) {\n      super.$emit.apply(this, arguments);\n    } else {\n      this.$wx.triggerEvent(event, { arguments: args });\n    }\n\n    return this;\n  }\n\n  $trigger(event, data, option) {\n    this.$wx.triggerEvent(event, { arguments: [data] }, option);\n  }\n}\n\nWepyComponent.prototype.$nextTick = renderNextTick;\n"
  },
  {
    "path": "packages/core/weapp/class/WepyConstructor.js",
    "content": "import WepyComponent from './WepyComponent';\nimport { initData } from '../init/data';\nimport { initWatch } from '../init/watch';\nimport { initComputed } from '../init/computed';\n\nexport default class WepyConstructor extends WepyComponent {\n  constructor(opt = {}) {\n    super();\n    let vm = new WepyComponent();\n\n    // Only need data and watchers for a empty WepyComponent\n    if (opt.data) {\n      initData(vm, opt.data);\n    }\n    initWatch(vm);\n\n    initComputed(vm, opt.computed);\n    return vm;\n  }\n}\n"
  },
  {
    "path": "packages/core/weapp/class/WepyPage.js",
    "content": "import WepyComponent from './WepyComponent';\nimport { isStr, isNum, isObj, isUndef, isFunc } from '../../shared/index';\n\nexport default class WepyPage extends WepyComponent {\n  $launch(url, params) {\n    this.$route('reLaunch', url, params);\n  }\n  $navigate(url, params) {\n    this.$route('navigate', url, params);\n  }\n\n  $redirect(url, params) {\n    this.$route('redirect', url, params);\n  }\n\n  $back(p = {}) {\n    if (isNum(p)) p = { delta: p };\n\n    if (!p.delta) p.delta = 1;\n\n    return wx.navigateBack(p);\n  }\n\n  $route(type, url, params = {}) {\n    let wxparams;\n    if (isStr(url)) {\n      let paramsList = [];\n      if (isObj(params)) {\n        for (let k in params) {\n          if (!isUndef(params[k])) {\n            paramsList.push(`${k}=${encodeURIComponent(params[k])}`);\n          }\n        }\n      }\n      if (paramsList.length) url = url + '?' + paramsList.join('&');\n\n      wxparams = { url: url };\n    } else {\n      wxparams = url;\n    }\n    let fn = wx[type] || wx[type + 'To'];\n    if (isFunc(fn)) {\n      return fn(wxparams);\n    }\n  }\n}\n"
  },
  {
    "path": "packages/core/weapp/config.js",
    "content": "import {\n  WEAPP_LIFECYCLE,\n  WEAPP_APP_LIFECYCLE,\n  WEAPP_PAGE_LIFECYCLE,\n  WEAPP_COMPONENT_LIFECYCLE\n} from '../shared/constants';\n\nexport const config = {\n  optionMergeStrategies: {},\n  constants: {\n    WEAPP_LIFECYCLE,\n    WEAPP_APP_LIFECYCLE,\n    WEAPP_PAGE_LIFECYCLE,\n    WEAPP_COMPONENT_LIFECYCLE\n  }\n};\n"
  },
  {
    "path": "packages/core/weapp/dispatcher/index.js",
    "content": "import Event from '../class/Event';\nimport { callUserHook } from '../init/hooks';\nimport { isFunc, camelize } from './../util/index';\n\n/**\n * Transform wxml data-xx params to an array\n */\nfunction transformParams(dataset, type, hasModel = false) {\n  let i = 0;\n  let params = [];\n  let modelParams = [];\n\n  let noParams = false;\n  let noModelParams = !hasModel;\n\n  const camelizedType = camelize(type);\n  while (i++ < 26 && (!noParams || !noModelParams)) {\n    let alpha = String.fromCharCode(64 + i);\n    if (!noParams) {\n      let key = 'wpy' + camelizedType + alpha;\n      if (!(key in dataset)) {\n        // it can be undefined;\n        noParams = true;\n      } else {\n        params.push(dataset[key]);\n      }\n    }\n    if (!noModelParams && hasModel) {\n      let modelKey = 'model' + alpha;\n      if (!(modelKey in dataset)) {\n        noModelParams = true;\n      } else {\n        modelParams.push(dataset[modelKey]);\n      }\n    }\n  }\n\n  return {\n    handler: params,\n    model: modelParams\n  };\n}\n\nexport const dispatcher = function(e) {\n  const vm = this.$wepy;\n  const type = e.type;\n  // touchstart do not have currentTarget\n  const dataset = (e.currentTarget || e.target).dataset || {};\n  const evtid = dataset.wpyEvt;\n  const modelId = dataset.modelId;\n  const rel = vm.$rel || {};\n  const handler = rel.handlers && rel.handlers[evtid] && rel.handlers[evtid][type];\n  const model = rel.models && rel.models[modelId];\n\n  if (!handler && !model) {\n    return;\n  }\n\n  const params = transformParams(dataset, type, !!model);\n\n  // Call model method\n  if (model && type === model.type && isFunc(model.handler)) {\n    model.handler.call(vm, e.detail.value, params.model);\n  }\n\n  // Call handler method\n  if (isFunc(handler)) {\n    const $event = new Event(e);\n    const paramsWithEvent = params.handler.concat($event);\n    let args = (e.detail && e.detail.arguments) || [];\n\n    const hookRes = callUserHook(vm, 'before-event', {\n      event: $event,\n      params: paramsWithEvent,\n      args: args\n    });\n\n    if (hookRes === false) {\n      // Event cancelled.\n      return;\n    }\n    return handler.apply(vm, paramsWithEvent);\n  } else if (!model) {\n    throw new Error('Unrecognized event');\n  }\n};\n"
  },
  {
    "path": "packages/core/weapp/global.js",
    "content": "export default Object.create(null);\n"
  },
  {
    "path": "packages/core/weapp/init/computed.js",
    "content": "import Watcher from './../observer/watcher';\nimport Dep from './../observer/dep';\nimport { sharedPropertyDefinition } from './data';\n\nfunction createComputedGetter(key) {\n  return function computedGetter() {\n    let watcher = this._computedWatchers && this._computedWatchers[key];\n    if (watcher) {\n      watcher.key = key;\n      if (watcher.dirty) {\n        watcher.evaluate();\n      }\n      if (Dep.target) {\n        watcher.depend();\n      }\n      return watcher.value;\n    }\n  };\n}\n\n/*\n * init computed\n */\nexport function initComputed(vm, computed) {\n  if (!computed) {\n    return;\n  }\n  let watchers = (vm._computedWatchers = Object.create(null));\n  let computedWatcherOptions = { computed: true };\n\n  Object.keys(computed).forEach(key => {\n    let def = computed[key];\n    let getter = typeof def === 'object' ? def.get : def;\n\n    if (!getter || typeof getter !== 'function') {\n      // eslint-disable-next-line\n      console.error(`Getter is missing for computed property \"${key}\"`);\n    }\n\n    // push to dirty after dep called.\n    watchers[key] = new Watcher(\n      vm,\n      getter || function() {},\n      function() {\n        // evaluate will set dirty\n        // vm.$dirty.push(key, key, newv);\n      },\n      computedWatcherOptions\n    );\n\n    if (typeof def === 'function') {\n      sharedPropertyDefinition.get = createComputedGetter(key);\n      sharedPropertyDefinition.set = function() {};\n    } else {\n      sharedPropertyDefinition.get = def.cache !== false ? createComputedGetter(key) : def.get;\n      sharedPropertyDefinition.set = def.set;\n    }\n\n    Object.defineProperty(vm, key, sharedPropertyDefinition);\n  });\n}\n"
  },
  {
    "path": "packages/core/weapp/init/data.js",
    "content": "import { observe } from './../observer/index';\nimport { noop, clone } from './../../shared/index';\n\nexport const sharedPropertyDefinition = {\n  enumerable: true,\n  configurable: true,\n  get: noop,\n  set: noop\n};\n\nexport function proxy(target, sourceKey, key) {\n  sharedPropertyDefinition.get = function proxyGetter() {\n    return this[sourceKey][key];\n  };\n  sharedPropertyDefinition.set = function proxySetter(val) {\n    this[sourceKey][key] = val;\n  };\n  Object.defineProperty(target, key, sharedPropertyDefinition);\n}\n\n/*\n * patch data option\n */\nexport function patchData(output, data) {\n  if (!data) {\n    data = {};\n  }\n  output.data = data;\n}\n\n/*\n * init data\n */\nexport function initData(vm, data) {\n  if (!data) {\n    data = {};\n  }\n  let _data;\n  if (typeof data === 'function') {\n    _data = data.call(vm);\n  } else {\n    _data = clone(data);\n  }\n  vm._data = _data;\n  Object.keys(_data).forEach(key => {\n    proxy(vm, '_data', key);\n  });\n\n  observe({\n    vm: vm,\n    key: '',\n    value: _data,\n    parent: '',\n    root: true\n  });\n  //observe(vm, _data, null, true);\n}\n"
  },
  {
    "path": "packages/core/weapp/init/hooks.js",
    "content": "import { isFunc, isUndef, warn } from './../util/index';\n\nexport function callUserHook(vm, hookName, arg) {\n  const pageHook = vm.hooks ? vm.hooks[hookName] : null;\n  const appHook = vm.$app && vm.$app.hooks ? vm.$app.hooks[hookName] : null;\n\n  if (!vm.$app) {\n    warn('$app is not initialized in this Component', vm);\n  }\n\n  let result = arg;\n\n  // First run page hook, and then run app hook\n  // Pass page hook result to app hook\n  // If return undefined, then return default argument\n  [pageHook, appHook].forEach(fn => {\n    if (isFunc(fn)) {\n      result = fn.call(vm, result);\n      if (isUndef(result)) {\n        result = arg;\n      }\n    }\n  });\n\n  return result;\n}\n\nexport function initHooks(vm, hooks = {}) {\n  vm.hooks = hooks;\n}\n"
  },
  {
    "path": "packages/core/weapp/init/index.js",
    "content": "export * from './data';\nexport * from './computed';\nexport * from './lifecycle';\nexport * from './methods';\nexport * from './watch';\nexport * from './props';\nexport * from './mixins';\nexport * from './hooks';\nexport * from './relations';\n"
  },
  {
    "path": "packages/core/weapp/init/lifecycle.js",
    "content": "import WepyApp from '../class/WepyApp';\nimport WepyPage from '../class/WepyPage';\nimport WepyComponent from '../class/WepyComponent';\nimport { initHooks } from './hooks';\nimport { initProps } from './props';\nimport { initWatch } from './watch';\nimport { initRender } from './render';\nimport { initData } from './data';\nimport { initComputed } from './computed';\nimport { initMethods } from './methods';\nimport { isArr, isFunc, isStr } from '../../shared/index';\nimport Dirty from '../class/Dirty';\nimport {\n  WEAPP_APP_LIFECYCLE,\n  WEAPP_PAGE_LIFECYCLE,\n  WEAPP_COMPONENT_LIFECYCLE,\n  WEAPP_COMPONENT_PAGE_LIFECYCLE\n} from '../../shared/index';\nimport { warn } from '../util/index';\n\nlet comid = 0;\nlet app;\n\nconst callUserMethod = function(vm, userOpt, method, args) {\n  let result;\n  let methods = userOpt[method];\n  if (isFunc(methods)) {\n    result = userOpt[method].apply(vm, args);\n  } else if (isArr(methods)) {\n    for (let i in methods) {\n      if (isFunc(methods[i])) {\n        result = methods[i].apply(vm, args);\n      }\n    }\n  }\n  return result;\n};\n\nexport const getLifeCycle = (defaultLifecycle, rel, type) => {\n  let lifecycle = defaultLifecycle.concat([]);\n  if (rel && rel.lifecycle && rel.lifecycle[type]) {\n    let userDefinedLifecycle = [];\n    const modifiedLifeCycles = rel.lifecycle[type];\n\n    if (isStr(modifiedLifeCycles) || isArr(modifiedLifeCycles)) {\n      userDefinedLifecycle = userDefinedLifecycle.concat(modifiedLifeCycles);\n      userDefinedLifecycle.forEach(u => {\n        if (lifecycle.indexOf(u) > -1) {\n          warn(`'${u}' is already implemented in current version, please remove it from your lifecycle config`);\n        } else {\n          lifecycle.push(u);\n        }\n      });\n    } else if (isFunc(modifiedLifeCycles)) {\n      lifecycle = modifiedLifeCycles.call(null, lifecycle);\n    }\n  }\n  return lifecycle;\n};\n\n/*\n * patch app lifecyle\n */\nexport function patchAppLifecycle(appConfig, options, rel = {}) {\n  appConfig.onLaunch = function(...args) {\n    let vm = new WepyApp();\n    app = vm;\n    vm.$options = options;\n    vm.$route = null; // default route is null\n    vm.$rel = rel;\n\n    vm.$wx = this;\n    this.$wepy = vm;\n\n    initHooks(vm, options.hooks);\n\n    initMethods(vm, options.methods);\n\n    return callUserMethod(vm, vm.$options, 'onLaunch', args);\n  };\n\n  let lifecycle = getLifeCycle(WEAPP_APP_LIFECYCLE, rel, 'app');\n\n  lifecycle.forEach(k => {\n    // it's not defined already && user defined it && it's an array or function\n    if (!appConfig[k] && options[k] && (isFunc(options[k]) || isArr(options[k]))) {\n      appConfig[k] = function(...args) {\n        return callUserMethod(app, app.$options, k, args);\n      };\n    }\n  });\n}\n\nexport function patchLifecycle(output, options, rel, isComponent) {\n  const initClass = isComponent ? WepyComponent : WepyPage;\n  const initLifecycle = function(...args) {\n    let vm = new initClass();\n\n    vm.$dirty = new Dirty('path');\n    vm.$children = [];\n    vm.$refs = {};\n\n    this.$wepy = vm;\n    vm.$wx = this;\n    vm.$is = this.is;\n    vm.$options = options;\n    vm.$rel = rel;\n    vm._watchers = [];\n    if (!isComponent) {\n      vm.$root = vm;\n    }\n    if (app) {\n      vm.$app = app;\n    }\n    if (this.is === 'custom-tab-bar/index') {\n      vm.$app = app;\n      vm.$parent = app;\n    }\n\n    vm.$id = ++comid + (isComponent ? '.1' : '.0');\n    if (!vm.$app) {\n      // vm.$app = $global.$app;\n    }\n\n    callUserMethod(vm, vm.$options, 'beforeCreate', args);\n\n    initHooks(vm, options.hooks);\n\n    initProps(vm, output.properties);\n\n    initData(vm, output.data, isComponent);\n\n    initMethods(vm, options.methods);\n\n    initComputed(vm, options.computed, true);\n\n    initWatch(vm, options.watch);\n\n    // create render watcher\n    initRender(\n      vm,\n      Object.keys(vm._data)\n        .concat(Object.keys(vm._props))\n        .concat(Object.keys(vm._computedWatchers || {})),\n      Object.keys(vm._computedWatchers || {})\n    );\n\n    return callUserMethod(vm, vm.$options, 'created', args);\n  };\n\n  output.created = initLifecycle;\n  if (isComponent) {\n    patchComponentLifecycle(output, options, rel);\n  } else {\n    patchPageLifecycle(output, options, rel);\n  }\n\n  // Common patch\n  let lifecycle = getLifeCycle(WEAPP_COMPONENT_LIFECYCLE, rel, 'component');\n\n  lifecycle.forEach(k => {\n    // beforeCreate is not a real lifecycle\n    if (!output[k] && k !== 'beforeCreate' && (isFunc(options[k]) || isArr(options[k]))) {\n      output[k] = function(...args) {\n        return callUserMethod(this.$wepy, this.$wepy.$options, k, args);\n      };\n    }\n  });\n}\n\n/**\n * Patch component life cycle\n * @param {*} output patch output\n * @param {*} options patch options\n * @param {*} rel patch rel\n */\nfunction patchComponentLifecycle(output, options, rel) {\n  output.attached = function(...args) {\n    // Component attached\n    let outProps = output.properties || {};\n    // this.propperties are includes datas\n    let acceptProps = this.properties;\n    let vm = this.$wepy;\n\n    this.triggerEvent('_init', vm);\n\n    // created 不能调用 setData，如果有 dirty 在此更新\n    vm.$forceUpdate();\n\n    Object.keys(outProps).forEach(k => (vm[k] = acceptProps[k]));\n\n    return callUserMethod(vm, vm.$options, 'attached', args);\n  };\n\n  // 增加组件页面声明周期\n  output.pageLifetimes = {};\n  const lifecycle = getLifeCycle(WEAPP_COMPONENT_PAGE_LIFECYCLE, rel, 'component');\n\n  lifecycle.forEach(function(k) {\n    if (!output.pageLifetimes[k] && options[k] && (isFunc(options[k]) || isArr(options[k]))) {\n      output.pageLifetimes[k] = function(...args) {\n        return callUserMethod(this.$wepy, this.$wepy.$options, k, args);\n      };\n    }\n  });\n}\n\n/**\n * Patch Page Life cycle\n * @param {*} output patch output\n * @param {*} options patch options\n * @param {*} rel rel\n */\nfunction patchPageLifecycle(output, options, rel) {\n  output.attached = function(...args) {\n    // Page attached\n    let vm = this.$wepy;\n    let app = vm.$app;\n\n    let refs = rel.refs || [];\n    let query = wx.createSelectorQuery();\n\n    refs.forEach(item => {\n      // {\n      //   id: { name: 'hello', bind: true },\n      //   ref: { name: 'value', bind: false }\n      // }\n      let idAttr = item.id;\n      let refAttr = item.ref;\n      let actualAttrIdName = idAttr.name;\n      let actualAttrRefName = refAttr.name;\n      let selector = `#${actualAttrIdName}`;\n\n      if (idAttr.bind) {\n        // if id is a bind attr\n        actualAttrIdName = vm[idAttr.name];\n        selector = `#${actualAttrIdName}`;\n        vm.$watch(idAttr.name, function(newAttrName) {\n          actualAttrIdName = newAttrName;\n          selector = `#${actualAttrIdName}`;\n          vm.$refs[actualAttrRefName] = query.select(selector);\n        });\n      }\n\n      if (refAttr.bind) {\n        // if ref is a bind attr\n        actualAttrRefName = vm[refAttr.name];\n\n        vm.$watch(refAttr.name, function(newAttrName, oldAttrName) {\n          actualAttrRefName = newAttrName;\n          vm.$refs[oldAttrName] = null;\n          vm.$refs[newAttrName] = query.select(selector);\n        });\n      }\n      vm.$refs[actualAttrRefName] = query.select(selector);\n    });\n\n    // created 不能调用 setData，如果有 dirty 在此更新\n    vm.$forceUpdate();\n\n    // TODO: page attached\n    return callUserMethod(vm, vm.$options, 'attached', args);\n  };\n  // Page lifecycle will be called under methods\n  // e.g:\n  // Component({\n  //   methods: {\n  //     onLoad () {\n  //       console.log('page onload')\n  //     }\n  //   }\n  // })\n\n  // Patch routed method\n  patchRouted(output);\n\n  let lifecycle = getLifeCycle(WEAPP_PAGE_LIFECYCLE, rel, 'page');\n\n  lifecycle.forEach(k => {\n    if (!output[k] && options[k] && (isFunc(options[k]) || isArr(options[k]))) {\n      // onShow is patched in routed method\n      if (k !== 'onShow') {\n        output.methods[k] = function(...args) {\n          return callUserMethod(this.$wepy, this.$wepy.$options, k, args);\n        };\n      }\n    }\n  });\n}\n/**\n * Add routed method for user.\n * @param {*} output patch output\n */\nfunction patchRouted(output) {\n  output.methods.onShow = function(...args) {\n    // Page attached\n    let vm = this.$wepy;\n    let app = vm.$app;\n    // eslint-disable-next-line\n    const pages = getCurrentPages();\n    const currentPage = pages[pages.length - 1];\n    const path = currentPage.__route__ || currentPage.route;\n    const webViewId = currentPage.__wxWebviewId__;\n\n    if (!app.$route || app.$route.path !== path) {\n      const oldRoute = app.$route;\n      const newRoute = {\n        path,\n        webViewId,\n        page: currentPage,\n        query: currentPage.options\n      };\n      app.$route = newRoute;\n      callUserMethod(vm, vm.$options, 'routed', [oldRoute, newRoute]);\n    }\n  };\n}\n"
  },
  {
    "path": "packages/core/weapp/init/methods.js",
    "content": "import { warn } from './../util/index';\nimport { dispatcher } from '../dispatcher/index';\n\n/*\n * initialize page methods, also the app\n */\nexport function initMethods(vm, methods) {\n  if (methods) {\n    Object.keys(methods).forEach(method => {\n      vm[method] = methods[method];\n    });\n  }\n}\n\n/*\n * patch method option\n */\nexport function patchMethods(output, methods) {\n  output.methods = {};\n  let target = output.methods;\n\n  target.__initComponent = function(e) {\n    let child = e.detail;\n    let { ref, wpyEvt } = e.target.dataset;\n    let vm = this.$wepy;\n    vm.$children.push(child);\n    if (ref) {\n      if (vm.$refs[ref]) {\n        warn('duplicate ref \"' + ref + '\" will be covered by the last instance.\\n', vm);\n      }\n      vm.$refs[ref] = child;\n    }\n    child.$evtId = wpyEvt;\n    child.$parent = vm;\n    child.$app = vm.$app;\n    child.$root = vm.$root;\n    return vm;\n  };\n  target.__dispatcher = dispatcher;\n\n  // TODO: perf\n  // Only orginal component method goes to target. no need to add all methods.\n  if (methods) {\n    Object.keys(methods).forEach(method => {\n      target[method] = methods[method];\n    });\n  }\n}\n"
  },
  {
    "path": "packages/core/weapp/init/mixins.js",
    "content": "import { isArr } from '../../shared/index';\nimport { WEAPP_LIFECYCLE } from '../../shared/index';\nimport { config } from '../config';\nimport $global from '../global';\n\n// [Default Strategy]\n// Update if it's not exist in output. Can be replaced by option[key].\n// e.g.\n// export default {\n//   myCustomMethod () {\n//     // doSomething\n//   }\n// }\n//\n// [Merge Strategy]\n// Replaced by the latest mixins property.\n// e.g.\n// export default {\n//   data: {\n//     a: 1\n//   }\n// }\n//\n// [Lifecycle Strategy]\n// Extend lifecycle. update lifecycle to an array.\n// e.g.\n// export default {\n//   onShow: {\n//     console.log('onShow');\n//   }\n// }\nlet globalMixinPatched = false;\n\nlet strats = null;\n\nfunction getStrategy(key) {\n  if (!strats) {\n    initStrats();\n  }\n  if (strats[key]) {\n    return strats[key];\n  } else {\n    return defaultStrat;\n  }\n}\nfunction defaultStrat(output, option, key, data) {\n  if (!output[key]) {\n    output[key] = data;\n  }\n}\n\nfunction simpleMerge(parentVal, childVal) {\n  return !parentVal || !childVal ? parentVal || childVal : Object.assign({}, parentVal, childVal);\n}\n\nfunction initStrats() {\n  if (strats) return strats;\n\n  strats = config.optionMergeStrategies;\n\n  strats.data = strats.props = strats.methods = strats.computed = strats.watch = strats.hooks = function mergeStrategy(\n    output,\n    option,\n    key,\n    data\n  ) {\n    option[key] = simpleMerge(option[key], data);\n  };\n\n  WEAPP_LIFECYCLE.forEach(lifecycle => {\n    if (!strats[lifecycle]) {\n      strats[lifecycle] = function lifeCycleStrategy(output, option, key, data) {\n        if (!option[key]) {\n          option[key] = isArr(data) ? data : [data];\n        } else {\n          option[key] = [data].concat(option[key]);\n        }\n      };\n    }\n  });\n}\n\nexport function patchMixins(output, option, mixins) {\n  if (!mixins && !$global.mixin) {\n    return;\n  }\n\n  if (!globalMixinPatched) {\n    let globalMixin = $global.mixin || [];\n\n    mixins = globalMixin.concat(mixins);\n    globalMixinPatched = true;\n  }\n\n  if (isArr(mixins)) {\n    mixins.forEach(mixin => patchMixins(output, option, mixin));\n    globalMixinPatched = false;\n  } else {\n    if (!strats) {\n      initStrats();\n    }\n    for (let k in mixins) {\n      strat = getStrategy(k);\n      let strat = strats[k] || defaultStrat;\n      strat(output, option, k, mixins[k]);\n    }\n  }\n}\n"
  },
  {
    "path": "packages/core/weapp/init/props.js",
    "content": "import { observe } from './../observer/index';\nimport { proxy } from './data';\nimport { isFunc, isArr, isStr, isObj, isUndef } from './../util/index';\n\nconst AllowedTypes = [String, Number, Boolean, Object, Array, null];\n\nconst observerFn = function() {\n  return function(newVal, oldVal, changedPaths) {\n    let vm = this.$wepy;\n\n    // changedPaths 长度大于 1，说明是由内部赋值改变的 prop\n    if (changedPaths.length > 1) {\n      return;\n    }\n    let _data = newVal;\n    if (typeof _data === 'function') {\n      _data = _data.call(vm);\n    }\n    vm[changedPaths[0]] = _data;\n  };\n};\n/*\n * patch props option\n */\nexport function patchProps(output, props) {\n  let newProps = {};\n  if (isStr(props)) {\n    newProps = [props];\n  }\n  if (isArr(props)) {\n    props.forEach(prop => {\n      newProps[prop] = {\n        type: null,\n        observer: observerFn(output, props, prop)\n      };\n    });\n  } else if (isObj(props)) {\n    for (let k in props) {\n      let prop = props[k];\n      let newProp = {};\n\n      // props.type\n      if (isUndef(prop.type)) {\n        newProp.type = null;\n      } else if (isArr(prop.type)) {\n        newProp.optionalTypes = prop.type;\n        newProp.type = prop.type[0];\n      } else if (AllowedTypes.indexOf(prop.type) === -1) {\n        newProp.type = null;\n        // eslint-disable-next-line\n        console.warn(\n          `Type property of props \"${k}\" is invalid. Only String/Number/Boolean/Object/Array/null is allowed in weapp Component`\n        );\n      } else {\n        newProp.type = prop.type;\n      }\n\n      // props.default\n      if (!isUndef(prop.default)) {\n        if (isFunc(prop.default)) {\n          newProp.value = prop.default.call(output);\n        } else {\n          newProp.value = prop.default;\n        }\n      }\n      // props.optionalTypes\n      if (!isUndef(prop.optionalTypes)) {\n        if (isArr(prop.optionalTypes)) {\n          newProp.optionalTypes = prop.optionalTypes;\n        }\n      }\n      // TODO\n      // props.validator\n      // props.required\n\n      newProp.observer = observerFn(output, props, prop);\n\n      newProps[k] = newProp;\n    }\n  }\n\n  // eslint-disable-next-line\n  Object.keys(newProps).forEach(prop => {});\n\n  output.properties = newProps;\n}\n\n/*\n * init props\n */\nexport function initProps(vm, properties) {\n  vm._props = {};\n\n  if (!properties) {\n    return;\n  }\n\n  Object.keys(properties).forEach(key => {\n    vm._props[key] = properties[key].value;\n    proxy(vm, '_props', key);\n  });\n\n  observe({\n    vm: vm,\n    key: '',\n    value: vm._props,\n    root: true\n  });\n}\n"
  },
  {
    "path": "packages/core/weapp/init/relations.js",
    "content": "export function patchRelations(output, relations) {\n  if (!relations) {\n    relations = {};\n  }\n  output.relations = relations;\n}\n"
  },
  {
    "path": "packages/core/weapp/init/render.js",
    "content": "import Watcher from './../observer/watcher';\nimport { callUserHook } from './hooks';\nimport { clone } from './../util/index';\nimport { renderFlushCallbacks } from './../util/next-tick';\n\nexport function resetDirty(vm) {\n  vm.$dirtyKey = {};\n  vm.$dirtyPath = {};\n}\n\nexport function initRender(vm, keys, computedKeys) {\n  vm._init = false;\n  let dirtyFromAttach = null;\n  return new Watcher(\n    vm,\n    function() {\n      if (!vm._init) {\n        keys.forEach(key => clone(vm[key]));\n      }\n\n      if (vm.$dirty.length() || dirtyFromAttach) {\n        let keys = vm.$dirty.get('key');\n        computedKeys.forEach(key => vm[key]);\n        let dirty = vm.$dirty.pop();\n\n        // TODO: reset subs\n        Object.keys(keys).forEach(key => clone(vm[key]));\n\n        if (vm._init) {\n          dirty = callUserHook(vm, 'before-setData', dirty);\n        }\n\n        // vm._fromSelf = true;\n        if (dirty || dirtyFromAttach) {\n          // init render is in lifecycle, setData in lifecycle will not work, so cacheData is needed.\n          if (!vm._init) {\n            if (dirtyFromAttach === null) {\n              dirtyFromAttach = {};\n            }\n            Object.assign(dirtyFromAttach, dirty);\n          } else if (dirtyFromAttach) {\n            // setData in attached\n            vm.$wx.setData(Object.assign(dirtyFromAttach, dirty || {}), renderFlushCallbacks);\n            dirtyFromAttach = null;\n          } else {\n            vm.$wx.setData(dirty, renderFlushCallbacks);\n          }\n        }\n      }\n      vm._init = true;\n    },\n    function() {},\n    null,\n    true\n  );\n}\n"
  },
  {
    "path": "packages/core/weapp/init/watch.js",
    "content": "export function initWatch(vm, watch) {\n  if (watch) {\n    Object.keys(watch).forEach(key => {\n      vm.$watch(key, watch[key]);\n    });\n  }\n}\n"
  },
  {
    "path": "packages/core/weapp/native/app.js",
    "content": "import { patchMixins, patchAppLifecycle } from '../init/index';\n\nexport function app(option, rel) {\n  let appConfig = {};\n\n  patchMixins(appConfig, option, option.mixins);\n  patchAppLifecycle(appConfig, option, rel);\n\n  return App(appConfig);\n}\n"
  },
  {
    "path": "packages/core/weapp/native/component.js",
    "content": "import { patchMixins, patchMethods, patchData, patchLifecycle, patchProps, patchRelations } from '../init/index';\n\nexport function component(opt = {}, rel) {\n  let compConfig = {\n    externalClasses: opt.externalClasses || [],\n    // support component options property\n    // example: options: {addGlobalClass:true}\n    options: opt.options || {}\n  };\n\n  patchMixins(compConfig, opt, opt.mixins);\n\n  if (opt.properties) {\n    compConfig.properties = opt.properties;\n    if (opt.props) {\n      // eslint-disable-next-line no-console\n      console.warn(`props will be ignore, if properties is set`);\n    }\n  } else if (opt.props) {\n    patchProps(compConfig, opt.props);\n  }\n\n  patchMethods(compConfig, opt.methods, true);\n\n  patchData(compConfig, opt.data, true);\n\n  patchRelations(compConfig, opt.relations);\n\n  patchLifecycle(compConfig, opt, rel, true);\n\n  return Component(compConfig);\n}\n"
  },
  {
    "path": "packages/core/weapp/native/index.js",
    "content": "export * from './app';\nexport * from './component';\nexport * from './page';\n"
  },
  {
    "path": "packages/core/weapp/native/page.js",
    "content": "import { patchMixins, patchData, patchMethods, patchLifecycle, patchProps } from '../init/index';\n\nexport function page(opt = {}, rel) {\n  let pageConfig = {\n    externalClasses: opt.externalClasses || [],\n    // support component options property\n    // example: options: {addGlobalClass:true}\n    options: opt.options || {}\n  };\n\n  patchMixins(pageConfig, opt, opt.mixins);\n\n  if (opt.properties) {\n    pageConfig.properties = opt.properties;\n    if (opt.props) {\n      // eslint-disable-next-line\n      console.warn(`props will be ignore, if properties is set`);\n    }\n  } else if (opt.props) {\n    patchProps(pageConfig, opt.props);\n  }\n\n  patchMethods(pageConfig, opt.methods);\n\n  patchData(pageConfig, opt.data);\n\n  patchLifecycle(pageConfig, opt, rel);\n\n  return Component(pageConfig);\n}\n"
  },
  {
    "path": "packages/core/weapp/observer/array.js",
    "content": "/*\n * not type checking this file because flow doesn't play well with\n * dynamically accessing methods on Array prototype\n */\n\nimport { def, hasOwn, isObject } from '../util/index';\nimport { cleanPaths } from './observerPath';\n\nconst arrayProto = Array.prototype;\nexport const arrayMethods = Object.create(arrayProto);\n\nconst methodsToPatch = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'];\n\n/**\n * Intercept mutating methods and emit events\n */\nmethodsToPatch.forEach(function(method) {\n  // cache original method\n  const original = arrayProto[method];\n  def(arrayMethods, method, function mutator(...args) {\n    const len = this.length;\n    // 清除已经失效的 paths\n    if (len > 0) {\n      switch (method) {\n        case 'pop':\n          delInvalidPaths(len - 1, this[len - 1], this);\n          break;\n        case 'shift':\n          delInvalidPaths(0, this[0], this);\n          break;\n        case 'splice':\n        case 'sort':\n        case 'reverse':\n          for (let i = 0; i < this.length; i++) {\n            delInvalidPaths(i, this[i], this);\n          }\n      }\n    }\n\n    const result = original.apply(this, args);\n    const ob = this.__ob__;\n    const vm = ob.vm;\n\n    // push parent key to dirty, wait to setData\n    if (vm.$dirty) {\n      if (method === 'push') {\n        const lastIndex = ob.value.length - 1;\n        vm.$dirty.set(ob.op, lastIndex, ob.value[lastIndex]);\n      } else {\n        vm.$dirty.set(ob.op, null, ob.value);\n      }\n    }\n\n    // 这里和 vue 不一样，所有变异方法都需要更新 path\n    ob.observeArray(ob.key, ob.value);\n\n    // notify change\n    ob.dep.notify();\n    return result;\n  });\n});\n\nfunction delInvalidPaths(key, value, parent) {\n  if (isObject(value) && hasOwn(value, '__ob__')) {\n    // delete invalid paths\n    cleanPaths(key, value.__ob__.op, parent.__ob__.op);\n  }\n}\n"
  },
  {
    "path": "packages/core/weapp/observer/dep.js",
    "content": "// import type Watcher from './watcher'\nimport { remove } from '../util/index';\n\nlet uid = 0;\n\n/**\n * A dep is an observable that can have multiple\n * directives subscribing to it.\n */\nexport default class Dep {\n  constructor() {\n    this.id = uid++;\n    this.subs = [];\n  }\n\n  addSub(sub) {\n    this.subs.push(sub);\n  }\n\n  removeSub(sub) {\n    remove(this.subs, sub);\n  }\n\n  depend() {\n    if (Dep.target) {\n      Dep.target.addDep(this);\n    }\n  }\n\n  notify() {\n    // stabilize the subscriber list first\n    const subs = this.subs.slice();\n    for (let i = 0, l = subs.length; i < l; i++) {\n      subs[i].update();\n    }\n  }\n}\n\n// the current target watcher being evaluated.\n// this is globally unique because there could be only one\n// watcher being evaluated at any time.\nDep.target = null;\nconst targetStack = [];\n\nexport function pushTarget(_target) {\n  if (Dep.target) targetStack.push(Dep.target);\n  Dep.target = _target;\n}\n\nexport function popTarget() {\n  Dep.target = targetStack.pop();\n}\n"
  },
  {
    "path": "packages/core/weapp/observer/index.js",
    "content": "import Dep from './dep';\nimport ObserverPath, { addPaths, cleanPaths } from './observerPath';\nimport { arrayMethods } from './array';\nimport { def, warn, hasOwn, hasProto, isObject, isPlainObject, isValidArrayIndex } from '../util/index';\n\nconst arrayKeys = Object.getOwnPropertyNames(arrayMethods);\n\n/**\n * By default, when a reactive property is set, the new value is\n * also converted to become reactive. However when passing down props,\n * we don't want to force conversion because the value may be a nested value\n * under a frozen data structure. Converting it would defeat the optimization.\n */\nexport const observerState = {\n  shouldConvert: true\n};\n\n/**\n * Observer class that are attached to each observed\n * object. Once attached, the observer converts target\n * object's property keys into getter/setters that\n * collect dependencies and dispatches updates.\n */\nexport class Observer {\n  constructor({ vm, key, value, parent }) {\n    this.value = value;\n    this.dep = new Dep();\n    this.vmCount = 0;\n    this.vm = vm;\n    this.op = new ObserverPath(key, this, parent && parent.__ob__ && parent.__ob__.op);\n\n    def(value, '__ob__', this);\n    if (Array.isArray(value)) {\n      const augment = hasProto ? protoAugment : copyAugment;\n      augment(value, arrayMethods, arrayKeys);\n      this.observeArray(key, value);\n    } else {\n      this.walk(key, value);\n    }\n  }\n\n  /**\n   * Walk through each property and convert them into\n   * getter/setters. This method should only be called when\n   * value type is Object.\n   */\n  walk(key, obj) {\n    const keys = Object.keys(obj);\n    for (let i = 0; i < keys.length; i++) {\n      defineReactive({ vm: this.vm, obj: obj, key: keys[i], value: obj[keys[i]], parent: obj });\n      //defineReactive(this.vm, obj, keys[i], obj[keys[i]]);\n    }\n  }\n\n  /**\n   * Observe a list of Array items.\n   */\n  observeArray(key, items) {\n    for (let i = 0, l = items.length; i < l; i++) {\n      observe({ vm: this.vm, key: i, value: items[i], parent: items });\n    }\n  }\n\n  /**\n   * Check if path exsit in vm\n   */\n  hasPath(path) {\n    let value = this.vm;\n    let key = '';\n    let i = 0;\n    while (i < path.length) {\n      if (path[i] !== '.' && path[i] !== '[' && path[i] !== ']') {\n        key += path[i];\n      } else if (key.length !== 0) {\n        value = value[key];\n        key = '';\n        if (!isObject(value)) {\n          return false;\n        }\n      }\n      i++;\n    }\n    return true;\n  }\n\n  /**\n   * Is this path value equal\n   */\n  isPathEq(path, value) {\n    let objValue = this.vm;\n    let key = '';\n    let i = 0;\n    while (i < path.length) {\n      if (path[i] !== '.' && path[i] !== '[' && path[i] !== ']') {\n        key += path[i];\n      } else if (key.length !== 0) {\n        objValue = objValue[key];\n        key = '';\n        if (!isObject(objValue)) {\n          return false;\n        }\n      }\n      i++;\n    }\n    if (key.length !== 0) {\n      objValue = objValue[key];\n    }\n    return value === objValue;\n  }\n}\n\n// helpers\n\n/**\n * Augment an target Object or Array by intercepting\n * the prototype chain using __proto__\n */\nfunction protoAugment(target, src) {\n  /* eslint-disable no-proto */\n  target.__proto__ = src;\n  /* eslint-enable no-proto */\n}\n\n/**\n * Augment an target Object or Array by defining\n * hidden properties.\n */\n/* istanbul ignore next */\nfunction copyAugment(target, src, keys) {\n  for (let i = 0, l = keys.length; i < l; i++) {\n    const key = keys[i];\n    def(target, key, src[key]);\n  }\n}\n\n/**\n * Attempt to create an observer instance for a value,\n * returns the new observer if successfully observed,\n * or the existing observer if the value already has one.\n */\nexport function observe({ vm, key, value, parent, root }) {\n  if (!isObject(value)) {\n    return;\n  }\n  let ob;\n  if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {\n    ob = value.__ob__;\n    const op = ob.op;\n    addPaths(key, op, parent.__ob__.op);\n  } else if (\n    observerState.shouldConvert &&\n    (Array.isArray(value) || isPlainObject(value)) &&\n    Object.isExtensible(value) &&\n    !value._isVue\n  ) {\n    ob = new Observer({ vm: vm, key: key, value: value, parent: parent });\n  }\n  if (root && ob) {\n    ob.vmCount++;\n  }\n  return ob;\n}\n\n/**\n * Define a reactive property on an Object.\n */\nexport function defineReactive({ vm, obj, key, value, parent, customSetter, shallow }) {\n  const dep = new Dep();\n\n  const property = Object.getOwnPropertyDescriptor(obj, key);\n  if (property && property.configurable === false) {\n    return;\n  }\n\n  // cater for pre-defined getter/setters\n  const getter = property && property.get;\n  if (!getter && arguments.length === 2) {\n    value = obj[key];\n  }\n  const setter = property && property.set;\n\n  let childOb = !shallow && observe({ vm: vm, key: key, value: value, parent: obj });\n  Object.defineProperty(obj, key, {\n    enumerable: true,\n    configurable: true,\n    get: function reactiveGetter() {\n      const val = getter ? getter.call(obj) : value;\n      if (Dep.target) {\n        dep.depend();\n        if (childOb) {\n          childOb.dep.depend();\n          if (Array.isArray(val)) {\n            dependArray(val);\n          }\n        }\n      }\n      return val;\n    },\n    set: function reactiveSetter(newVal) {\n      const val = getter ? getter.call(obj) : value;\n      /* eslint-disable no-self-compare */\n      if (newVal === val || (newVal !== newVal && val !== val)) {\n        return;\n      }\n\n      if (isObject(value) && hasOwn(value, '__ob__')) {\n        /**\n         * 删掉无效的 paths\n         * 注意：即使 path 只有一个也要删掉，因为其子节点可能有多个 path\n         */\n        cleanPaths(key, value.__ob__.op, parent.__ob__.op);\n      }\n\n      /* eslint-enable no-self-compare */\n      if (process.env.NODE_ENV !== 'production' && customSetter) {\n        customSetter();\n      }\n      if (setter) {\n        setter.call(obj, newVal);\n      } else {\n        value = newVal;\n      }\n\n      // Have to set dirty after value assigned, otherwise the dirty key is incrrect.\n      if (vm) {\n        // push parent key to dirty, wait to setData\n        if (vm.$dirty) {\n          vm.$dirty.set(obj.__ob__.op, key, newVal);\n        }\n      }\n      childOb = !shallow && observe({ vm: vm, key: key, value: newVal, parent: parent });\n      dep.notify();\n    }\n  });\n}\n\n/**\n * Set a property on an object. Adds the new property and\n * triggers change notification if the property doesn't\n * already exist.\n */\nexport function set(vm, target, key, val) {\n  if (Array.isArray(target) && isValidArrayIndex(key)) {\n    target.length = Math.max(target.length, key);\n    target.splice(key, 1, val);\n    return val;\n  }\n\n  if (key in target && !(key in Object.prototype)) {\n    target[key] = val;\n    return val;\n  }\n\n  const ob = target.__ob__;\n  if (target._isVue || (ob && ob.vmCount)) {\n    process.env.NODE_ENV !== 'production' &&\n      warn(\n        'Avoid adding reactive properties to a Vue instance or its root $data ' +\n          'at runtime - declare it upfront in the data option.'\n      );\n    return val;\n  }\n\n  if (!ob) {\n    target[key] = val;\n    return val;\n  }\n\n  if (isObject(target[key]) && hasOwn(target[key], '__ob__')) {\n    // delete invalid paths\n    cleanPaths(key, target[key].__ob__.op, ob.op);\n  }\n  defineReactive({ vm: vm, obj: ob.value, key: key, value: val, parent: ob.value });\n  if (vm) {\n    // push parent key to dirty, wait to setData\n    if (vm.$dirty && hasOwn(target, '__ob__')) {\n      vm.$dirty.set(target.__ob__.op, key, val);\n    }\n  }\n  ob.dep.notify();\n  return val;\n}\n\n/**\n * Delete a property and trigger change if necessary.\n */\nexport function del(target, key) {\n  if (Array.isArray(target) && isValidArrayIndex(key)) {\n    target.splice(key, 1);\n    return;\n  }\n\n  const ob = target.__ob__;\n  if (target._isVue || (ob && ob.vmCount)) {\n    process.env.NODE_ENV !== 'production' &&\n      warn('Avoid deleting properties on a Vue instance or its root $data ' + '- just set it to null.');\n    return;\n  }\n\n  if (!hasOwn(target, key)) {\n    return;\n  }\n\n  // set $dirty\n  target[key] = null;\n  delete target[key];\n  if (!ob) {\n    return;\n  }\n  ob.dep.notify();\n}\n\n/**\n * Collect dependencies on array elements when the array is touched, since\n * we cannot intercept array element access like property getters.\n */\nfunction dependArray(value) {\n  for (let e, i = 0, l = value.length; i < l; i++) {\n    e = value[i];\n    e && e.__ob__ && e.__ob__.dep.depend();\n    if (Array.isArray(e)) {\n      dependArray(e);\n    }\n  }\n}\n"
  },
  {
    "path": "packages/core/weapp/observer/observerPath.js",
    "content": "/**\n * @desc ObserverPath 类以及相关处理函数\n * Observer 所在位置对应在整棵 data tree 的路径集合\n * @createDate 2019-07-21\n */\nimport { hasOwn, isNum, isObject, remove } from '../util/index';\n\n/**\n * 生成完整路径\n * @param key  {String|Number} 当为字符串时，说明是属性名，当为数字时，说明是索引\n * @param parentPath {String} 父路径\n * @return {string}\n */\nconst setPath = (key, parentPath) => {\n  return isNum(key) ? `${parentPath}[${key}]` : `${parentPath}.${key}`;\n};\n\n/**\n * 得到 ObserverPath\n * @param value 被观察对象\n * @return {ObserverPath|null}\n */\nconst pickOp = value => {\n  return isObject(value) && hasOwn(value, '__ob__') ? value.__ob__.op : null;\n};\n\nexport default class ObserverPath {\n  constructor(key, ob, parentOp) {\n    this.ob = ob;\n    // eslint-disable-next-line eqeqeq\n    if (parentOp) {\n      const { combinePathKeys, combinePathMap } = getPathMap(key, parentOp.pathKeys, parentOp.pathMap);\n      this.pathKeys = combinePathKeys;\n      this.pathMap = combinePathMap;\n    } else {\n      this.pathKeys = null;\n      this.pathMap = null;\n    }\n  }\n\n  traverseOp(key, pathKeys, pathMap, handler) {\n    // 得到 newKey 和 pathMap 组合的路径集合\n    const { combinePathMap, combinePathKeys } = getPathMap(key, pathKeys, pathMap);\n    let handlePathKeys = [];\n    let handlePathMap = {};\n    let hasChange = false;\n\n    // 遍历 combinePathMap\n    for (let i = 0; i < combinePathKeys.length; i++) {\n      const pathObj = handler(combinePathMap[combinePathKeys[i]], this);\n      if (pathObj) {\n        hasChange = true;\n        handlePathKeys.push(pathObj.path);\n        handlePathMap[pathObj.path] = pathObj;\n      }\n    }\n\n    if (hasChange) {\n      const value = this.ob.value;\n      if (Array.isArray(value)) {\n        for (let i = 0; i < value.length; i++) {\n          const op = pickOp(value[i]);\n          op && op.traverseOp(i, handlePathKeys, handlePathMap, handler);\n        }\n      } else {\n        const keys = Object.keys(value);\n        for (let i = 0; i < keys.length; i++) {\n          const key = keys[i];\n          const op = pickOp(value[key]);\n          op && op.traverseOp(key, handlePathKeys, handlePathMap, handler);\n        }\n      }\n    }\n  }\n\n  addPath(pathObj) {\n    this.pathKeys.push(pathObj.path);\n    this.pathMap[pathObj.path] = pathObj;\n  }\n\n  delPath(path) {\n    remove(this.pathKeys, path);\n    delete this.pathMap[path];\n  }\n}\n\n/**\n * 添加新的 __ob__ 的 path\n */\nexport function addPaths(newKey, op, parentOp) {\n  op.traverseOp(newKey, parentOp.pathKeys, parentOp.pathMap, handler);\n\n  function handler(pathObj, op) {\n    if (!(pathObj.path in op.pathMap)) {\n      // 新增一条 path\n      op.addPath(pathObj);\n      return pathObj;\n    } else {\n      return null;\n    }\n  }\n}\n\n/**\n * 删除指定的 __ob__ 的 path\n */\nexport function cleanPaths(oldKey, op, parentOp) {\n  op.traverseOp(oldKey, parentOp.pathKeys, parentOp.pathMap, handler);\n\n  function handler(pathObj, op) {\n    // 删除一条 path\n    op.delPath(pathObj.path);\n    return pathObj;\n  }\n}\n\n/**\n * 得到 pathMap 与 key 组合后的路径集合\n */\nexport function getPathMap(key, pathKeys, pathMap) {\n  if (pathMap) {\n    // console.log('pathMap', pathMap)\n    let combinePathKeys = [];\n    let combinePathMap = {};\n    for (let i = 0; i < pathKeys.length; i++) {\n      const path = setPath(key, pathMap[pathKeys[i]].path);\n      combinePathKeys.push(path);\n      combinePathMap[path] = { key, root: pathMap[pathKeys[i]].root, path };\n    }\n    return { combinePathKeys, combinePathMap };\n  } else {\n    return {\n      combinePathKeys: [key],\n      combinePathMap: { [key]: { key, root: key, path: key } }\n    };\n  }\n}\n"
  },
  {
    "path": "packages/core/weapp/observer/scheduler.js",
    "content": "//import { callHook, activateChildComponent } from '../instance/lifecycle';\n\nimport { warn, nextTick } from '../util/index';\n\nexport const MAX_UPDATE_COUNT = 100;\n\nconst queue = [];\nconst activatedChildren = [];\nlet has = {};\nlet circular = {};\nlet waiting = false;\nlet flushing = false;\nlet index = 0;\n\n/**\n * Reset the scheduler's state.\n */\nfunction resetSchedulerState() {\n  index = queue.length = activatedChildren.length = 0;\n  has = {};\n  if (process.env.NODE_ENV !== 'production') {\n    circular = {};\n  }\n  waiting = flushing = false;\n}\n\n/**\n * Flush both queues and run the watchers.\n */\nfunction flushSchedulerQueue(times = 0) {\n  flushing = true;\n  let watcher, id;\n\n  // Sort queue before flush.\n  // This ensures that:\n  // 1. Components are updated from parent to child. (because parent is always\n  //    created before the child)\n  // 2. A component's user watchers are run before its render watcher (because\n  //    user watchers are created before the render watcher)\n  // 3. If a component is destroyed during a parent component's watcher run,\n  //    its watchers can be skipped.\n  times === 0 && queue.sort((a, b) => a.id - b.id);\n\n  // do not cache length because more watchers might be pushed\n  // as we run existing watchers\n  // there would be mutilple renderWatcher in the queue.\n  let renderWatcher = [];\n  if (times === 0) {\n    index = 0;\n  }\n  for (; index < queue.length; index++) {\n    // if it's renderWatcher, run it in the end\n    watcher = queue[index];\n    if (watcher && watcher.isRenderWatcher) {\n      renderWatcher.push(watcher);\n      continue;\n    }\n    id = watcher.id;\n    has[id] = null;\n    watcher.run();\n    // in dev build, check and stop circular updates.\n    // eslint-disable-next-line\n    if (process.env.NODE_ENV !== 'production' && has[id] != null) {\n      circular[id] = (circular[id] || 0) + 1;\n      if (circular[id] > MAX_UPDATE_COUNT) {\n        warn(\n          'You may have an infinite update loop ' +\n            (watcher.user ? `in watcher with expression \"${watcher.expression}\"` : `in a component render function.`),\n          watcher.vm\n        );\n        resetSchedulerState();\n        return;\n      }\n    }\n  }\n  // Run renderWatcher in the end.\n  if (renderWatcher.length) {\n    renderWatcher.forEach(watcher => {\n      has[watcher.id] = null;\n      watcher.run();\n    });\n  }\n\n  // It may added new watcher to the queue in render watcher\n  let pendingQueue = queue.slice(index);\n\n  if (pendingQueue.length) {\n    flushSchedulerQueue(times + 1);\n  } else {\n    // keep copies of post queues before resetting state\n    // const activatedQueue = activatedChildren.slice()\n    // const updatedQueue = queue.slice()\n\n    resetSchedulerState();\n\n    // call component updated and activated hooks\n    // callActivatedHooks(activatedQueue)\n    // callUpdatedHooks(updatedQueue)\n\n    // devtool hook\n    /* istanbul ignore if */\n    /*\n    if (devtools && config.devtools) {\n      devtools.emit('flush')\n    }*/\n  }\n}\n\n/*\nfunction callUpdatedHooks(queue) {\n  let i = queue.length;\n  while (i--) {\n    const watcher = queue[i];\n    const vm = watcher.vm;\n    if (vm._watcher === watcher && vm._isMounted) {\n      callHook(vm, 'updated');\n    }\n  }\n}*/\n\n/**\n * Queue a kept-alive component that was activated during patch.\n * The queue will be processed after the entire tree has been patched.\n */\nexport function queueActivatedComponent(vm) {\n  // setting _inactive to false here so that a render function can\n  // rely on checking whether it's in an inactive tree (e.g. router-view)\n  vm._inactive = false;\n  activatedChildren.push(vm);\n}\n\n/*\nfunction callActivatedHooks(queue) {\n  for (let i = 0; i < queue.length; i++) {\n    queue[i]._inactive = true;\n    activateChildComponent(queue[i], true);\n  }\n}\n*/\n\n/**\n * Push a watcher into the watcher queue.\n * Jobs with duplicate IDs will be skipped unless it's\n * pushed when the queue is being flushed.\n */\nexport function queueWatcher(watcher) {\n  const id = watcher.id;\n  // eslint-disable-next-line\n  if (has[id] == null) {\n    has[id] = true;\n    if (!flushing) {\n      queue.push(watcher);\n    } else {\n      // if already flushing, splice the watcher based on its id\n      // if already past its id, it will be run next immediately.\n      let i = queue.length - 1;\n      while (i > index && queue[i].id > watcher.id) {\n        i--;\n      }\n      queue.splice(i + 1, 0, watcher);\n    }\n    // queue the flush\n    if (!waiting) {\n      waiting = true;\n      nextTick(flushSchedulerQueue);\n    }\n  }\n}\n"
  },
  {
    "path": "packages/core/weapp/observer/traverse.js",
    "content": "import { _Set as Set, isObject } from '../util/index';\n\nconst seenObjects = new Set();\n\n/**\n * Recursively traverse an object to evoke all converted\n * getters, so that every nested property inside the object\n * is collected as a \"deep\" dependency.\n */\nexport function traverse(val) {\n  _traverse(val, seenObjects);\n  seenObjects.clear();\n}\n\nfunction _traverse(val, seen) {\n  let i, keys;\n  const isA = Array.isArray(val);\n  if ((!isA && !isObject(val)) || Object.isFrozen(val)) {\n    return;\n  }\n  if (val.__ob__) {\n    const depId = val.__ob__.dep.id;\n    if (seen.has(depId)) {\n      return;\n    }\n    seen.add(depId);\n  }\n  if (isA) {\n    i = val.length;\n    while (i--) _traverse(val[i], seen);\n  } else {\n    keys = Object.keys(val);\n    i = keys.length;\n    while (i--) _traverse(val[keys[i]], seen);\n  }\n}\n"
  },
  {
    "path": "packages/core/weapp/observer/watcher.js",
    "content": "import { warn, remove, isObject, parsePath, _Set as Set, handleError } from '../util/index';\n\nimport { traverse } from './traverse';\nimport { queueWatcher } from './scheduler';\nimport Dep, { pushTarget, popTarget } from './dep';\n\n//import { SimpleSet } from '../util/index';\n\nlet uid = 0;\n\n/**\n * A watcher parses an expression, collects dependencies,\n * and fires callback when the expression value changes.\n * This is used for both the $watch() api and directives.\n */\nexport default class Watcher {\n  constructor(vm, expOrFn, cb, options, isRenderWatcher) {\n    this.vm = vm;\n    if (isRenderWatcher) {\n      vm._watcher = this;\n    }\n    vm._watchers.push(this);\n    // options\n    if (options) {\n      this.deep = !!options.deep;\n      this.user = !!options.user;\n      this.computed = !!options.computed;\n      this.sync = !!options.sync;\n    } else {\n      this.deep = this.user = this.computed = this.sync = false;\n    }\n    this.cb = cb;\n    this.id = ++uid; // uid for batching\n    this.active = true;\n    this.dirty = this.computed; // for computed watchers\n    this.deps = [];\n    this.newDeps = [];\n    this.depIds = new Set();\n    this.newDepIds = new Set();\n    this.isRenderWatcher = isRenderWatcher;\n    this.expression = process.env.NODE_ENV !== 'production' ? expOrFn.toString() : '';\n    // parse expression for getter\n    if (typeof expOrFn === 'function') {\n      this.getter = expOrFn;\n    } else {\n      this.getter = parsePath(expOrFn);\n      if (!this.getter) {\n        this.getter = function() {};\n        process.env.NODE_ENV !== 'production' &&\n          warn(\n            `Failed watching path: \"${expOrFn}\" ` +\n              'Watcher only accepts simple dot-delimited paths. ' +\n              'For full control, use a function instead.',\n            vm\n          );\n      }\n    }\n    this.value = this.computed ? undefined : this.get();\n  }\n\n  /**\n   * Evaluate the getter, and re-collect dependencies.\n   */\n  get() {\n    pushTarget(this);\n    let value;\n    const vm = this.vm;\n    try {\n      value = this.getter.call(vm, vm);\n    } catch (e) {\n      if (this.user) {\n        handleError(e, vm, `getter for watcher \"${this.expression}\"`);\n      } else {\n        throw e;\n      }\n    } finally {\n      // \"touch\" every property so they are all tracked as\n      // dependencies for deep watching\n      if (this.deep) {\n        traverse(value);\n      }\n      popTarget();\n      if (!this.isRenderWatcher) this.cleanupDeps();\n    }\n    return value;\n  }\n\n  /**\n   * Add a dependency to this directive.\n   */\n  addDep(dep) {\n    const id = dep.id;\n    if (!this.newDepIds.has(id)) {\n      this.newDepIds.add(id);\n      this.newDeps.push(dep);\n      if (!this.depIds.has(id)) {\n        dep.addSub(this);\n      }\n    }\n  }\n\n  /**\n   * Clean up for dependency collection.\n   */\n  cleanupDeps() {\n    let i = this.deps.length;\n    while (i--) {\n      const dep = this.deps[i];\n      if (!this.newDepIds.has(dep.id)) {\n        dep.removeSub(this);\n      }\n    }\n    let tmp = this.depIds;\n    this.depIds = this.newDepIds;\n    this.newDepIds = tmp;\n    this.newDepIds.clear();\n    tmp = this.deps;\n    this.deps = this.newDeps;\n    this.newDeps = tmp;\n    this.newDeps.length = 0;\n  }\n\n  /**\n   * Subscriber interface.\n   * Will be called when a dependency changes.\n   */\n  update() {\n    /* istanbul ignore else */\n    if (this.computed) {\n      this.dirty = true;\n    } else if (this.sync) {\n      this.run();\n    } else {\n      queueWatcher(this);\n    }\n  }\n\n  /**\n   * Scheduler job interface.\n   * Will be called by the scheduler.\n   */\n  run() {\n    if (this.active) {\n      const value = this.get();\n      if (\n        value !== this.value ||\n        // Deep watchers and watchers on Object/Arrays should fire even\n        // when the value is the same, because the value may\n        // have mutated.\n        isObject(value) ||\n        this.deep\n      ) {\n        // set new value\n        const oldValue = this.value;\n        this.value = value;\n        if (this.user) {\n          try {\n            this.cb.call(this.vm, value, oldValue);\n          } catch (e) {\n            handleError(e, this.vm, `callback for watcher \"${this.expression}\"`);\n          }\n        } else {\n          this.cb.call(this.vm, value, oldValue);\n        }\n      }\n    }\n  }\n\n  /**\n   * Evaluate the value of the watcher.\n   * This only gets called for computed watchers.\n   */\n  evaluate() {\n    this.value = this.get();\n    if (this.vm.$dirty) {\n      let keyVal =\n        this._computedWatchers && this._computedWatchers[this.key]\n          ? this.vm._computedWatchers[this.key].value\n          : this.value;\n      this.vm.$dirty.push(this.key, this.key, keyVal, this.value);\n    }\n    this.dirty = false;\n    return this.value;\n  }\n\n  /**\n   * Depend on all deps collected by this watcher.\n   */\n  depend() {\n    if (Dep.target) {\n      let i = this.deps.length;\n      while (i--) {\n        this.deps[i].depend();\n      }\n    }\n  }\n\n  /**\n   * Remove self from all dependencies' subscriber list.\n   */\n  teardown() {\n    if (this.active) {\n      // remove self from vm's watcher list\n      // this is a somewhat expensive operation so we skip it\n      // if the vm is being destroyed.\n      if (!this.vm._isBeingDestroyed) {\n        remove(this.vm._watchers, this);\n      }\n      let i = this.deps.length;\n      while (i--) {\n        this.deps[i].removeSub(this);\n      }\n      this.active = false;\n    }\n  }\n}\n"
  },
  {
    "path": "packages/core/weapp/util/config.js",
    "content": "export default {};\n"
  },
  {
    "path": "packages/core/weapp/util/debug.js",
    "content": "import config from './config';\nimport { noop } from '../../shared/util';\n\nexport let warn = noop;\nexport let tip = noop;\n\nconst generateComponentTrace = function(vm) {\n  return `Found in component: \"${vm.$is}\"`;\n};\n\nif (process.env.NODE_ENV !== 'production') {\n  const hasConsole = typeof console !== 'undefined';\n  // TODO\n  warn = (msg, vm) => {\n    if (hasConsole && !config.silent) {\n      // eslint-disable-next-line\n      console.error(`[WePY warn]: ${msg}` + (vm ? generateComponentTrace(vm) : ''));\n    }\n  };\n\n  tip = (msg, vm) => {\n    if (hasConsole && !config.silent) {\n      // eslint-disable-next-line\n      console.warn(`[WePY tip]: ${msg}` + (vm ? generateComponentTrace(vm) : ''));\n    }\n  };\n}\n"
  },
  {
    "path": "packages/core/weapp/util/error.js",
    "content": "import config from './config';\nimport { warn } from './debug';\n\nexport function handleError(err, vm, info) {\n  if (vm) {\n    let cur = vm;\n    while ((cur = cur.$parent)) {\n      const hooks = cur.$options.errorCaptured;\n      if (hooks) {\n        for (let i = 0; i < hooks.length; i++) {\n          try {\n            const capture = hooks[i].call(cur, err, vm, info) === false;\n            if (capture) return;\n          } catch (e) {\n            globalHandleError(e, cur, 'errorCaptured hook');\n          }\n        }\n      }\n    }\n  }\n  globalHandleError(err, vm, info);\n}\n\nfunction globalHandleError(err, vm, info) {\n  if (config.errorHandler) {\n    try {\n      return config.errorHandler.call(null, err, vm, info);\n    } catch (e) {\n      logError(e, null, 'config.errorHandler');\n    }\n  }\n  logError(err, vm, info);\n}\n\nfunction logError(err, vm, info) {\n  if (process.env.NODE_ENV !== 'production') {\n    warn(`Error in ${info}: \"${err.toString()}\"`, vm);\n  }\n  /* istanbul ignore else */\n  if (typeof console !== 'undefined') {\n    // eslint-disable-next-line\n    console.error(err);\n  } else {\n    throw err;\n  }\n}\n"
  },
  {
    "path": "packages/core/weapp/util/index.js",
    "content": "export * from './../../shared/index';\n\nexport * from './debug';\nexport * from './error';\nexport * from './next-tick';\nexport * from './model';\n\n/**\n * Remove an item from an array\n */\nexport function remove(arr, item) {\n  if (arr.length) {\n    var index = arr.indexOf(item);\n    if (index > -1) {\n      return arr.splice(index, 1);\n    }\n  }\n}\n\n/**\n * Check if a string starts with $ or _\n */\nexport function isReserved(str) {\n  const c = (str + '').charCodeAt(0);\n  return c === 0x24 || c === 0x5f;\n}\n\n/**\n * Define a property.\n */\nexport function def(obj, key, val, enumerable) {\n  Object.defineProperty(obj, key, {\n    value: val,\n    enumerable: !!enumerable,\n    writable: true,\n    configurable: true\n  });\n}\n\n/**\n * Parse simple path.\n */\nconst bailRE = /[^\\w.$]/;\nexport function parsePath(path) {\n  if (bailRE.test(path)) {\n    return;\n  }\n  const segments = path.split('.');\n  return function(obj) {\n    for (let i = 0; i < segments.length; i++) {\n      if (!obj) return;\n      obj = obj[segments[i]];\n    }\n    return obj;\n  };\n}\n"
  },
  {
    "path": "packages/core/weapp/util/model.js",
    "content": "/**\n * Parse a v-model expression into a base path and a final key segment.\n * Handles both dot-path and possible square brackets.\n *\n * Possible cases:\n *\n * - test\n * - test[key]\n * - test[test1[key]]\n * - test[\"a\"][key]\n * - xxx.test[a[a].test1[key]]\n * - test.xxx.a[\"asa\"][test1[key]]\n *\n */\nexport function parseModel(str) {\n  str = str.trim();\n  let len = str.length;\n\n  // e.g.\n  // test[0].a\n  // test.a.b\n  if (str.indexOf('[') < 0 || str.lastIndexOf(']') < len - 1) {\n    let dot = str.lastIndexOf('.');\n    if (dot > -1) {\n      return {\n        expr: str.slice(0, dot),\n        key: `${str.slice(dot + 1)}`\n      };\n    } else {\n      return {\n        expr: str,\n        key: null\n      };\n    }\n  }\n\n  /*\n   * e.g.\n   * test[a[b]]\n   */\n\n  let index = 0;\n  let exprStart = 0;\n  let exprEnd = 0;\n\n  let isQuoteStart = function(chr) {\n    return chr === 0x22 || chr === 0x27;\n  };\n\n  let parseString = function(chr) {\n    while (index < len && str.charCodeAt(++index) !== chr) {}\n  };\n\n  let parseBracket = function(chr) {\n    let inBracket = 1;\n    exprStart = index;\n    while (index < len) {\n      chr = str.charCodeAt(++index);\n      if (isQuoteStart(chr)) {\n        parseString(chr);\n        continue;\n      }\n      if (chr === 0x5b) inBracket++;\n      if (chr === 0x5d) inBracket--;\n\n      if (inBracket === 0) {\n        exprEnd = index;\n        break;\n      }\n    }\n  };\n\n  while (index < len) {\n    let chr = str.charCodeAt(++index);\n    if (isQuoteStart(chr)) {\n      parseString(chr);\n    } else if (chr === 0x5b) {\n      parseBracket(chr);\n    }\n  }\n\n  return {\n    expr: str.slice(0, exprStart),\n    key: str.slice(exprStart + 1, exprEnd)\n  };\n}\n"
  },
  {
    "path": "packages/core/weapp/util/next-tick.js",
    "content": "import { handleError } from './error';\nimport {\n  //isIOS,\n  isNative\n} from './../../shared/env';\n\nconst callbacks = [];\nlet pending = false;\n\nfunction flushCallbacks() {\n  pending = false;\n  const copies = callbacks.slice(0);\n  callbacks.length = 0;\n  for (let i = 0; i < copies.length; i++) {\n    copies[i]();\n  }\n}\n\n// Here we have async deferring wrappers using both micro and macro tasks.\n// In < 2.4 we used micro tasks everywhere, but there are some scenarios where\n// micro tasks have too high a priority and fires in between supposedly\n// sequential events (e.g. #4521, #6690) or even between bubbling of the same\n// event (#6566). However, using macro tasks everywhere also has subtle problems\n// when state is changed right before repaint (e.g. #6813, out-in transitions).\n// Here we use micro task by default, but expose a way to force macro task when\n// needed (e.g. in event handlers attached by v-on).\nlet microTimerFunc;\nlet macroTimerFunc;\nlet useMacroTask = false;\n\n// Determine (macro) Task defer implementation.\n// Technically setImmediate should be the ideal choice, but it's only available\n// in IE. The only polyfill that consistently queues the callback after all DOM\n// events triggered in the same loop is by using MessageChannel.\n/* istanbul ignore if */\nif (typeof setImmediate !== 'undefined' && isNative(setImmediate)) {\n  macroTimerFunc = () => {\n    setImmediate(flushCallbacks);\n  };\n} else if (\n  /* eslint-disable no-undef */\n  typeof MessageChannel !== 'undefined' &&\n  (isNative(MessageChannel) ||\n    // PhantomJS\n    MessageChannel.toString() === '[object MessageChannelConstructor]')\n) {\n  const channel = new MessageChannel();\n  const port = channel.port2;\n  channel.port1.onmessage = flushCallbacks;\n  macroTimerFunc = () => {\n    port.postMessage(1);\n  };\n  /* eslint-enable no-undef */\n} else {\n  /* istanbul ignore next */\n  macroTimerFunc = () => {\n    setTimeout(flushCallbacks, 0);\n  };\n}\n\n// Determine MicroTask defer implementation.\n/* istanbul ignore next, $flow-disable-line */\nif (typeof Promise !== 'undefined' && isNative(Promise)) {\n  const p = Promise.resolve();\n  microTimerFunc = () => {\n    p.then(flushCallbacks);\n    // in problematic UIWebViews, Promise.then doesn't completely break, but\n    // it can get stuck in a weird state where callbacks are pushed into the\n    // microtask queue but the queue isn't being flushed, until the browser\n    // needs to do some other work, e.g. handle a timer. Therefore we can\n    // \"force\" the microtask queue to be flushed by adding an empty timer.\n    // if (isIOS) setTimeout(noop)\n  };\n} else {\n  // fallback to macro\n  microTimerFunc = macroTimerFunc;\n}\n\n/**\n * Wrap a function so that if any code inside triggers state change,\n * the changes are queued using a Task instead of a MicroTask.\n */\nexport function withMacroTask(fn) {\n  return (\n    fn._withTask ||\n    (fn._withTask = function() {\n      useMacroTask = true;\n      const res = fn.apply(null, arguments);\n      useMacroTask = false;\n      return res;\n    })\n  );\n}\n\nexport function nextTick(cb, ctx) {\n  let _resolve;\n  callbacks.push(() => {\n    if (cb) {\n      try {\n        cb.call(ctx);\n      } catch (e) {\n        handleError(e, ctx, 'nextTick');\n      }\n    } else if (_resolve) {\n      _resolve(ctx);\n    }\n  });\n  if (!pending) {\n    pending = true;\n    if (useMacroTask) {\n      macroTimerFunc();\n    } else {\n      microTimerFunc();\n    }\n  }\n  // $flow-disable-line\n  if (!cb && typeof Promise !== 'undefined') {\n    return new Promise(resolve => {\n      _resolve = resolve;\n    });\n  }\n}\n\nconst renderCallbacks = [];\n\nexport function renderFlushCallbacks() {\n  const copies = renderCallbacks.slice(0);\n  renderCallbacks.length = 0;\n  for (let i = 0; i < copies.length; i++) {\n    copies[i]();\n  }\n}\n\nexport function renderNextTick(cb, ctx) {\n  let _resolve;\n  renderCallbacks.push(() => {\n    if (cb) {\n      try {\n        cb.call(ctx);\n      } catch (e) {\n        handleError(e, ctx, 'nextTick');\n      }\n    } else if (_resolve) {\n      _resolve(ctx);\n    }\n  });\n\n  if (!cb && typeof Promise !== 'undefined') {\n    return new Promise(resolve => {\n      _resolve = resolve;\n    });\n  }\n}\n"
  },
  {
    "path": "packages/core/weapp/wepy.js",
    "content": "import WepyConstructor from './class/WepyConstructor';\nimport $global from './global';\nimport { initGlobalAPI } from './apis/index';\nimport { config } from './config';\n\nconst wepy = initGlobalAPI(WepyConstructor);\n\nwepy.config = config;\nwepy.global = $global;\nwepy.version = __VERSION__;\n\nexport default wepy;\n"
  },
  {
    "path": "packages/plugin-define/.npmignore",
    "content": "node_modules\n"
  },
  {
    "path": "packages/plugin-define/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n# 2.1.0 (2020-07-04)\n\n**Note:** Version bump only for package @wepy/plugin-define\n\n\n\n\n\n# 2.1.0-alpha.10 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/plugin-define\n\n\n\n\n\n# 2.1.0-alpha.9 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/plugin-define\n\n\n\n\n\n# 2.1.0-alpha.8 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/plugin-define\n\n\n\n\n\n# 2.1.0-alpha.7 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/plugin-define\n\n\n\n\n\n# 2.1.0-alpha.6 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/plugin-define\n\n\n\n\n\n# 2.1.0-alpha.5 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/plugin-define\n\n\n\n\n\n# [2.1.0-alpha.4](https://github.com/Tencent/wepy/compare/v2.1.0-alpha.2...v2.1.0-alpha.4) (2020-06-20)\n\n**Note:** Version bump only for package @wepy/plugin-define\n"
  },
  {
    "path": "packages/plugin-define/README.md",
    "content": "[English](./README_EN.md) | 简体中文\n\n# wepy define plugin\n\n## 安装\n\n```bash\nnpm install @wepy/plugin-define --save-dev\n```\n\n## 配置方式\n\n**wepy.config.js**\n\n```javascript\nconst DefinePlugin = require('@wepy/plugin-define');\n\nmodule.exports = {\n  plugins: [\n    DefinePlugin({\n      BASE_URL: JSON.stringify('http://foobar.com'),\n      'process.env.NODE_ENV': 'development',\n      'typeof window': JSON.stringify('undefined'),\n      DEV: true\n    })\n  ]\n};\n```\n\n## 参考网站\n\n[webpack.DefinePlugin](https://webpack.js.org/plugins/define-plugin/)\n\n\n\n"
  },
  {
    "path": "packages/plugin-define/README_EN.md",
    "content": "English | [简体中文](./README.md)\n\n# wepy define plugin\n\n## Install\n\n```bash\nnpm install @wepy/plugin-define --save-dev\n```\n\n## Configration\n\n**wepy.config.js**\n```javascript\nconst DefinePlugin = require('@wepy/plugin-define');\n\nmodule.exports = {\n  plugins: [\n    DefinePlugin({\n      BASE_URL: JSON.stringify('http://foobar.com'),\n      'process.env.NODE_ENV': 'development',\n      'typeof window': JSON.stringify('undefined'),\n      DEV: true\n    })\n  ]\n};\n```\n\n## Reference\n[webpack.DefinePlugin](https://webpack.js.org/plugins/define-plugin/)\n\n\n\n"
  },
  {
    "path": "packages/plugin-define/index.js",
    "content": "/**\n * Tencent is pleased to support the open source community by making WePY available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n *\n * Licensed under the MIT License (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n * http://opensource.org/licenses/MIT\n * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n */\n\nconst stringifyObj = obj => {\n  return (\n    'Object({' +\n    Object.keys(obj)\n      .map(key => {\n        const code = obj[key];\n        return JSON.stringify(key) + ':' + toCode(code);\n      })\n      .join(',') +\n    '})'\n  );\n};\n\n/**\n * Convert code to a string that evaluates\n * @param {CodeValue} code Code to evaluate\n * @param {Parser} parser Parser\n * @returns {string} code converted to string that evaluates\n */\nconst toCode = code => {\n  if (code === null) {\n    return 'null';\n  }\n  if (code === undefined) {\n    return 'undefined';\n  }\n  if (code instanceof RegExp && code.toString) {\n    return code.toString();\n  }\n  if (typeof code === 'function' && code.toString) {\n    return '(' + code.toString() + ')';\n  }\n  if (typeof code === 'object') {\n    return stringifyObj(code);\n  }\n  return code + '';\n};\n\nexports = module.exports = function DefinePlugin(options = {}) {\n  return function() {\n    this.register('walker-unary-expression-undefined', function(parser, expr, names) {\n      if (expr.operator === 'typeof') {\n        let v = options[`typeof ${names.name}`] || options[`typeof(${names.name})`];\n        if (v) {\n          parser.replacements.push({ expr, value: toCode(v) });\n        }\n      }\n      return [parser, expr, names];\n    });\n    this.register('walker-member-expression-undefined', function(parser, expr, names) {\n      if (options.hasOwnProperty(names.name)) {\n        parser.replacements.push({ expr, value: toCode(options[names.name]) });\n      }\n      return [parser, expr, names];\n    });\n    this.register('walker-identifier-undefined', function(parser, expr) {\n      if (options.hasOwnProperty(expr.name)) {\n        parser.replacements.push({ expr, value: toCode(options[expr.name]) });\n      }\n      return [parser, expr];\n    });\n  };\n};\n"
  },
  {
    "path": "packages/plugin-define/package.json",
    "content": "{\n  \"name\": \"@wepy/plugin-define\",\n  \"version\": \"2.1.0\",\n  \"description\": \"wepy define plugin\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"npm run test:unit && npm run test:integration\",\n    \"test:unit\": \"mocha ./test/*.test.js\",\n    \"test:integration\": \"mocha ./test/*.integration.js\"\n  },\n  \"keywords\": [\n    \"wepy\",\n    \"DefinePlugin\"\n  ],\n  \"author\": {\n    \"name\": \"Gcaufy\"\n  },\n  \"license\": \"MIT\",\n  \"readme\": \"ERROR: No README data found!\",\n  \"_id\": \"@wepy/plugin-define@2.0.4\",\n  \"_commitid\": \"fb07fd4\",\n  \"devDependencies\": {\n    \"@wepy/cli\": \"^2.1.0\"\n  },\n  \"gitHead\": \"5a25776457360bbbbc54a4d059f6bc7c032d5df3\"\n}\n"
  },
  {
    "path": "packages/plugin-define/test/fixtures/expected/app.js",
    "content": "module.exports = {\n  definedVariable: 'http://www.foo.com',\n  inObjectProperty: { BASE_URL: 'http://foo.com' },\n  inString: 'BASE_URL',\n  inTemplateLiterals: 'http://www.bar.com/api/',\n\n  shouldReplaced: 'http://www.bar.com',\n  objectTest: 'development',\n\n  typeofTest: 'undefined',\n  typeofTest2: 'undefined',\n\n  builtinFuncValue: 666\n};\n"
  },
  {
    "path": "packages/plugin-define/test/fixtures/src/app.wpy",
    "content": "<script lang=\"js\">\n  function definedVariable() {\n    let BASE_URL = 'http://www.foo.com';\n    return BASE_URL;\n  }\n\n  const inObjectProperty = {\n    BASE_URL: 'http://foo.com'\n  };\n  const inString = 'BASE_URL';\n\n  function useBuiltinFunc() {\n    let obj = {};\n    let b = 1;\n\n    __defineSetter__.call(obj, 'a', function (val) {\n      b = val;\n    });\n    obj.a = 666;\n\n    return b;\n  }\n\n  module.exports = {\n    definedVariable: definedVariable(),\n    inObjectProperty,\n    inString,\n    inTemplateLiterals: `${BASE_URL}/api/`,\n\n    shouldReplaced: BASE_URL,\n\n    objectTest: process.env.NODE_ENV,\n\n    typeofTest: typeof window,\n    typeofTest2: typeof (window),\n\n    builtinFuncValue: useBuiltinFunc()\n  };\n\n</script>\n"
  },
  {
    "path": "packages/plugin-define/test/fixtures/weapp/.gitignore",
    "content": "*\n!.gitignore\n"
  },
  {
    "path": "packages/plugin-define/test/fixtures/wepy.config.js",
    "content": "const DefinePlugin = require('../../index');\n\nmodule.exports = {\n  plugins: [\n    DefinePlugin({\n      BASE_URL: JSON.stringify('http://www.bar.com')\n    }),\n    DefinePlugin({\n      'process.env.NODE_ENV': JSON.stringify('development'),\n      'typeof window': JSON.stringify('undefined'),\n    })\n  ],\n}\n"
  },
  {
    "path": "packages/plugin-define/test/index.integration.js",
    "content": "const path = require('path');\nconst { exec } = require('child_process');\nconst expect = require('chai').expect;\n\ndescribe('plugin-define integration', function() {\n  it('full build', function(done) {\n    this.timeout(10000);\n\n    let wepyPath = path.resolve(process.cwd(), '../cli/bin/wepy.js');\n\n    exec(`cd test/fixtures && node ${wepyPath} build`, function(error) {\n      if (error) {\n        throw error;\n      }\n\n      expect(require('./fixtures/weapp/app.js')).to.deep.equal(require('./fixtures/expected/app.js'));\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "packages/plugin-define/test/index.test.js",
    "content": "const expect = require('chai').expect;\nconst Hook = require('@wepy/cli/core/hook');\nconst PluginDefine = require('../index');\n\nfunction createCompile(pluginOpt) {\n  let instance = new Hook();\n  PluginDefine(pluginOpt).call(instance);\n  instance.parser = {\n    replacements: []\n  };\n  return instance;\n}\n\ndescribe('plugin-define', function() {\n  it('walker-unary-expression-undefined', function() {\n    const names = {\n      name: 'window'\n    };\n    // typeof window generate the same ast with typeof(window)\n    // let a = typeof window;\n    const unaryExpr = {\n      type: 'UnaryExpression',\n      start: 8,\n      end: 21,\n      operator: 'typeof',\n      prefix: true,\n      argument: {\n        type: 'Identifier',\n        start: 15,\n        end: 21,\n        name: 'window'\n      }\n    };\n\n    let compile = createCompile();\n\n    let args = compile.hookSeq('walker-unary-expression-undefined', compile.parser, unaryExpr, names);\n    expect(args[0].replacements.length).to.equal(0);\n\n    compile = createCompile({\n      'typeof window': JSON.stringify('xyz')\n    });\n    args = compile.hookSeq('walker-unary-expression-undefined', compile.parser, unaryExpr, names);\n    expect(args[0].replacements[0].expr).to.equal(unaryExpr);\n    expect(args[0].replacements[0].value).to.equal('\"xyz\"');\n\n    // delete x.y\n    const deleteUnaryExpr = {\n      type: 'UnaryExpression',\n      start: 0,\n      end: 10,\n      operator: 'delete',\n      prefix: true,\n      argument: {\n        type: 'MemberExpression',\n        start: 7,\n        end: 10,\n        object: {\n          type: 'Identifier',\n          start: 7,\n          end: 8,\n          name: 'x'\n        },\n        property: {\n          type: 'Identifier',\n          start: 9,\n          end: 10,\n          name: 'y'\n        },\n        computed: false\n      }\n    };\n\n    compile = createCompile({\n      'x.y': JSON.stringify('xyz')\n    });\n    args = compile.hookSeq('walker-unary-expression-undefined', compile.parser, deleteUnaryExpr, { name: 'x.y' });\n    expect(args[0].replacements.length).to.equal(0);\n  });\n\n  it('walker-member-expression-undefined', function() {\n    const memberExpr = {\n      type: 'MemberExpression',\n      start: 8,\n      end: 28,\n      object: {\n        type: 'MemberExpression',\n        start: 8,\n        end: 19,\n        object: {\n          type: 'Identifier',\n          start: 8,\n          end: 15,\n          name: 'process'\n        },\n        property: {\n          type: 'Identifier',\n          start: 16,\n          end: 19,\n          name: 'env'\n        },\n        computed: false\n      },\n      property: {\n        type: 'Identifier',\n        start: 20,\n        end: 28,\n        name: 'NODE_ENV'\n      },\n      computed: false\n    };\n\n    const names = {\n      name: 'process.env.NODE_ENV'\n    };\n\n    let compile = createCompile();\n\n    let args = compile.hookSeq('walker-member-expression-undefined', compile.parser, memberExpr, names);\n    expect(args[0].replacements.length).to.equal(0);\n\n    compile = createCompile({\n      'process.env.NODE_ENV': JSON.stringify('dev')\n    });\n    args = compile.hookSeq('walker-member-expression-undefined', compile.parser, memberExpr, names);\n    expect(args[0].replacements[0].expr).to.equal(memberExpr);\n    expect(args[0].replacements[0].value).to.equal('\"dev\"');\n  });\n\n  it('walker-identifier-undefined', function() {\n    const memberExpr = {\n      type: 'Identifier',\n      start: 8,\n      end: 19,\n      name: 'DEFINED_VAR'\n    };\n\n    const names = {\n      name: 'DEFINED_VAR'\n    };\n\n    let compile = createCompile();\n\n    let args = compile.hookSeq('walker-identifier-undefined', compile.parser, memberExpr, names);\n    expect(args[0].replacements.length).to.equal(0);\n\n    compile = createCompile({\n      DEFINED_VAR: JSON.stringify('something')\n    });\n    args = compile.hookSeq('walker-identifier-undefined', compile.parser, memberExpr, names);\n    expect(args[0].replacements[0].expr).to.equal(memberExpr);\n    expect(args[0].replacements[0].value).to.equal('\"something\"');\n  });\n\n  it('test different values', function() {\n    let compile, args;\n\n    compile = createCompile({\n      V_NULL: null\n    });\n    args = compile.hookSeq('walker-member-expression-undefined', compile.parser, null, { name: 'V_NULL' });\n    expect(args[0].replacements[0].value).to.equal('null');\n\n    compile = createCompile({\n      V_UNDEFINED: undefined\n    });\n    args = compile.hookSeq('walker-member-expression-undefined', compile.parser, null, { name: 'V_UNDEFINED' });\n    expect(args[0].replacements[0].value).to.equal('undefined');\n\n    const reg = new RegExp('[0-9a-z]', 'ig');\n    compile = createCompile({\n      V_REGEXP: reg\n    });\n    args = compile.hookSeq('walker-member-expression-undefined', compile.parser, null, { name: 'V_REGEXP' });\n    expect(args[0].replacements[0].value).to.equal(reg.toString());\n\n    const func = () => func(1);\n    compile = createCompile({\n      V_FUNCTION: func\n    });\n    args = compile.hookSeq('walker-member-expression-undefined', compile.parser, null, { name: 'V_FUNCTION' });\n    expect(args[0].replacements[0].value).to.equal('(' + func.toString() + ')');\n\n    const obj = { a: 1, b: 4 };\n    compile = createCompile({\n      V_OBJECT: obj\n    });\n    args = compile.hookSeq('walker-member-expression-undefined', compile.parser, null, { name: 'V_OBJECT' });\n    const stringObj = args[0].replacements[0].value;\n    const toObj = new Function('return ' + stringObj)();\n    expect(JSON.stringify(obj)).to.equal(JSON.stringify(toObj));\n  });\n});\n"
  },
  {
    "path": "packages/plugin-eslint/.npmignore",
    "content": "node_modules\n"
  },
  {
    "path": "packages/plugin-eslint/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n# 2.1.0 (2020-07-04)\n\n**Note:** Version bump only for package @wepy/plugin-eslint\n\n\n\n\n\n# 2.1.0-alpha.10 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/plugin-eslint\n\n\n\n\n\n# 2.1.0-alpha.9 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/plugin-eslint\n\n\n\n\n\n# 2.1.0-alpha.8 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/plugin-eslint\n\n\n\n\n\n# 2.1.0-alpha.7 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/plugin-eslint\n\n\n\n\n\n# 2.1.0-alpha.6 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/plugin-eslint\n\n\n\n\n\n# 2.1.0-alpha.5 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/plugin-eslint\n\n\n\n\n\n# [2.1.0-alpha.4](https://github.com/Tencent/wepy/compare/v2.1.0-alpha.2...v2.1.0-alpha.4) (2020-06-20)\n\n**Note:** Version bump only for package @wepy/plugin-eslint\n"
  },
  {
    "path": "packages/plugin-eslint/README.md",
    "content": "# wepy eslint 插件\n\n## 安装\n\n```bash\nnpm install @wepy/plugin-eslint --save-dev\n```\n\n## 配置`wepy.config.js`\n\n```javascript\nconst eslint = require('@wepy/plugin-eslint');\n\nmodule.exports = {\n  plugins: [\n    eslint({\n      // options\n    })\n  ]\n};\n```\n\n## 参数说明\n\n你提供的配置选项 ```options``` 将传递给 ```CLIEngine```处理，有关 ```options``` 的更多详细信息，请参阅[eslint文档](https://eslint.org/docs/developer-guide/nodejs-api#cliengine)。\n\n#### quiet (默认值: ```false```)\n\n如果此选项设置为true，插件将仅处理和报告错误，忽略警告\n\n```javascript\nconst eslint = require('@wepy/plugin-eslint');\n\nmodule.exports = {\n  plugins: [\n    eslint({\n      quiet: true\n    })\n  ]\n};\n```\n#### fix (default: ```false```)\n\n启用 ```ESLint``` 自动修复功能\n\n注意：此选项将更改源文件\n\n#### output (default: ```true```)\n\n启用 ```ESLint```\n\n#### eslintPath (default: ```eslint```)\n\n用于 ```linting``` 的 ```ESLint``` 实例的路径\n\n#### formatter (default: eslint stylish formatter)\n\n用于格式化 ```ESLint``` 输出，选项值接收字符串或者函数\n\n```javascript\nconst eslint = require('@wepy/plugin-eslint');\n\nmodule.exports = {\n  plugins: [\n    eslint({\n      // default value\n      formatter: require('eslint/lib/formatters/stylish'),\n\n      // community formatter\n      formatter: require('eslint-friendly-formatter'),\n\n      // custom formatter\n      formatter: function(results) {\n        // `results` format is available here\n        // http://eslint.org/docs/developer-guide/nodejs-api.html#executeonfiles()\n\n        // you should return a string\n        // DO NOT USE console.*() directly !\n        return 'OUTPUT'\n      }\n    })\n  ]\n};\n```\n"
  },
  {
    "path": "packages/plugin-eslint/index.js",
    "content": "/**\n * Tencent is pleased to support the open source community by making WePY available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n *\n * Licensed under the MIT License (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n * http://opensource.org/licenses/MIT\n * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n */\n\nconst objectHash = require('object-hash');\nconst engines = {};\n\nlet cached = {}; // ESLint line cache\n\nfunction lint(engine, file) {\n  return engine.executeOnFiles(file);\n}\n\nfunction printLinterOutput(res, options) {\n  if (res.warningCount && options.quiet) {\n    res.warningCount = 0;\n    res.results.forEach(item => {\n      item.warningCount = 0;\n      item.messages = item.messages.filter(message => message.severity !== 1);\n    });\n  }\n\n  // if enabled, use eslint auto-fixing where possible\n  if (options.fix && (res.fixableErrorCount > 0 || res.fixableWarningCount)) {\n    const eslint = require(options.eslintPath);\n    eslint.CLIEngine.outputFixes(res);\n  }\n  // removed file ignore warning\n  res.results.forEach(item => {\n    item.messages = item.messages.filter(msg => msg.message.indexOf('File ignored') === -1);\n  });\n\n  if (res.errorCount || res.warningCount) {\n    const fmt = options.formatter(res.results);\n\n    if (fmt && options.output) {\n      // eslint-disable-next-line\n      console.log(fmt);\n    }\n  }\n}\n\nexports = module.exports = function(options = {}) {\n  return function() {\n    // Clear the eslint cache when watch process done\n    this.register('process-clear', function() {\n      cached = {};\n    });\n\n    // Registe before parse hook to every process\n    ['wxs', 'config', 'script', 'template'].forEach(type => {\n      this.register('before-wepy-parser-' + type, function({ node, ctx } = {}) {\n        // wpy files goes here four times.\n        if (cached[ctx.file]) {\n          return Promise.resolve({ node, ctx });\n        }\n\n        if (ctx.npm) {\n          return Promise.resolve({ node, ctx });\n        }\n\n        cached[ctx.file] = 1;\n\n        options = Object.assign(\n          {},\n          {\n            useEslintrc: true,\n            eslintPath: 'eslint',\n            quiet: false,\n            output: true,\n            extensions: ['.js', this.options.wpyExt || '.wpy']\n          },\n          options\n        );\n\n        // Create singleton engine per config\n        const optionsHash = objectHash(options);\n        if (!engines[optionsHash]) {\n          const eslint = require(options.eslintPath);\n          engines[optionsHash] = new eslint.CLIEngine(options);\n        }\n\n        // Create eslint formatter\n        if (typeof options.formatter === 'string') {\n          try {\n            options.formatter = require(options.formatter);\n\n            if (\n              options.formatter &&\n              typeof options.formatter !== 'function' &&\n              typeof options.formatter.default === 'function'\n            ) {\n              options.formatter = options.formatter.default;\n            }\n          } catch (_) {\n            // ignore\n          }\n        }\n\n        if (!options.formatter || typeof options.formatter !== 'function') {\n          const userEslintPath = options.eslintPath;\n          if (userEslintPath) {\n            try {\n              options.formatter = require(userEslintPath + '/lib/formatters/stylish');\n            } catch (e) {\n              options.formatter = require('eslint/lib/formatters/stylish');\n            }\n          } else {\n            options.formatter = require('eslint/lib/formatters/stylish');\n          }\n        }\n\n        const engine = engines[optionsHash];\n\n        printLinterOutput(lint(engine, [ctx.file]), options);\n\n        return Promise.resolve({ node, ctx });\n      });\n    });\n  };\n};\n"
  },
  {
    "path": "packages/plugin-eslint/package.json",
    "content": "{\n  \"name\": \"@wepy/plugin-eslint\",\n  \"version\": \"2.1.0\",\n  \"description\": \"wepy eslint\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"keywords\": [\n    \"wepy\",\n    \"eslint\"\n  ],\n  \"author\": {\n    \"name\": \"dlhandsome\"\n  },\n  \"license\": \"MIT\",\n  \"peerDependencies\": {\n    \"eslint\": \">=1.6.0 <6.0.0\"\n  },\n  \"dependencies\": {\n    \"object-hash\": \"^1.3.1\"\n  },\n  \"readme\": \"ERROR: No README data found!\",\n  \"_id\": \"@wepy/plugin-eslint@0.1.5\",\n  \"_commitid\": \"251e67f\",\n  \"gitHead\": \"5a25776457360bbbbc54a4d059f6bc7c032d5df3\"\n}\n"
  },
  {
    "path": "packages/plugin-eslint/test/index.test.js",
    "content": "// Todo\n"
  },
  {
    "path": "packages/plugin-uglifyjs/.npmignore",
    "content": "node_modules\n"
  },
  {
    "path": "packages/plugin-uglifyjs/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n# 2.1.0 (2020-07-04)\n\n**Note:** Version bump only for package @wepy/plugin-uglifyjs\n\n\n\n\n\n# 2.1.0-alpha.10 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/plugin-uglifyjs\n\n\n\n\n\n# 2.1.0-alpha.9 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/plugin-uglifyjs\n\n\n\n\n\n# 2.1.0-alpha.8 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/plugin-uglifyjs\n\n\n\n\n\n# 2.1.0-alpha.7 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/plugin-uglifyjs\n\n\n\n\n\n# 2.1.0-alpha.6 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/plugin-uglifyjs\n\n\n\n\n\n# 2.1.0-alpha.5 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/plugin-uglifyjs\n\n\n\n\n\n# [2.1.0-alpha.4](https://github.com/Tencent/wepy/compare/v2.1.0-alpha.2...v2.1.0-alpha.4) (2020-06-20)\n\n**Note:** Version bump only for package @wepy/plugin-uglifyjs\n"
  },
  {
    "path": "packages/plugin-uglifyjs/README.md",
    "content": "# wepy uglifyjs 插件\n\n## 安装\n\n```bash\nnpm install @wepy/plugin-uglifyjs uglify-js --save-dev\n```\n\n## 配置`wepy.config.js`\n\n```javascript\nconst PluginUglifyjs = require('@wepy/plugin-uglifyjs');\n\nmodule.exports = {\n  plugins: [\n    PluginUglifyjs({\n    // options\n    })\n  ]\n};\n```\n\n## 参数说明\n\n你提供的配置选项 ```options``` 将传递给 ```UglifyJS```处理，有关 ```options``` 的更多详细信息，请参阅[UglifyJS文档](https://github.com/mishoo/UglifyJS2#minify-options)。\n\n\n"
  },
  {
    "path": "packages/plugin-uglifyjs/index.js",
    "content": "/**\n * Tencent is pleased to support the open source community by making WePY available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n *\n * Licensed under the MIT License (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n * http://opensource.org/licenses/MIT\n * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n */\n\nconst UglifyJS = require('uglify-js');\nconst path = require('path');\n\n/*\n * To human readable size\n */\nfunction formatSizeUnits(bytes) {\n  if (bytes >= 1073741824) {\n    bytes = (bytes / 1073741824).toFixed(2) + ' GB';\n  } else if (bytes >= 1048576) {\n    bytes = (bytes / 1048576).toFixed(2) + ' MB';\n  } else if (bytes >= 1024) {\n    bytes = (bytes / 1024).toFixed(2) + ' KB';\n  } else if (bytes > 1) {\n    bytes = bytes + ' bytes';\n  } else if (bytes === 1) {\n    bytes = bytes + ' byte';\n  } else {\n    bytes = '0 bytes';\n  }\n  return bytes;\n}\n\nlet totalSize = 0;\nlet totalFile = 0;\nlet totalMinSize = 0;\n\nexports = module.exports = function(options = {}) {\n  return function() {\n    this.register('process-done', function() {\n      this.logger.info(\n        'uglifyjs',\n        `Compressed File: ${totalFile}, Original Size: ${formatSizeUnits(\n          totalSize\n        )}, Compressed Size: ${formatSizeUnits(totalMinSize)}, Ratio: ${(totalMinSize / totalSize).toFixed(2)}%`\n      );\n\n      // Clear data\n      totalFile = 0;\n      totalSize = 0;\n      totalMinSize = 0;\n    });\n\n    this.register('output-file', function({ filename, code, encoding }) {\n      this.logger.silly('uglifyjs', 'File: ' + filename);\n\n      let ext = path.extname(filename);\n      if (ext !== '.js') {\n        return { filename, code, encoding };\n      }\n\n      totalFile++;\n      totalSize += code.length;\n\n      let result = UglifyJS.minify({ [filename]: code }, options);\n\n      if (result.error) {\n        let pos = {\n          line: result.error.line,\n          column: result.error.col\n        };\n        throw {\n          handler: 'script',\n          error: {\n            filename: result.error.filename,\n            code: code,\n            type: 'error',\n            message: result.error.message,\n            title: 'uglifyjs'\n          },\n          pos: {\n            start: pos,\n            end: pos\n          }\n        };\n      } else {\n        totalMinSize += result.code.length;\n        return Promise.resolve({\n          filename,\n          code: result.code,\n          encoding\n        });\n      }\n    });\n  };\n};\n"
  },
  {
    "path": "packages/plugin-uglifyjs/package.json",
    "content": "{\n  \"name\": \"@wepy/plugin-uglifyjs\",\n  \"version\": \"2.1.0\",\n  \"description\": \"wepy uglifyjs\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"keywords\": [\n    \"wepy\",\n    \"uglifyjs\"\n  ],\n  \"author\": {\n    \"name\": \"Gcaufy\"\n  },\n  \"license\": \"MIT\",\n  \"peerDependencies\": {\n    \"uglify-js\": \"^3.4.9\"\n  },\n  \"readme\": \"ERROR: No README data found!\",\n  \"_id\": \"@wepy/plugin-uglifyjs@0.0.3\",\n  \"_commitid\": \"4a8435b\",\n  \"gitHead\": \"5a25776457360bbbbc54a4d059f6bc7c032d5df3\"\n}\n"
  },
  {
    "path": "packages/plugin-uglifyjs/test/index.test.js",
    "content": "// Todo\n"
  },
  {
    "path": "packages/redux/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n# 2.1.0 (2020-07-04)\n\n**Note:** Version bump only for package @wepy/redux\n\n\n\n\n\n# 2.1.0-alpha.10 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/redux\n\n\n\n\n\n# 2.1.0-alpha.9 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/redux\n\n\n\n\n\n# 2.1.0-alpha.8 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/redux\n\n\n\n\n\n# 2.1.0-alpha.7 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/redux\n\n\n\n\n\n# 2.1.0-alpha.6 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/redux\n\n\n\n\n\n# 2.1.0-alpha.5 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/redux\n\n\n\n\n\n# [2.1.0-alpha.4](https://github.com/Tencent/wepy/compare/v2.1.0-alpha.2...v2.1.0-alpha.4) (2020-06-20)\n\n**Note:** Version bump only for package @wepy/redux\n"
  },
  {
    "path": "packages/redux/README.md",
    "content": "[English](./README_EN.md) | 简体中文\n\n# WePY 2.0中的Redux\n\n## 安装\n\n```\nnpm install @wepy/redux redux --save\n```\n\n## 用法\n\n1. 安装Redux\n\n```\n// app.wpy\nimport wepy from '@wepy/core';\nimport wepyRedux from '@wepy/redux';\n\nwepy.use(wepyRedux);\n```\n\n2. 初始化 Store\n\n```\n// ~/store.js\nimport { createStore, combineReducers } from 'redux';\n\nexport default createStore(combineReducers({\n  counter (state = { num: 0 }, action) {\n    switch (action.type) {\n      case 'ADD':\n        return {\n          ...state,\n          num: state.num + 1\n        };\n    }\n    return state;\n  }\n}));\n```\n\n3. 映射到组件\n\n```\n// ~/counter.wpy\n<template>\n  <div> {{counter.num}} </div>\n  <button @tap=\"increment\"> Increment </button>\n</template>\n<script>\nimport wepy from '@wepy/core';\nimport { mapState } from '@wepy/redux';\nimport store from './store'\n\nwepy.component({\n  store,\n  computed: {\n    ...mapState([ 'counter' ])\n  },\n  methods: {\n    increment () {\n      this.$store.dispatch({ type: 'ADD' })\n    }\n  }\n})\n```\n\n## API\n\n* mapState(states) \n\n  状态：字符串/数组/K-V对象.。需要映射的 state 属性。如:\n\n  ```\n  mapState('counter')\n  mapState(['counter', 'somethingelse'])\n  mapState({ alias: 'counter' })\n  mapState({ \n    num: function (state) {\n      return state.counter.num;\n    } \n  })\n  ```\n\n* mapActions(actions)\n\n  actions: K-V Object. 需要映射的 action 。如：\n\n  ```\n  mapActions({ add: 'ADD' });\n  mapActions({ \n    add: function () {\n      return {\n        type: 'ADD'\n      };\n    } \n  });\n  ```\n\n## Document \n\n[https://redux.jg.org](https://redux.js.org)"
  },
  {
    "path": "packages/redux/README_EN.md",
    "content": "English | [简体中文](./README.md)\n\n# Redux in WePY 2.0 \n\n## Install\n\n```\nnpm install @wepy/redux redux --save\n```\n\n## Usage\n\n1. Install Redux\n```\n// app.wpy\nimport wepy from '@wepy/core';\nimport wepyRedux from '@wepy/redux';\n\nwepy.use(wepyRedux);\n```\n\n2. Initialize a store\n```\n// ~/store.js\nimport { createStore, combineReducers } from 'redux';\n\nexport default createStore(combineReducers({\n  counter (state = { num: 0 }, action) {\n    switch (action.type) {\n      case 'ADD':\n        return {\n          ...state,\n          num: state.num + 1\n        };\n    }\n    return state;\n  }\n}));\n```\n\n3. Map to Component\n```\n// ~/counter.wpy\n<template>\n  <div> {{counter.num}} </div>\n  <button @tap=\"increment\"> Increment </button>\n</template>\n<script>\nimport wepy from '@wepy/core';\nimport { mapState } from '@wepy/redux';\nimport store from './store'\n\nwepy.component({\n  store,\n  computed: {\n    ...mapState([ 'counter' ])\n  },\n  methods: {\n    increment () {\n      this.$store.dispatch({ type: 'ADD' })\n    }\n  }\n})\n```\n\n## API\n\n* mapState(states) \n\n    states: String/Array/K-V Object. 需要映射的 state 属性。如:\n    ```\n    mapState('counter')\n    mapState(['counter', 'somethingelse'])\n    mapState({ alias: 'counter' })\n    mapState({ \n      num: function (state) {\n        return state.counter.num;\n      } \n    })\n    ```\n* mapActions(actions)\n\n    actions: K-V Object. 需要映射的 action 。如：\n    ```\n    mapActions({ add: 'ADD' });\n    mapActions({ \n      add: function () {\n        return {\n          type: 'ADD'\n        };\n      } \n    });\n    ```\n\n## Document \n[https://redux.jg.org](https://redux.js.org)\n"
  },
  {
    "path": "packages/redux/dist/index.js",
    "content": "'use strict';\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nfunction normalizeMap(map) {\n  if (typeof map === 'string') { map = [map]; }\n  return Array.isArray(map) ? map.map(function (k) { return ({ key: k, val: k }); }) : Object.keys(map).map(function (k) { return ({ key: k, val: map[k] }); });\n}\n\nvar mapState = function(states) {\n  var res = Object.create(null);\n  var resValueMap = Object.create(null);\n  normalizeMap(states).forEach(function (ref) {\n    var key = ref.key;\n    var val = ref.val;\n\n    /**\n     * resValueMap 记录由 mapState 产生的值\n     * 在初始化时将其变成 observer 的\n     */\n    resValueMap[key] = Object.preventExtensions({ value: undefined });\n    res[key] = function mappedState() {\n      var state = this.$store.getState();\n      var value = typeof val === 'function' ? val.call(this, state) : state[val];\n\n      // 利用 redux state 每次改变都会返回一个新 state 的特性，只需做引用比较\n      var resValueMap = res[key][this.$id];\n      if (resValueMap[key].value !== value) {\n        resValueMap[key] = Object.preventExtensions({ value: value });\n      }\n      return resValueMap[key].value;\n    };\n    res[key].redux = true;\n    res[key].resValueMap = resValueMap;\n  });\n  return res;\n};\n\nvar mapActions = function(actions) {\n  var res = {};\n  normalizeMap(actions).forEach(function (ref) {\n    var key = ref.key;\n    var val = ref.val;\n\n    res[key] = function mappedAction() {\n      var args = [], len = arguments.length;\n      while ( len-- ) args[ len ] = arguments[ len ];\n\n      if (!this.$store) {\n        // eslint-disable-next-line\n        console.warn((\"[@wepy/redux] action \\\"\" + key + \"\\\" do not work, if store is not defined.\"));\n        return;\n      }\n      var dispatchParam;\n      if (typeof val === 'string') {\n        dispatchParam = {\n          type: val,\n          payload: args.length > 1 ? args : args[0]\n        };\n      } else {\n        dispatchParam = typeof val === 'function' ? val.apply(this.$store, args) : val;\n      }\n      return this.$store.dispatch(dispatchParam);\n    };\n  });\n  return res;\n};\n\nfunction wepyInstall(wepy) {\n  wepy.mixin({\n    beforeCreate: function beforeCreate() {\n      var options = this.$options;\n      if (options.store) {\n        this.$store = typeof options.store === 'function' ? options.store() : options.store;\n      } else if (options.parent && options.parent.$store) {\n        this.$store = options.parent.$store;\n      }\n      if (checkReduxComputed(this.$options)) {\n        if (!this.$store) {\n          // eslint-disable-next-line\n          console.warn(\"[@wepy/redux] state do not work, if store is not defined.\");\n          return;\n        }\n        var ref = this.$options;\n        var computed = ref.computed;\n        var keys = Object.keys(computed);\n        var resValueMap;\n        for (var i = 0; i < keys.length; i++) {\n          if ('resValueMap' in computed[keys[i]]) {\n            if (!resValueMap) {\n              resValueMap = Object.assign({}, computed[keys[i]].resValueMap);\n            }\n            computed[keys[i]][this.$id] = resValueMap;\n          }\n        }\n        wepy.observe({\n          vm: this,\n          key: '',\n          value: resValueMap,\n          parent: '',\n          root: true\n        });\n      }\n    },\n\n    created: function created() {\n      var this$1 = this;\n\n      if (!checkReduxComputed(this.$options)) {\n        return;\n      }\n      var store = this.$store;\n      var ref = this.$options;\n      var computed = ref.computed;\n      this.$unsubscribe = store.subscribe(function () {\n        var keys = Object.keys(computed);\n        for (var i = 0; i < keys.length; i++) {\n          if ('redux' in computed[keys[i]]) {\n            this$1._computedWatchers[keys[i]].get();\n          }\n        }\n      });\n    },\n\n    detached: function detached() {\n      this.$unsubscribe && this.$unsubscribe();\n    }\n  });\n}\n\nfunction checkReduxComputed(options) {\n  if (!('computed' in options)) {\n    return false;\n  }\n  var computed = options.computed;\n  var keys = Object.keys(computed);\n  for (var i = 0; i < keys.length; i++) {\n    if ('redux' in computed[keys[i]]) {\n      return true;\n    }\n  }\n  return false;\n}\n\nvar index = {\n  install: wepyInstall,\n  version: \"2.0.3\"\n};\n\nexports.default = index;\nexports.mapState = mapState;\nexports.mapActions = mapActions;\n"
  },
  {
    "path": "packages/redux/helper.js",
    "content": "function normalizeMap(map) {\n  if (typeof map === 'string') map = [map];\n  return Array.isArray(map) ? map.map(k => ({ key: k, val: k })) : Object.keys(map).map(k => ({ key: k, val: map[k] }));\n}\n\nexport const mapState = function(states) {\n  const res = Object.create(null);\n  const resValueMap = Object.create(null);\n  normalizeMap(states).forEach(({ key, val }) => {\n    /**\n     * resValueMap 记录由 mapState 产生的值\n     * 在初始化时将其变成 observer 的\n     */\n    resValueMap[key] = Object.preventExtensions({ value: undefined });\n    res[key] = function mappedState() {\n      const state = this.$store.getState();\n      const value = typeof val === 'function' ? val.call(this, state) : state[val];\n\n      // 利用 redux state 每次改变都会返回一个新 state 的特性，只需做引用比较\n      const resValueMap = res[key][this.$id];\n      if (resValueMap[key].value !== value) {\n        resValueMap[key] = Object.preventExtensions({ value });\n      }\n      return resValueMap[key].value;\n    };\n    res[key].redux = true;\n    res[key].resValueMap = resValueMap;\n  });\n  return res;\n};\n\nexport const mapActions = function(actions) {\n  const res = {};\n  normalizeMap(actions).forEach(({ key, val }) => {\n    res[key] = function mappedAction(...args) {\n      if (!this.$store) {\n        // eslint-disable-next-line\n        console.warn(`[@wepy/redux] action \"${key}\" do not work, if store is not defined.`);\n        return;\n      }\n      let dispatchParam;\n      if (typeof val === 'string') {\n        dispatchParam = {\n          type: val,\n          payload: args.length > 1 ? args : args[0]\n        };\n      } else {\n        dispatchParam = typeof val === 'function' ? val.apply(this.$store, args) : val;\n      }\n      return this.$store.dispatch(dispatchParam);\n    };\n  });\n  return res;\n};\n"
  },
  {
    "path": "packages/redux/index.js",
    "content": "import { mapState, mapActions } from './helper';\nimport install from './install';\n\nexport default {\n  install,\n  version: __VERSION__\n};\nexport { mapState, mapActions };\n"
  },
  {
    "path": "packages/redux/install.js",
    "content": "export default function wepyInstall(wepy) {\n  wepy.mixin({\n    beforeCreate() {\n      const options = this.$options;\n      if (options.store) {\n        this.$store = typeof options.store === 'function' ? options.store() : options.store;\n      } else if (options.parent && options.parent.$store) {\n        this.$store = options.parent.$store;\n      }\n      if (checkReduxComputed(this.$options)) {\n        if (!this.$store) {\n          // eslint-disable-next-line\n          console.warn(`[@wepy/redux] state do not work, if store is not defined.`);\n          return;\n        }\n        const { computed } = this.$options;\n        const keys = Object.keys(computed);\n        let resValueMap;\n        for (let i = 0; i < keys.length; i++) {\n          if ('resValueMap' in computed[keys[i]]) {\n            if (!resValueMap) {\n              resValueMap = { ...computed[keys[i]].resValueMap };\n            }\n            computed[keys[i]][this.$id] = resValueMap;\n          }\n        }\n        wepy.observe({\n          vm: this,\n          key: '',\n          value: resValueMap,\n          parent: '',\n          root: true\n        });\n      }\n    },\n\n    created() {\n      if (!checkReduxComputed(this.$options)) {\n        return;\n      }\n      const store = this.$store;\n      const { computed } = this.$options;\n      this.$unsubscribe = store.subscribe(() => {\n        const keys = Object.keys(computed);\n        for (let i = 0; i < keys.length; i++) {\n          if ('redux' in computed[keys[i]]) {\n            this._computedWatchers[keys[i]].get();\n          }\n        }\n      });\n    },\n\n    detached() {\n      this.$unsubscribe && this.$unsubscribe();\n    }\n  });\n}\n\nfunction checkReduxComputed(options) {\n  if (!('computed' in options)) {\n    return false;\n  }\n  const { computed } = options;\n  const keys = Object.keys(computed);\n  for (let i = 0; i < keys.length; i++) {\n    if ('redux' in computed[keys[i]]) {\n      return true;\n    }\n  }\n  return false;\n}\n"
  },
  {
    "path": "packages/redux/package.json",
    "content": "{\n  \"name\": \"@wepy/redux\",\n  \"version\": \"2.1.0\",\n  \"description\": \"Redux in WePY\",\n  \"main\": \"dist/index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/Tencent/wepy.git\"\n  },\n  \"keywords\": [\n    \"Redux\",\n    \"WePY\"\n  ],\n  \"author\": {\n    \"name\": \"Gcaufy\",\n    \"email\": \"gcaufy@gmail.com\"\n  },\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/Tencent/wepy/issues\"\n  },\n  \"homepage\": \"https://github.com/Tencent/wepy#readme\",\n  \"readme\": \"README.md\",\n  \"_id\": \"@wepy/redux@2.0.3\",\n  \"_commitid\": \"a423f8d\",\n  \"gitHead\": \"5a25776457360bbbbc54a4d059f6bc7c032d5df3\"\n}\n"
  },
  {
    "path": "packages/router/README.md",
    "content": "\n**Coming soon**\n\n\n* [Usage](./doc/usage.md)\n* [配置](./doc/config.md)\n* [导航守卫](./doc/guard.md)\n* API\n    * [router](./doc/router.md)\n    * [实例](./doc/instance.md)\n"
  },
  {
    "path": "packages/router/core/config.js",
    "content": "/**\n * @desc\n * @author wudi@supermonkey.com.cn\n * @createDate 2019/11/18\n */\nconst config = {\n  homePage: '',\n  tabPages: [],\n  routeMap: {}\n}\n\nfunction setConfig(obj) {\n  Object.assign(config, obj)\n}\n\nexport { setConfig }\n\nexport default config\n"
  },
  {
    "path": "packages/router/core/createRouter.js",
    "content": "/**\n * @desc\n * @author wudi@supermonkey.com.cn\n * @createDate 2019/11/18\n */\nimport guard, { createRouterGuard } from './guard'\nimport getRealPageInfo from './utils/getRealPageInfo'\nimport { setConfig } from './config'\nimport routeManager from './routeManager'\nimport routerApi from './routerApi'\n\n/**\n * 创建路由实例\n * @param config 路由配置\n */\nexport default function createRouter(config) {\n  config['routeMap'] = normalizeRouteMap(config.routeMap)\n  setConfig(config)\n\n  return {\n    getRealPageInfo,\n    ...config,\n    ...routerApi,\n    get currentVm() {\n      return routeManager.currentVm\n    },\n    get route() {\n      return routeManager.route\n    },\n    beforeEach: cb => guard.globalGuard.beforeEach(cb),\n    beforeResolve: cb => guard.globalGuard.beforeResolve(cb),\n    afterEach: cb => guard.globalGuard.afterEach(cb)\n  }\n\n  function normalizeRouteMap(routeMap) {\n    const normalizeRouteMap = {}\n\n    for (const key in routeMap) {\n      if (!guard.hasInRouterGuardMap(key)) {\n        guard.updateRouterGuardMap(createRouterGuard(key))\n      }\n\n      if (typeof routeMap[key] === 'string') {\n        normalizeRouteMap[key] = { handler: () => handleStrResult(routeMap[key]) }\n      } else if (typeof routeMap[key] === 'function') {\n        normalizeRouteMap[key] = { handler: createHandler(routeMap[key]) }\n      } else {\n        if ('handler' in routeMap[key]) {\n          normalizeRouteMap[key] = { handler: createHandler(routeMap[key].handler) }\n        } else {\n          normalizeRouteMap[key] = { handler: () => routeMap[key] }\n        }\n\n        if ('beforeEnter' in routeMap[key]) {\n          normalizeRouteMap[key]['beforeEnter'] = routeMap[key].beforeEnter\n        }\n      }\n\n      if ('beforeEnter' in normalizeRouteMap[key]) {\n        guard.routerGuardMap[key].beforeEnter(normalizeRouteMap[key].beforeEnter)\n      }\n    }\n\n    return normalizeRouteMap\n\n    function createHandler(fn) {\n      return ({ query }) => {\n        const result = fn({ query })\n\n        if (typeof result === 'string') {\n          return handleStrResult(result)\n        }\n\n        return result\n      }\n    }\n\n    function handleStrResult(str) {\n      if (str.indexOf('/') === -1) {\n        return { name: str }\n      }\n\n      return { path: str }\n    }\n  }\n}\n"
  },
  {
    "path": "packages/router/core/guard/createComponentGuard.js",
    "content": "\nimport { createGuardManager } from './guardManager'\n\nfunction createComponentGuard(name) {\n  const beforeRouteLeaveManager = createGuardManager()\n  const beforeRouteEnterManager = createGuardManager()\n  const beforeRouteUpdateManager = createGuardManager()\n\n  return {\n    get name() {\n      return name\n    },\n    get beforeRouteLeaveGuards() {\n      return beforeRouteLeaveManager.guards\n    },\n    get beforeRouteEnterGuards() {\n      return beforeRouteEnterManager.guards\n    },\n    get beforeRouteUpdateGuards() {\n      return beforeRouteUpdateManager.guards\n    },\n    beforeRouteLeave(cb) {\n      beforeRouteLeaveManager.register(cb)\n    },\n    beforeRouteEnter(cb) {\n      beforeRouteEnterManager.register(cb)\n    },\n    beforeRouteUpdate(cb) {\n      beforeRouteUpdateManager.register(cb)\n    }\n  }\n}\n\nexport default createComponentGuard\n"
  },
  {
    "path": "packages/router/core/guard/createRouterGuard.js",
    "content": "\nimport { createGuardManager } from './guardManager'\n\nfunction createRouterGuard(name) {\n  const beforeEnterManager = createGuardManager()\n\n  return {\n    get name() {\n      return name\n    },\n    get beforeEnterGuards() {\n      return beforeEnterManager.guards\n    },\n    beforeEnter(cb) {\n      beforeEnterManager.register(cb)\n    }\n  }\n}\n\nexport default createRouterGuard\n"
  },
  {
    "path": "packages/router/core/guard/globalGuard.js",
    "content": "\nimport { createGuardManager } from './guardManager'\n\nconst beforeEachManager = createGuardManager()\nconst beforeResolveManager = createGuardManager()\nconst afterEachManager = createGuardManager()\n\nexport default {\n  get beforeEachGuards() {\n    return beforeEachManager.guards\n  },\n  get beforeResolveGuards() {\n    return beforeResolveManager.guards\n  },\n  get afterEachGuards() {\n    return afterEachManager.guards\n  },\n  beforeEach(cb) {\n    beforeEachManager.register(cb)\n  },\n  beforeResolve(cb) {\n    beforeResolveManager.register(cb)\n  },\n  afterEach(cb) {\n    afterEachManager.register(cb)\n  }\n}\n"
  },
  {
    "path": "packages/router/core/guard/guardManager.js",
    "content": "\nfunction createGuardManager() {\n  const guards = []\n\n  return {\n    register(guard) {\n      guards.push(guard)\n\n      return () => {\n        this.unRegister(guard)\n      }\n    },\n\n    unRegister(guard) {\n      const index = guards.indexOf(guard)\n\n      if (index !== -1) {\n        guards.splice(index, 1)\n\n        return true\n      }\n\n      console.warn('此 guard 并未注册，因此无法注销 ')\n\n      return false\n    },\n    clear() {\n      guards.length = 0\n    },\n\n    get guards() {\n      return guards.slice()\n    }\n  }\n}\n\nexport { createGuardManager }\n"
  },
  {
    "path": "packages/router/core/guard/index.js",
    "content": "/**\n * @desc\n * @author wudi@supermonkey.com.cn\n * @createDate 2019/11/18\n */\nimport createComponentGuard from './createComponentGuard'\nimport createRouterGuard from './createRouterGuard'\nimport globalGuard from './globalGuard'\n\nconst routerGuardMap = {}\nconst componentGuardMap = {}\n\nexport {\n  createComponentGuard,\n  createRouterGuard\n}\n\nexport default {\n  get globalGuard() {\n    return globalGuard\n  },\n  get routerGuardMap() {\n    return routerGuardMap\n  },\n  get componentGuardMap() {\n    return componentGuardMap\n  },\n  updateRouterGuardMap(routerGuard) {\n    routerGuardMap[routerGuard.name] = routerGuard\n  },\n  updateComponentGuardMap(componentGuard) {\n    componentGuardMap[componentGuard.name] = componentGuard\n  },\n  hasInRouterGuardMap(name) {\n    return name in routerGuardMap\n  },\n  hasInComponentGuardMap(name) {\n    return name in componentGuardMap\n  }\n}\n"
  },
  {
    "path": "packages/router/core/index.js",
    "content": "/**\n * @desc\n * @author wudi@supermonkey.com.cn\n * @createDate 2020/3/5\n */\nimport { encodeParams, encodeUrl, decodeParams, decodePage, decodeUrl } from './utils/urlParse'\nimport createRouter from './createRouter'\nimport guard, { createComponentGuard } from './guard'\nimport routeManager from './routeManager'\nimport config from './config'\n\nexport {\n  encodeParams,\n  encodeUrl,\n  decodeParams,\n  decodePage,\n  decodeUrl,\n  createRouter,\n  guard,\n  createComponentGuard,\n  routeManager,\n  config\n}\n"
  },
  {
    "path": "packages/router/core/routeManager.js",
    "content": "\nconst _currentRoutes = []\nconst _showRoutes = []\nlet _next = null\nlet _currentVm = null\nlet _currentRoute = null\n\n// 页面参数缓存\nconst routeManager = {\n  get currentVm() {\n    return _currentVm\n  },\n  get next() {\n    return _next\n  },\n  get routes() {\n    return _currentRoutes\n  },\n  get route() {\n    return _currentRoute\n  },\n  get referrerRoute() {\n    if (_showRoutes.length <= 1) {\n      return null\n    }\n\n    return _showRoutes[0]\n  },\n\n  get lastRoute() {\n    return nthRoute(routeManager.routes, -2)\n  },\n\n  setCurrentVm(vm) {\n    _currentVm = vm\n  },\n  setNext(next) {\n    _next = next\n  },\n  clearNext() {\n    _next = null\n  },\n  createRoute(params) {\n    const {\n      id = null,\n      name,\n      query = {},\n      routes = null,\n      fullPath,\n      referrerRoute = null,\n      meta = null,\n      redirectedFrom = null\n    } = params\n\n    const path = fullPath.split('?')[0]\n\n    return {\n      id, name, query, routes, path, fullPath, referrerRoute, meta, redirectedFrom\n    }\n  },\n  setCurrentRoute(route) {\n    _currentRoute = route\n  },\n  updateCurrentRoute(params) {\n    Object.assign(_currentRoute, params)\n  },\n  pushRoute(route) {\n    _currentRoutes.push(route)\n\n    return route\n  },\n  popRoute() {\n    return _currentRoutes.pop()\n  },\n  clearRoutes() {\n    _currentRoutes.length = 0\n  },\n  pushShowRoute(route) {\n    if (last(_showRoutes) && route.id === last(_showRoutes).id) {\n      return route\n    }\n\n    _showRoutes.push(route)\n\n    if (_showRoutes.length > 2) {\n      _showRoutes.shift()\n    }\n\n    return route\n  },\n  clearShowRoutes() {\n    _showRoutes.length = 0\n  }\n}\n\nexport default routeManager\n\nfunction last(list, index = 1) {\n  return list[list.length - index] || null\n}\n\nfunction nthRoute(routes, index) {\n  return (index >= 0 ? routes[index] : last(routes, -index)) || null\n}\n"
  },
  {
    "path": "packages/router/core/routerApi.js",
    "content": "/**\n * @desc\n * @author wudi@supermonkey.com.cn\n * @createDate 2019/7/3\n */\nimport getRealPageInfo from './utils/getRealPageInfo'\nimport { encodeUrl } from './utils/urlParse'\nimport runQueue from './utils/queue'\nimport guard from './guard'\nimport routeManager from './routeManager'\nimport config from './config'\n\nconst errorHandlers = []\n\n/**\n * 将路由接口（'navigateBack', 'navigateTo', 'redirectTo', 'reLaunch', 'switchTab'）promise化\n * 修改传入参数。由 url 改为 name、query\n * name 为页面名称（String）、query 为页面参数的键值对（Object）\n */\nconst wxApiList = ['navigateBack', 'navigateTo', 'redirectTo', 'reLaunch', 'switchTab']\nconst promiseRouteApi = jumpMethodName => async (params = {}, encode = false) => {\n  const { success = () => {}, fail = () => {}, complete = () => {}, delta = 1, name, query = {}, ...otherParams } = params\n\n  if (jumpMethodName !== 'navigateBack' && name === undefined) {\n    throw new Error('页面跳转没有传入 name')\n  }\n\n  // 解析出真正要跳转的页面\n  const { pageMethod, pageDelta, realPage, pageData, pageMeta, pageEncode, pages } = await runGuard({\n    name, query, delta, jumpMethodName, encode\n  })\n\n  // 处理 beforeRouteUpdate\n  if (realPage === routeManager.route.name) {\n    routeManager.updateCurrentRoute({ query: pageData, meta: pageMeta })\n\n    return true\n  }\n\n  // hack 处理，因为 onHide 时拿到的 route 不对\n  routeManager['__tempRoute'] = getRoute({\n    pageMethod, pageDelta, realPage, pageData, pageMeta, pages\n  })\n\n  return handleNavigator(\n    getRealMethod({ pageMethod, realPage }),\n    getNavigatorParams({\n      pageMethod, pageDelta, realPage, pageData, pageEncode\n    }),\n    { success, fail, complete }\n  )\n\n  async function runGuard({ name, query = {}, delta, jumpMethodName = 'navigateTo', encode }) {\n    routeManager.clearNext()\n\n    const to = getTo({\n      name, query, delta, jumpMethodName, encode\n    })\n    try {\n      await runQueue(getGuardQueue(to.name, to.pages), guard => new Promise(async (resolve, reject) => {\n        const handleNext = createHandleNext()\n        try {\n          const res = await guard(\n            to,\n            routeManager.route,\n            handleNext.bind(null, resolve, reject)\n          )\n\n          res !== undefined && handleNext(resolve, reject, res)\n        } catch (e) {\n          handleNext(resolve, reject, e)\n        }\n\n        function createHandleNext() {\n          let isExecuted = false\n\n          return (resolve, reject, to) => {\n            if (isExecuted) {\n              return\n            }\n\n            isExecuted = true\n\n            if (to === false) {\n              reject(new Error('router to: false'))\n            } else if (type(to) === 'Error') {\n              reject(to)\n\n              errorHandlers.forEach(errorHandler => errorHandler(to))\n            } else if (type(to) === 'Object') {\n              reject(to)\n            } else if (type(to) === 'Function') {\n              resolve()\n\n              routeManager.setNext(to)\n            } else {\n              resolve()\n            }\n          }\n        }\n      }))\n    } catch (e) {\n      if (type(e) === 'Object') {\n        return runGuard(e)\n      }\n\n      throw e\n    }\n\n    return {\n      pageMethod: jumpMethodName,\n      pageDelta: delta,\n      realPage: to.name,\n      pageData: to.query,\n      pageMeta: to.meta,\n      pageEncode: encode,\n      pages: to.pages\n    }\n\n    function getTo({ name, query, delta, jumpMethodName, encode }) {\n      if (jumpMethodName === 'navigateBack') {\n        return {\n          ...routeManager.routes[routeManager.routes.length - 1 - delta],\n          jumpMethodName,\n          delta,\n          pages: [routeManager.routes[routeManager.routes.length - 1 - delta].name]\n        }\n      }\n\n      const { pageData = {}, pageMeta, pages } = getRealPageInfo({ name, query })\n\n      return {\n        name: pages[pages.length - 1], query: pageData, meta: pageMeta, jumpMethodName, encode, pages\n      }\n    }\n\n    function getGuardQueue(name, pages) {\n      if (name === routeManager.route.name) {\n        const beforeGuards = [...guard.componentGuardMap[name].beforeRouteUpdateGuards]\n\n        return [\n          ...beforeGuards.map(beforeGuard => beforeGuard.bind(routeManager.currentVm))\n        ]\n      }\n\n      const beforeGuards = [\n        ...guard.componentGuardMap[routeManager.route.name].beforeRouteLeaveGuards,\n        ...guard.globalGuard.beforeEachGuards,\n        ...getBeforeEnterGuards(pages)\n      ]\n\n      return [\n        ...beforeGuards.map(beforeGuard => beforeGuard.bind(routeManager.currentVm)),\n        ...getBeforeRouteEnterGuards(name),\n        ...guard.globalGuard.beforeResolveGuards\n      ]\n\n      function getBeforeRouteEnterGuards(name) {\n        if (name in guard.componentGuardMap) {\n          return guard.componentGuardMap[name].beforeRouteEnterGuards\n        }\n\n        return []\n      }\n\n      function getBeforeEnterGuards(pages) {\n        const result = []\n\n        pages.forEach(name => Array.prototype.push.apply(result, guard.routerGuardMap[name].beforeEnterGuards))\n\n        return result\n      }\n    }\n  }\n\n  function getRoute({ pageMethod, pageDelta, realPage, pageData, pageMeta, pages }) {\n    return pageMethod === 'navigateBack'\n      ? Object.assign({}, routeManager.routes[routeManager.routes.length - 1 - pageDelta])\n      : routeManager.createRoute({\n        name: realPage,\n        query: pageData,\n        meta: pageMeta,\n        fullPath: encodeUrl({ name: realPage, query: pageData }),\n        redirectedFrom: pages[pages.length - 2] || null\n      })\n  }\n\n  function handleNavigator(method, params, { success, fail, complete }) {\n    return new Promise(((resolve, reject) => {\n      setTimeout(() => wx[method]({\n        ...params,\n        ...otherParams,\n        success: (...res) => {\n          resolve(...res)\n          success(...res)\n        },\n        fail: (...res) => {\n          reject(...res)\n          fail(...res)\n        },\n        complete\n      }), 1)\n    }))\n  }\n\n  function getRealMethod({ pageMethod, realPage }) {\n    // 确定跳转页面的跳转方式\n    if ((config.tabPages.indexOf(realPage) !== -1) && (pageMethod === 'navigateTo' || pageMethod === 'redirectTo')) {\n      return 'switchTab'\n    }\n\n    return pageMethod\n  }\n\n  function getNavigatorParams({ pageMethod, pageDelta, realPage, pageData, pageEncode }) {\n    return pageMethod === 'navigateBack'\n      ? { delta: pageDelta }\n      : { url: encodeUrl({ name: realPage, query: pageData }, { encode: pageEncode, isAbsolutePath: true }) }\n  }\n}\n\nconst routerApi = {}\nwxApiList.forEach(key => (routerApi[key] = promiseRouteApi(key)))\n\nrouterApi['onError'] = handler => errorHandlers.push(handler)\nrouterApi['backHome'] = () => routerApi.switchTab({ name: config.homePage })\n\nexport default routerApi\n\nfunction type(val) {\n  const type = val === undefined ? 'Undefined' : Object.prototype.toString.call(val).slice(8, -1)\n\n  return val === null ? 'Null' : type\n}\n"
  },
  {
    "path": "packages/router/core/utils/getRealPageInfo.js",
    "content": "/**\n * @desc\n * @author wudi@supermonkey.com.cn\n * @createDate 2019/11/15\n */\nimport config from '../config'\n\nfunction getRealPageInfo({ name, query, meta }, pages = []) {\n  if (!(name in config.routeMap)) {\n    throw new Error(`routeMap 中未找到 ${name} 页面`)\n  }\n\n  pages.push(name)\n  const result = config.routeMap[name].handler({ query })\n\n  if ('path' in result) {\n    return {\n      pagePath: result.path,\n      pageData: mergeRight(result.query, query),\n      pageMeta: mergeRight(result.meta, meta),\n      pages\n    }\n  }\n\n  return getRealPageInfo(\n    { name: result.name, query: mergeRight(result.query, query), meta: mergeRight(result.meta, meta) },\n    pages\n  )\n}\n\nexport default getRealPageInfo\n\nfunction mergeRight(dataA, dataB) {\n  if (typeof dataA === 'undefined') {\n    return dataB\n  }\n\n  if (typeof dataB === 'undefined') {\n    return dataA\n  }\n\n  if (Object.prototype.toString.call(dataA) === '[object Object]'\n    && Object.prototype.toString.call(dataA) === '[object Object]') {\n    return Object.assign({}, dataA, dataB)\n  }\n\n  return dataB\n}\n"
  },
  {
    "path": "packages/router/core/utils/queue.js",
    "content": "/**\n * @desc\n * @author wudi@supermonkey.com.cn\n * @createDate 2019/11/14\n */\n\nexport default async function runQueue(queue, wrapperFn) {\n  for (const item of queue) {\n    item && await wrapperFn(item)\n  }\n}\n"
  },
  {
    "path": "packages/router/core/utils/urlParse.js",
    "content": "/**\n * @desc\n * @author wudi@supermonkey.com.cn\n * @createDate 2019/11/15\n */\nimport getRealPageInfo from './getRealPageInfo'\n\n/**\n * 编码url参数，如：{a: 123, b: 345} => a=123&b=456\n * @param obj\n * @param encode = false\n * return String\n */\nfunction encodeParams(obj, encode = false) {\n  const results = []\n\n  for (const key in obj) {\n    if (['string', 'number'].indexOf(typeof obj[key]) !== -1) {\n      results.push(`${key}=${encode ? encodeURIComponent(obj[key]) : obj[key]}`)\n    }\n  }\n\n  return results.join('&')\n}\n\n/**\n * 编码url参数，如：{ name: 'xxxxPage', query: {a: 123, b: 345} } => /pages/xxxxPage?a=123&b=456\n * @param obj\n * @param encode = false\n * @param isAbsolutePath = false 是否得到真实的页面（物理页面）\n * return String\n */\nfunction encodeUrl({ name, query = {} }, { encode = false, isAbsolutePath = true } = {}) {\n  const { pagePath, pageData } = isAbsolutePath ? getRealPageInfo({ name, query }) : { pagePath: name, pageData: query }\n  const paramsStr = encodeParams(pageData, encode)\n\n  return paramsStr ? `${pagePath}?${paramsStr}` : pagePath\n}\n\n/**\n * 解码 fullPath 或 params ，如：a=123&b=456 => { a: 123, b: 345 }\n * @param fullPath\n * @param decode = true\n * @returns {*}\n */\nfunction decodeParams(fullPath, decode = true) {\n  const splitArr = fullPath.split('?')\n  const result = {}\n\n  void (splitArr.length > 1 ? splitArr[1] : splitArr[0])\n    .split('&')\n    .map(str => str.split('='))\n    .forEach(([key, value]) => (result[key] = decode ? decodeURIComponent(value) : value))\n\n  return result\n}\n\n/**\n * 解析 /pages/xxxxPage?a=123&b=456 => xxxxPage\n * @param fullPath\n */\nfunction decodePage(fullPath) {\n  const result = fullPath.split('?')[0].split('/')\n\n  return result[result.length - 1]\n}\n\n/**\n * 解析 fullPath 页面和参数。如: /pages/xxxxPage?a=123&b=456 => { name: xxxxPage, query: { a: 123, b: 345 } }\n * @param fullPath\n * @param decode = true\n * @return {{ query: *, name }}\n */\nfunction decodeUrl(fullPath, decode = true) {\n  return {\n    name: decodePage(fullPath),\n    query: decodeParams(fullPath, decode)\n  }\n}\n\nexport {\n  encodeParams,\n  encodeUrl,\n  decodeParams,\n  decodePage,\n  decodeUrl\n}\n"
  },
  {
    "path": "packages/router/doc/config.md",
    "content": "## 路由配置\n\nrouteMap 是一个对象（key / value），所有页面的路由都在此配置。其中 key 为页面名（name），value 为路由配置信息（config），例如：\n\n> `页面名必须在页面里定义：wepy.page({ name: '页面名' })`\n\n```js\nhomePage = 'SplashScreen'\ntabPages = ['CourseList']\nrouteMap = {\n  SplashScreen: '/pages/SplashScreen',\n  CourseList: '/pages/tabBar/courseList/CourseList',\n  ClassList: { \n    name: 'CourseList', query: { courseType: 'class' } \n  },\n  BookList: { \n    path: '/pages/BookList', query: { info: { name: 'roma' } }, meta: 2\n  },\n  CityList: {\n    handler: ({ query }) => ({ path: '/pages/CityList', query }) \n  },\n  Courses: 'CourseList'\n}\n```\n\nconfig 支持三种数据类型来配置一个路由：Object、function、string\n\n### config（Object）\n\n两种结构：\n\n#### 第一种\n\n| 字段名      | 类型     | 必填 | 说明                                                         |\n| :---------- | -------- | ---- | ------------------------------------------------------------ |\n| path        | string   | 否   | 页面绝对路径 |\n| name        | string   | 否   | 页面名                                                       |\n| query        | Object   | 否   | 路由传参参数                                                 |\n| meta        | any      | 否   | 不属于 data 的额外信息                                       |\n| beforeEnter | function | 否   | 查看导航守卫章节                                             |\n\n> 注：`path、page 二选一，page 应该与页面文件名一致`\n\n#### 第二种\n\n| 字段名      | 类型     | 必填 | 说明                                                       |\n| :---------- | -------- | ---- | ---------------------------------------------------------- |\n| handler     | function | 是.  | ({ query }) => { path, name, query, meta }，具体含义参考上面 |\n| beforeEnter | function | 否   | 查看导航守卫章节                                           |\n\n### config（function）\n\n```\n({ query }) => ({ path | name, query(可选), meta(可选) } | string)\n```\n\n### config（string）\n\n```\npath 或者 name，有 / 的被认为是 path\n```\n"
  },
  {
    "path": "packages/router/doc/guard.md",
    "content": "## 导航守卫\n\n导航守卫参考 vue-router 的导航守卫，基本保持接口对齐。但有以下区别：\n\n- 支持 promise，可让函数返回一个 promise 代替 next。\n- to、from 的具体内容不同\n- 解析流程有部分区别\n\n### beforeRouteLeave\n\n- 组件守卫，离开页面时触发\n\n- **形式**：beforeRouteLeave(to, from, next)\n\n- **参数**：\n\n  - `{Object} to` 目标路由\n    - name 页面名\n    - query 跳转页面携带数据\n    - meta 携带额外信息\n    - jumpMethodName 跳转方式: 'navigateBack', 'navigateTo', 'redirectTo', 'reLaunch', 'switchTab'\n    - encode: 是否编码\n  - `{Object} from` 原路由\n    - name 页面名\n    - query 跳转页面携带数据\n    - meta 携带额外信息\n  - `{function} next`\n    - **`next()`**: 进入下一个守卫\n    - **`next(false)`**: 中断当前的导航\n    - **`next({ name, query, meta, jumpMethodName, encode })`**: 跳转到一个不同的页面。当前导航被中断\n    - **`next(error)`**: 如果传入 `next` 的参数是一个 `Error` 实例，则导航会被终止且该错误会被传递给 `router.onError()` 注册过的回调\n\n- **this**：指向离开页面的实例\n\n- **返回值**：promise，无论 rejected 还是 fulfilled ，其值的处理逻辑相同\n\n  - **`true`**: 进入下一个守卫\n  - **`false`**: 中断当前的导航\n  - **`{ name, query, meta, jumpMethodName, encode }`**: 跳转到一个不同的页面。当前导航被中断\n  - **`error`**: 返回一个 `Error` 实例，则导航会被终止且该错误会被传递给 `router.onError()` 注册过的回调\n\n  > `注意`：next 和 返回值 二选一，不然跳转会卡主\n\n- **用法**\n\n  在页面里定义\n\n- **示例**\n\n  ```js\n  <script>\n    wepy.page({\n      beforeRouteLeave(to, from, next) {\n        next()\n      }\n      // 或者\n      async beforeRouteLeave(to, from) {\n        return true\n      }\n    })\n  </script>\n  ```\n\n### beforeEach\n\n- 全局守卫，离开页面时触发\n\n- **形式**：beforeEach(to, from, next)\n\n- **参数**：\n\n  - `{Object} to` 目标路由\n    - name 页面名\n    - query 跳转页面携带数据\n    - meta 携带额外信息\n    - jumpMethodName 跳转方式: 'navigateBack', 'navigateTo', 'redirectTo', 'reLaunch', 'switchTab'\n    - encode: 是否编码\n  - `{Object} from` 原路由\n    - name 页面名\n    - query 跳转页面携带数据\n    - meta 携带额外信息\n  - `{function} next`\n    - **`next()`**: 进入下一个守卫\n    - **`next(false)`**: 中断当前的导航\n    - **`next({ name, query, meta, jumpMethodName, encode })`**: 跳转到一个不同的页面。当前导航被中断\n    - **`next(error)`**: 如果传入 `next` 的参数是一个 `Error` 实例，则导航会被终止且该错误会被传递给 `router.onError()` 注册过的回调\n\n- **this**：指向离开页面的实例\n\n- **返回值**：\n\n  - promise，无论 rejected 还是 fulfilled ，其值的处理逻辑相同\n\n    - **`true`**: 进入下一个守卫\n    - **`false`**: 中断当前的导航\n    - **`{ name, query, meta, jumpMethodName, encode }`**: 跳转到一个不同的页面。当前导航被中断\n    - **`error`**: 返回一个 `Error` 实例，则导航会被终止且该错误会被传递给 `router.onError()` 注册过的回调\n\n    > `注意`：next 和 返回值 二选一，不然跳转会卡主\n\n- **用法**\n\n  全局定义\n\n- **示例**\n\n  ```js\n  <script>\n  import router from 'router'\n  router.beforeEach(function beforeEach(to, from, next) {\n    next()\n  })\n  // 或者\n  router.beforeEach(function beforeEach(to, from) {\n    return true\n  })\n  </script>\n  ```\n\n### beforeEnter\n\n- 路由守卫\n\n- **形式**：beforeEnter(to, from, next)\n\n- **参数**：\n\n  - `{Object} to` 目标路由\n    - name 页面名\n    - query 跳转页面携带数据\n    - meta 携带额外信息\n    - jumpMethodName 跳转方式: 'navigateBack', 'navigateTo', 'redirectTo', 'reLaunch', 'switchTab'\n    - encode: 是否编码\n  - `{Object} from` 原路由\n    - name 页面名\n    - query 跳转页面携带数据\n    - meta 携带额外信息\n  - `{function} next`\n    - **`next()`**: 进入下一个守卫\n    - **`next(false)`**: 中断当前的导航\n    - **`next({ name, query, meta, jumpMethodName, encode })`**: 跳转到一个不同的页面。当前导航被中断\n    - **`next(error)`**: 如果传入 `next` 的参数是一个 `Error` 实例，则导航会被终止且该错误会被传递给 `router.onError()` 注册过的回调\n\n- **this**：指向离开页面的实例\n\n- **返回值**：\n\n  - promise，无论 rejected 还是 fulfilled ，其值的处理逻辑相同\n\n    - **`true`**: 进入下一个守卫\n    - **`false`**: 中断当前的导航\n    - **`{ name, query, meta, jumpMethodName, encode }`**: 跳转到一个不同的页面。当前导航被中断\n    - **`error`**: 返回一个 `Error` 实例，则导航会被终止且该错误会被传递给 `router.onError()` 注册过的回调\n\n    > `注意`：next 和 返回值 二选一，不然跳转会卡主\n\n- **用法**\n\n  routerConfig 里配置\n\n- **示例**\n\n  ```js\n  routerConfig = {\n    PersonalDetail: {\n      path: '/pagesSubPackage/personal/pages/PersonalDetail',\n      beforeEnter: (to, from, next) => next()\n    }\n  }\n  ```\n\n### beforeRouteEnter\n\n- 组件守卫，进入页面时触发\n\n- **形式**：beforeRouteEnter(to, from, next)\n\n- **参数**：\n\n  - `{Object} to` 目标路由\n    - name 页面名\n    - query 跳转页面携带数据\n    - meta 携带额外信息\n    - jumpMethodName 跳转方式: 'navigateBack', 'navigateTo', 'redirectTo', 'reLaunch', 'switchTab'\n    - encode: 是否编码\n  - `{Object} from` 原路由\n    - name 页面名\n    - query 跳转页面携带数据\n    - meta 携带额外信息\n  - `{function} next`\n    - **`next()`**: 进入下一个守卫\n    - **`next(false)`**: 中断当前的导航\n    - **`next({ name, query, meta, jumpMethodName, encode })`**: 跳转到一个不同的页面。当前导航被中断\n    - **`next(error)`**: 如果传入 `next` 的参数是一个 `Error` 实例，则导航会被终止且该错误会被传递给 `router.onError()` 注册过的回调\n    - **`next(vm => {})`**：vm 为进入页面的实例\n\n- **this**：由于进入页面还未实例化，因此不能使用，由 vm 代替\n\n- **返回值**：\n\n  - promise，无论 rejected 还是 fulfilled ，其值的处理逻辑相同\n\n    - **`true`**: 进入下一个守卫\n    - **`false`**: 中断当前的导航\n    - **`{ name, query, meta, jumpMethodName, encode }`**: 跳转到一个不同的页面。当前导航被中断\n    - **`error`**: 返回一个 `Error` 实例，则导航会被终止且该错误会被传递给 `router.onError()` 注册过的回调\n    - **`vm => {}`**： vm 为进入页面的实例\n\n    > `注意`：next 和 返回值 二选一，不然跳转会卡主\n\n- **用法**\n\n  页面里定义\n\n- **示例**\n\n  ```js\n  <script>\n    wepy.page({\n      beforeRouteEnter(to, from, next) {\n        next(false)\n      }\n      // 或者\n      async beforeRouteEnter(to, from) {\n        return vm => {}\n      }\n    })\n  </script>\n  ```\n\n### beforeResolve\n\n- 全局守卫，以上守卫执行后执行，但在页面跳转前\n\n- **形式**：beforeResolve(to, from, next)\n\n- **参数**：\n\n  - `{Object} to` 目标路由\n    - name 页面名\n    - query 跳转页面携带数据\n    - meta 携带额外信息\n    - jumpMethodName 跳转方式: 'navigateBack', 'navigateTo', 'redirectTo', 'reLaunch', 'switchTab'\n    - encode: 是否编码\n  - `{Object} from` 原路由\n    - name 页面名\n    - query 跳转页面携带数据\n    - meta 携带额外信息\n  - `{function} next`\n    - **`next()`**: 进入下一个守卫\n    - **`next(false)`**: 中断当前的导航\n    - **`next({ name, query, meta, jumpMethodName, encode })`**: 跳转到一个不同的页面。当前导航被中断\n    - **`next(error)`**: 如果传入 `next` 的参数是一个 `Error` 实例，则导航会被终止且该错误会被传递给 `router.onError()` 注册过的回调\n\n- **this**：无 this\n\n- **返回值**：\n\n  - promise，无论 rejected 还是 fulfilled ，其值的处理逻辑相同\n\n    - **`true`**: 进入下一个守卫\n    - **`false`**: 中断当前的导航\n    - **`{ name, query, meta, jumpMethodName, encode }`**: 跳转到一个不同的页面。当前导航被中断\n    - **`error`**: 返回一个 `Error` 实例，则导航会被终止且该错误会被传递给 `router.onError()` 注册过的回调\n\n    > `注意`：next 和 返回值 二选一，不然跳转会卡主\n\n- **用法**\n\n  全局定义\n\n- **示例**\n\n  ```js\n  <script>\n  import router from 'router'\n  router.beforeResolve((to, from, next) => next())\n  // 或者\n  router.beforeResolve((to, from) => true)\n  </script>\n  ```\n\n### afterEach\n\n- 全局守卫，进入页面后触发\n\n- **形式**：afterEach(to, from)\n\n- **参数**：\n\n  - `{Object} to` 目标路由\n    - name 页面名\n    - query 跳转页面携带数据\n    - meta 携带额外信息\n  - `{Object} from` 原路由\n    - name 页面名\n    - query 跳转页面携带数据\n    - meta 携带额外信息\n\n- **this**：指向进入页面的实例\n\n- **返回值**：\n\n  - 无\n\n- **用法**\n\n  全局定义\n\n- **示例**\n\n  ```js\n  <script>\n  import router from 'router'\n  router.afterEach((to, from) => {})\n  </script>\n  ```\n\n### beforeRouteUpdate\n\n- 组件守卫，页面内跳转\n\n- **形式**：beforeRouteUpdate(to, from, next)\n\n- **参数**：\n\n  - `{Object} to` 目标路由\n    - query 跳转页面携带数据\n    - meta 携带额外信息\n  - `{Object} from` 原路由\n    - query 跳转页面携带数据\n    - meta 携带额外信息\n  - `{function} next`\n    - **`next()`**: 进入下一个守卫\n    - **`next(false)`**: 中断当前的导航\n    - **`next({ name, query, meta, jumpMethodName, encode })`**: 跳转到一个不同的页面。当前导航被中断\n    - **`next(error)`**: 如果传入 `next` 的参数是一个 `Error` 实例，则导航会被终止且该错误会被传递给 `router.onError()` 注册过的回调\n\n- **this**：当前页面的实例\n\n- **返回值**：promise，无论 rejected 还是 fulfilled ，其值的处理逻辑相同\n\n  - **`true`**: 进入下一个守卫\n  - **`false`**: 中断当前的导航\n  - **`{ name, query, meta, jumpMethodName, encode }`**: 跳转到一个不同的页面。当前导航被中断\n  - **`error`**: 返回一个 `Error` 实例，则导航会被终止且该错误会被传递给 `router.onError()` 注册过的回调\n\n  > `注意`：next 和 返回值 二选一，不然跳转会卡主\n  >\n  > **跳转成功以后，route 对象会更新**\n\n- **用法**\n\n  在页面里定义（当跳转页面为当前页面时，触发此导航）\n\n- **示例**\n\n  ```js\n  <script>\n    wepy.page({\n      beforeRouteUpdate(to, from, next) {\n        next()\n      }\n      // 或者\n      async beforeRouteLeave(to, from) {\n        return true\n      }\n    })\n  </script>\n  ```\n\n### 完整页面导航解析流程\n\n#### 不同页面\n\n1. 从一个页面跳转到另一页面\n2. 在离开页面里调用 `beforeRouteLeave`\n3. 调用全局的 `beforeEach` \n4. 调用路由配置里的 `beforeEnter`\n5. 调用即将进入页面的 `beforeRouteEnter`\n6. 调用全局的 `beforeResolve` \n7. 页面进入后\n8. 调用全局的 `afterEach` \n9. 调用 `beforeRouteEnter` 中传给 `next` 的回调函数（如果定义了）\n10. 如果某个守卫改变了页面跳转，则中断以上流程并且重新开始导航解析\n\n#### 同一个页面\n\n1. 从一个页面跳转到另一页面\n2. 离开页和进入页为同一个页面\n3. 调用当前页的`beforeRouteUpdate`\n"
  },
  {
    "path": "packages/router/doc/instance.md",
    "content": "## 实例属性\n\n### this.$router\n\n- **类型**：Object\n\n  router 对象实例\n\n- **参考**：跟全局 router 对象一致，[参考](router.md)\n\n### this.$route\n\n- **类型**：Object\n\n  route 对象实例\n\n- **参考**：跟全局 router.route 对象一致，[参考](router.md#route)\n"
  },
  {
    "path": "packages/router/doc/router.md",
    "content": "# router\n\n## 导入方式\n\n`import router from 'router'`\n\n## 属性\n\n### route\n\n- 类型: Route\n\n  当前页面对应的路由对象\n\n- route.id\n\n  - 类型: string\n\n    当前页面的 id（唯一）\n\n- route.fullPath\n\n  - 类型: string\n\n    当前页面 url，带查询参数（只带数字类型和字符串类型的参数数据）\n\n- route.path\n\n  - 类型: string\n\n    当前页面 url，不带查询参数\n\n- route.name\n\n  - 类型: string\n\n    当前页面名\n\n- route.query\n\n  - 类型: Object\n\n    当前页面的完整查询参数数据\n\n- route.meta\n\n  - 类型: string\n\n    当前页面的非查询参数的其它数据\n\n- route.routes\n\n  - 类型: [Route, Route, ..., Route(当前路由)]\n\n    当前页面的路由栈\n\n- route.referrerRoute\n\n  - 类型: Route\n\n    前向路由，访问轨迹的当前页面的上一个页面的路由，没有则为 null\n\n    例如：A -> B -> C，再返回到 B，当前路由为 B，lastRoute 为 A，而 referrerRoute 为 C\n\n- redirectedFrom\n\n  - 类型: String\n\n    重定向页面名\n\n### homePage\n\n- **类型**: string\n\n  首页的页面名\n\n### tabPages\n\n- **类型**: List<String>\n\n  tab 页配置表，因为 tab 页跳转的 api 不一样\n\n  ```js\n  const tabPages = [\n    'BoxList',\n    'CourseList',\n    'MyBooking',\n    'My'\n  ]\n  \n  ```\n\n### routeMap\n\n- **类型**: Object\n\n  [页面路由配置表](config.md)\n\n## 方法/导航\n\n页面导航在 wx api 的基础上封装\n\n### navigateTo\n\n保留当前页面，跳转到应用内的某个页面\n\n- **形式**：navigateTo(object, encode)\n\n- **参数**：\n\n  - `{Object} object`\n    - `{string} name`页面名\n    - `{Object} query`页面参数\n    - `{function} success`接口调用成功的回调函数\n    - `{function} fail`接口调用失败的回调函数\n    - `{function} complete`接口调用结束的回调函数（调用成功、失败都会执行）\n  - `{bool} encode`是否对参数进行编码\n\n- **返回值** promise，根据调用成功/失败设置状态\n\n- **示例**\n\n  ```js\n  import router from 'router'\n  router.navigateTo({ name: 'BadgeDetail', query: { badgeId, sk } })\n  ```\n\n### redirectTo\n\n关闭当前页面，跳转到应用内的某个页面\n\n- **形式**：redirectTo(object, encode)\n\n- **参数**：\n\n  - `{Object} object`\n    - `{string} name`页面名\n    - `{Object} query`页面参数\n    - `{function} success`接口调用成功的回调函数\n    - `{function} fail`接口调用失败的回调函数\n    - `{function} complete`接口调用结束的回调函数（调用成功、失败都会执行）\n  - `{bool} encode`是否对参数进行编码\n\n- **返回值** promise，根据调用成功/失败设置状态\n\n- **示例**\n\n  ```js\n  import router from 'router'\n  router.redirectTo({ name: 'BadgeDetail', query: { badgeId, sk } })\n  ```\n\n### switchTab\n\n跳转到 tabBar 页面\n\n- **形式**：switchTab(object, encode)\n\n- **参数**：\n\n  - `{Object} object`\n    - `{string} name`页面名\n    - `{Object} query`页面参数\n    - `{function} success`接口调用成功的回调函数\n    - `{function} fail`接口调用失败的回调函数\n    - `{function} complete`接口调用结束的回调函数（调用成功、失败都会执行）\n  - `{bool} encode`是否对参数进行编码\n\n- **返回值** promise，根据调用成功/失败设置状态\n\n- **示例**\n\n  ```js\n  import router from 'router'\n  router.switchTab({ name: 'ClassList', query: { scheduleId, sk } })\n  ```\n\n### navigateBack\n\n关闭当前页面，返回上一页面或多级页面\n\n- **形式**：navigateBack(object, encode)\n\n- **参数**：\n\n  - `{Object} object`\n    - `{number} delta`返回的页面数，如果 delta 大于现有页面数，则返回到首页。默认：1\n    - `{function} success`接口调用成功的回调函数\n    - `{function} fail`接口调用失败的回调函数\n    - `{function} complete`接口调用结束的回调函数（调用成功、失败都会执行）\n\n- **返回值** promise，根据调用成功/失败设置状态\n\n- **示例**\n\n  ```js\n  import router from 'router'\n  router.navigateBack({ delta: 1 })\n  ```\n\n### reLaunch\n\n关闭所有页面，打开到应用内的某个页面\n\n- **形式**：reLaunch(object, encode)\n\n- **参数**：\n\n  - `{Object} object`\n    - `{string} name`页面名\n    - `{Object} query`页面参数\n    - `{function} success`接口调用成功的回调函数\n    - `{function} fail`接口调用失败的回调函数\n    - `{function} complete`接口调用结束的回调函数（调用成功、失败都会执行）\n  - `{bool} encode`是否对参数进行编码\n\n- **返回值** promise，根据调用成功/失败设置状态\n\n- **示例**\n\n  ```js\n  import router from 'router'\n  router.reLaunch({ name: 'ClassList', query: { scheduleId, sk } })\n  ```\n\n>  page 会根据 routeMap 找到真实页面路径（path）\n>\n> data 会转换成查询参数（'key=value&key2=value2'），如果 encode 为 true，则会使用 encodeURIComponent 进行编码，由于转换后是字符串，因此 query 里如果有非 string 和 number 将会被过滤掉，可以从 route.query 里拿到完整的 query\n\n## 方法/全局守卫\n\n### beforeEach\n\n[参考](guard.md#beforeEach)\n\n### beforeResolve\n\n[参考](guard.md#beforeResolve)\n\n### afterEach\n\n[参考](guard.md#afterEach)\n"
  },
  {
    "path": "packages/router/doc/usage.md",
    "content": "## Features\n\n对微信路由进行了封装和扩展（设计思路主要参考 vue router）\n\n- 结构化路由配置\n- api 支持 promise\n- 任意类型的路由传参\n- 导航守卫\n\n## Usage\n\n### 创建一个路由管理器\n\n```js\nconst homePage = 'SplashScreen'\nconst tabPages = ['CourseList']\nconst routeMap = {\n  SplashScreen: '/pages/SplashScreen',\n  CourseList: '/pages/tabBar/courseList/CourseList',\n  CourseDetail: '/pages/CourseDetail','\n  CourseOnlineDetail: {\n    name: 'CourseDetail', \n    query: { courseType: 'online' }\n  },\n}\nconst config = { homePage, tabPages, routeMap }\n\nconst router = createSmRouter(config)\nwepy.use(routerPlugin, router);\n\nexport { router }\n```\n\n### 使用场景\n\n具体使用场景可以根据业务自行处理，下面给出几个典型场景供开发者参考\n\n#### 页面跳转\n\n```js\n// 其它页\nconst course = { id: '123', text: '课程' };\nrouter.navigateTo({ name: 'CourseDetail', query: { course } })\n\n\n// CourseDetail 页\nwepy.page({\n  name: 'CourseDetail',\n  onLoad() {\n    // params = { course: { id: '123', text: '课程' } }\n    const params = this.$route.query;\n  }\n})\n```\n\n#### 别名跳转\n\n```js\n// 其它页\nconst course = { id: '233', text: '线上课程' };\nrouter.navigateTo({ name: 'CourseOnlineDetail', query: { course } })\n\n// CourseDetail 页\nwepy.page({\n  name: 'CourseDetail',\n  onLoad() {\n    // params = { course: { id: '233', text: '线上课程' }, courseType: 'online' }\n    const params = this.$route.query;\n  }\n})\n```\n\n#### 预加载数据\n\n- 提升页面加载速度，减少用户等待时间，这时可以使用守卫 `beforeRouteEnter`处理\n\n  ```js\n  <script>\n    wepy.page({\n      name: 'xxx',\n      _pData: null,\n      beforeRouteEnter(to, from, next) {\n        const pData = api.getXXX()\n        next(vm => {\n          vm.$options._pData = pData\n        })\n      },\n      onLoad() {\n        this._fetchData()\n      },\n      methods: { \n        async _fetchData() {\n          try {\n            if (this.$options._pData) {\n              this._renderingData = await this.$options._pData\n            } else {\n              this._renderingData = await api.getXXX()\n            }\n          } catch(e) {\n            // 错误处理\n          } finally {\n            this.$options._pData = null\n          }\n        }\n       }\n    })\n  </script>\n  ```\n\n#### 复杂情况下的页面数据交互\n\n- 将获取数据抽象成一个服务\n\n  ```js\n  // 代金券选择组件\n  wepy.component({\n    /** 页面/组件名 */\n    name: 'BookingConfirmRowSelectTicket',\n    methods: {\n      async goSelectTicket() {\n        this.ticketId = await this._getTicketId() || ''\n      },\n  \n      _getTicketId() {\n        return new Promise((resolve, reject) => {\n          this.$router.navigateTo({\n            name: 'UseTicket',\n            query: {\n              ...params,\n              resolve,\n              reject\n            }\n          })\n        })\n      }\n    },\n  })\n  \n  // 选择代金券页面\n  wepy.page({\n    /** 页面/组件名 */\n    name: 'UseTicket',\n    methods: {\n      onSelectTicket({ ticketId }) {\n        this.ticketId = ticketId\n        this.$router.navigateBack({ delta: 1 })\n      }\n    },\n    onUnload() {\n      this.$route.query.resolve(this.ticketId)\n    }\n  })\n  ```\n\n#### 非正常流程页面跳转\n\n- 要求符合条件 A 的用户无论点击哪个按钮都要跳到某个指定页面，这时可以使用守卫 `beforeRouteLeave`处理\n\n  ```js\n  <script>\n    wepy.page({\n      name: 'xxx',\n      beforeRouteLeave(to, from, next) {\n        // 如果不加 to.name !== 'xxxPage'，会进入死循环\n      \tif (this.condition && to.name !== 'xxxPage') {\n      \t  next({ name: 'xxxPage', jumpMethodName: 'navigateTo' })\n      \t} else {\n      \t  next()\n      \t}\n      }\n    })\n  </script>\n  ```\n\n#### 限制进入某个页面\n\n- 进入某个页面需要符合某个条件，这时可以使用守卫 `beforeEnter`处理\n\n  ```js\n  routerConfig = {\n    xxxPage: {\n      path: '/xxxPath',\n      beforeEnter: (to, from, next) => {\n        if (condition) {\n          next()\n        } else {\n          this.$showToast('需要 xxx 条件方可进入哦')\n          next(false)\n        }\n      }\n    }\n  }\n  ```\n\n#### 页面内不同标签页之间跳转\n\n- 某个页面由不同业务组成，分成不同标签页，在定义路由时可根据标签页定义不同的逻辑页面（映射到同一个物理页面），页面内跳转时，可以使用`beforeRouteUpdate`守卫处理。（可以参考启动页、课表页）\n\n  ```js\n  routeMap = {\n    xxxPage: '/xxxPath',\n    APage: { name: 'xxxPage', query: { type: 'A' } },\n    BPage: { name: 'xxxPage', query: { type: 'B' } }\n  }\n  \n  <script>\n    wepy.page({\n      name: 'xxxPage',\n      data: {\n        type: 'A'\n      },\n      beforeRouteUpdate(to, from, next) {\n        if (to.query.type === 'B') {\n          // 处理 B 业务\n        }\n  \n        next()\n      }\n    })\n  </script>\n  ```\n\n## 注意事项\n\n- 路由管理器基于微信提供的 api，但如果用户某个路由跳转行为不是基于 api，那么守卫将无法处理，开发时需要注意。例如：手势滑动返回 或者 点击 tab 或者从外部跳转进入小程序\n- 对于首次分包加载， `beforeRouteEnter`守卫无法终止路由跳转，因为导航守卫是在运行时处理的，首次分包加载前无跳转页面代码，因此拿不到此守卫\n\n## 文档\n\n* [配置](config.md)\n* [导航守卫](guard.md)\n* API\n    * [router](router.md)\n    * [实例](instance.md)\n"
  },
  {
    "path": "packages/router/index.js",
    "content": "import routerPlugin from './install'\nimport { encodeParams, encodeUrl, decodeParams, decodePage, decodeUrl, createRouter } from '../router/core'\n\nexport {\n  encodeParams,\n  encodeUrl,\n  decodeParams,\n  decodePage,\n  decodeUrl,\n  createRouter,\n  routerPlugin\n}\n"
  },
  {
    "path": "packages/router/install.js",
    "content": "import {\n  encodeParams,\n  encodeUrl,\n  decodeParams,\n  decodePage,\n  decodeUrl,\n  guard,\n  createComponentGuard,\n  routeManager,\n  config\n} from './core'\n\nlet _isExternalJump = false\nlet _isCallAppShow = false\nlet _externalQuery = {}\n\nexport default {\n  install(wepy, router) {\n    wepy.config.optionMergeStrategies['__routerHandler'] = (_, option) => {\n      const { name, beforeRouteLeave, beforeRouteEnter, beforeRouteUpdate } = option\n\n      if (!(name in config.routeMap)) {\n        return\n      }\n\n      if (!guard.hasInComponentGuardMap(name)) {\n        guard.updateComponentGuardMap(createComponentGuard(name))\n      }\n\n      if (beforeRouteLeave) {\n        guard.componentGuardMap[name].beforeRouteLeave(beforeRouteLeave)\n      }\n\n      if (beforeRouteEnter) {\n        guard.componentGuardMap[name].beforeRouteEnter(beforeRouteEnter)\n        handleBeforeRouteLeave(name, beforeRouteEnter)\n      }\n\n      if (beforeRouteUpdate) {\n        guard.componentGuardMap[name].beforeRouteUpdate(beforeRouteUpdate)\n      }\n\n      async function handleBeforeRouteLeave(name, beforeRouteLeave) {\n        if (routeManager.__tempRoute && name === routeManager.__tempRoute.name) {\n          try {\n            const res = await beforeRouteLeave(routeManager.__tempRoute, routeManager.route, res => {\n              if (typeof res === 'function') {\n                routeManager.setNext(res)\n              }\n            })\n\n            if (typeof res === 'function') {\n              routeManager.setNext(res)\n            }\n          } catch (e) {\n            console.error('handleBeforeRouteLeave', e)\n          }\n        }\n      }\n    }\n\n    wepy.mixin({\n      __routerHandler: '',\n\n      beforeCreate() {\n        this['$name'] = this.$options.name\n        this['$encodeParams'] = encodeParams\n        this['$encodeUrl'] = encodeUrl\n        this['$decodeParams'] = decodeParams\n        this['$decodePage'] = decodePage\n        this['$decodeUrl'] = decodeUrl\n        this['$router'] = router\n\n        // 判断是否是组件 0 为页面，1 为组件\n        if (last(this.$id) === '1') {\n          Object.defineProperty(this, '$route', { get: () => this.$root.$route })\n        }\n      },\n\n      created() {\n        // 判断是否是组件 0 为页面，1 为组件\n        if (last(this.$id) === '1') {\n          return\n        }\n\n        resetPageRoute.call(this)\n\n        handleTmpRoute()\n\n        handleTapTab.call(this)\n\n        updateRouteManager.call(this)\n\n        setThisRoute.call(this)\n\n        handleGuards.call(this)\n\n        function resetPageRoute() {\n          // 保底处理，tab 页\n          if (config.tabPages.indexOf(this.$name) !== -1) {\n            routeManager.clearRoutes()\n          }\n\n          if (_isExternalJump) {\n            updateIsExternalJump(false)\n            updateIsCallAppShow(false)\n\n            routeManager.clearRoutes()\n            routeManager.clearShowRoutes()\n\n            setCurrentRoute(this.$name, _externalQuery)\n          }\n        }\n\n        function handleTapTab() {\n          // 点击 tab\n          if (routeManager.route.name !== this.$name) {\n            setCurrentRoute(this.$name, {})\n          }\n        }\n\n        function setCurrentRoute(name, query) {\n          const fullPath = encodeUrl({ name, query })\n          routeManager.setCurrentRoute(routeManager.createRoute({ name, query, fullPath }))\n        }\n\n        function updateRouteManager() {\n          routeManager.setCurrentVm(this)\n          routeManager.pushRoute(routeManager.route)\n          routeManager.pushShowRoute(routeManager.route)\n          routeManager.updateCurrentRoute({\n            id: this.$id,\n            routes: [...routeManager.routes],\n            referrerRoute: routeManager.referrerRoute\n          })\n        }\n\n        function setThisRoute() {\n          this['$_route'] = routeManager.route\n          Object.defineProperty(this, '$route', {\n            get: () => this.$_route\n          })\n        }\n      },\n\n      onLaunch(options) {\n        updateIsExternalJump(true)\n      },\n\n      onShow(options) {\n        // App onShow\n        if (!('$app' in this)) {\n          handleAppOnShow.call(this, options)\n          return\n        }\n\n        handleTmpRoute()\n\n        // 手势滑动返回 或者 点击 tab 或者 其它方式，进入已经存在的页面\n        if (routeManager.route !== this.$_route) {\n          // 其它方式跳转过来\n          if (routeManager.route.name === this.$name) {\n            this['$_route'] = routeManager.route\n          }\n\n          // tab 页\n          if (config.tabPages.indexOf(this.$name) !== -1) {\n            routeManager.clearRoutes()\n            routeManager.pushRoute(this.$_route)\n          }\n\n          updateRouteManager.call(this)\n          handleGuards.call(this)\n        }\n\n        function handleAppOnShow(options) {\n          updateIsCallAppShow(true)\n          updateExternalQuery(options.query)\n        }\n\n        function updateRouteManager() {\n          routeManager.setCurrentVm(this)\n          routeManager.setCurrentRoute(this.$_route)\n          routeManager.pushShowRoute(routeManager.route)\n          routeManager.updateCurrentRoute({ referrerRoute: routeManager.referrerRoute })\n        }\n      },\n\n      onUnload() {\n        if (_isCallAppShow) {\n          updateIsCallAppShow(false)\n          updateIsExternalJump(true)\n        }\n\n        routeManager.popRoute()\n      }\n    })\n  }\n}\n\nfunction handleGuards() {\n  try {\n    guard.globalGuard.afterEachGuards.forEach(guard => guard(routeManager.route, routeManager.lastRoute))\n  } catch (e) {\n    console.error('handleGuards afterEach', e)\n  }\n\n  if (routeManager.next) {\n    try {\n      routeManager.next(this)\n    } catch (e) {\n      console.error('routeManager.next', e)\n    }\n    routeManager.clearNext()\n  }\n}\n\nfunction last(list, index = 1) {\n  return list[list.length - index] || null\n}\n\n// hack 处理，因为 onHide 时拿到的 route 不对\nfunction handleTmpRoute() {\n  if (routeManager.__tempRoute) {\n    routeManager.setCurrentRoute(routeManager.__tempRoute)\n    delete routeManager.__tempRoute\n  }\n}\n\nfunction updateIsExternalJump(val) {\n  _isExternalJump = val\n}\n\nfunction updateIsCallAppShow(val) {\n  _isCallAppShow = val\n}\n\nfunction updateExternalQuery(query) {\n  _externalQuery = query\n}\n"
  },
  {
    "path": "packages/router/package.json",
    "content": "{\n  \"name\": \"@wepy/router\",\n  \"version\": \"0.0.1\",\n  \"description\": \"router in WePY\",\n  \"main\": \"dist/index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/Tencent/wepy.git\"\n  },\n  \"keywords\": [\n    \"router\",\n    \"WePY\"\n  ],\n  \"author\": {\n    \"name\": \"nishino\",\n    \"email\": \"nishinotsukasavirgo@gmail.com\"\n  },\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/Tencent/wepy/issues\"\n  },\n  \"homepage\": \"https://github.com/Tencent/wepy#readme\",\n  \"readme\": \"README.md\",\n  \"_id\": \"@wepy/router@0.0.1\",\n  \"_commitid\": \"a423f8d\",\n  \"gitHead\": \"5a25776457360bbbbc54a4d059f6bc7c032d5df3\"\n}\n"
  },
  {
    "path": "packages/use-intercept/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n# 2.1.0 (2020-07-04)\n\n**Note:** Version bump only for package @wepy/use-intercept\n\n\n\n\n\n# 2.1.0-alpha.10 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/use-intercept\n\n\n\n\n\n# 2.1.0-alpha.9 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/use-intercept\n\n\n\n\n\n# 2.1.0-alpha.8 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/use-intercept\n\n\n\n\n\n# 2.1.0-alpha.7 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/use-intercept\n\n\n\n\n\n# 2.1.0-alpha.6 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/use-intercept\n\n\n\n\n\n# 2.1.0-alpha.5 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/use-intercept\n\n\n\n\n\n# [2.1.0-alpha.4](https://github.com/Tencent/wepy/compare/v2.1.0-alpha.2...v2.1.0-alpha.4) (2020-06-20)\n\n**Note:** Version bump only for package @wepy/use-intercept\n"
  },
  {
    "path": "packages/use-intercept/README.md",
    "content": "[English](./README_EN.md) | 简体中文\n\n# @wepy/use-intercept\n\n weapp APIs intercept factory.\n\n## 安装 \n\n```\nnpm install @wepy/use-intercept --save\n```\n\n## 用法\n\n\n### 基本用法\n\n```\nimport wepy from '@wepy/core';\nimport useIntercept  from '@wepy/use-intercept';\n\nwepy.use(useIntercept);\n\nconst request = wepy.intercept(wepy.wx.request, {\n  config(params) {\n    console.log(params);\n    if (!params.data) {\n      params.data = {};\n    }\n    params.data.t = +new Date();\n    return params;\n    // return Promise.resolve(params); // support async config interceptor\n  },\n  success(res) {\n    console.log(res);\n    return res;\n  },\n  fail(e) {\n    console.log(e);\n    return e;\n  }\n})\n```\n\n"
  },
  {
    "path": "packages/use-intercept/README_EN.md",
    "content": "English | [简体中文](./README.md)\n\n# @wepy/use-intercept\n\n weapp APIs intercept factory.\n\n## Install \n\n```\nnpm install @wepy/use-intercept --save\n```\n\n## Usage\n\n\n### Basic Usage\n\n```\nimport wepy from '@wepy/core';\nimport useIntercept  from '@wepy/use-intercept';\n\nwepy.use(useIntercept);\n\nconst request = wepy.intercept(wepy.wx.request, {\n  config(params) {\n    console.log(params);\n    if (!params.data) {\n      params.data = {};\n    }\n    params.data.t = +new Date();\n    return params;\n    // return Promise.resolve(params); // support async config interceptor\n  },\n  success(res) {\n    console.log(res);\n    return res;\n  },\n  fail(e) {\n    console.log(e);\n    return e;\n  }\n})\n```\n\n"
  },
  {
    "path": "packages/use-intercept/dist/index.js",
    "content": "'use strict';\n\nvar install = require('./install');\n\nvar index = {\n  install: install,\n  version: \"2.0.3\"\n};\n\nmodule.exports = index;\n"
  },
  {
    "path": "packages/use-intercept/index.js",
    "content": "import install from './install';\n\nexport default {\n  install,\n  version: __VERSION__\n};\n"
  },
  {
    "path": "packages/use-intercept/install.js",
    "content": "/**\n * Intercept a function\n * @param  {Function} fn           the function need to intercept\n * @param  {Object}   interceptors interceptors configuration\n * @return {Function}              intercepted function\n */\nconst intercept = function(fn, interceptors) {\n  return function(...args) {\n    const self = this;\n    if (fn._promisify) {\n      const callit = function(args) {\n        let promise = fn.apply(this, args);\n        const successInterceptors = interceptors.success;\n        if (typeof successInterceptors === 'function') {\n          promise = promise.then(rst => {\n            return successInterceptors(rst);\n          });\n        }\n        const failInterceptors = interceptors.fail;\n        if (typeof failInterceptors === 'function') {\n          promise = promise.catch(e => {\n            throw failInterceptors(e);\n          });\n        }\n        return promise;\n      };\n\n      const configInterceptors = interceptors.config;\n      if (typeof configInterceptors === 'function') {\n        args = configInterceptors.apply(self, args);\n      }\n      if (isPromise(args)) {\n        return args.then(res => {\n          return callit(res);\n        });\n      } else {\n        return callit(args);\n      }\n    } else {\n      let originalOption = args[0];\n      let option = originalOption;\n      const callit = function(args) {\n        ['fail', 'success', 'complete'].forEach(item => {\n          const bak = args[item];\n          if (typeof bak === 'function') {\n            args[item] = res => {\n              if (typeof interceptors[item] === 'function') {\n                res = interceptors[item].call(self, res);\n              }\n              bak.call(self, res);\n            };\n          }\n        });\n        return fn.call(self, args);\n      };\n\n      const configInterceptors = interceptors.config;\n      if (typeof configInterceptors === 'function') {\n        option = configInterceptors.call(self, originalOption);\n      }\n      if (isPromise(option)) {\n        return option\n          .then(res => {\n            return callit(res);\n          })\n          .catch(e => {\n            const failInterceptors = interceptors.fail;\n            if (typeof failInterceptors === 'function') {\n              e = failInterceptors.call(self, e);\n            }\n            const failFunc = originalOption.fail;\n            if (typeof failFunc === 'function') {\n              failFunc.call(self, e);\n            }\n          });\n      } else {\n        return callit(option);\n      }\n    }\n  };\n};\n\nfunction isPromise(obj) {\n  return !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function';\n}\n/*\n * wx API intercept\n * useage:\n * wepy.use(useIntercept)\n * wepy.intercept(wepy.wx.request, {\n *   config(params) {\n *     params.t = +new Date();\n *     return params;\n *     // return Promise.resolve(params);\n *   },\n *   success(res) {\n *     return res;\n *   },\n *   fail(e) {\n *     return e;\n *   }\n * })\n */\n\nexport default function install(wepy) {\n  wepy.wx = wepy.wx || Object.assign({}, wx);\n  wepy.intercept = intercept;\n}\n\n"
  },
  {
    "path": "packages/use-intercept/package.json",
    "content": "{\n  \"name\": \"@wepy/use-intercept\",\n  \"version\": \"2.1.0\",\n  \"description\": \"wepy intercept\",\n  \"main\": \"/dist/index.js\",\n  \"scripts\": {\n    \"test\": \"mocha --require esm ./test/**/*\"\n  },\n  \"author\": {\n    \"name\": \"Gcaufy\",\n    \"email\": \"gcaufy@gmail.com\"\n  },\n  \"license\": \"MIT\",\n  \"readme\": \"ERROR: No README data found!\",\n  \"_id\": \"@wepy/use-intercept@2.0.4\",\n  \"_commitid\": \"2fd06e4\",\n  \"gitHead\": \"5a25776457360bbbbc54a4d059f6bc7c032d5df3\"\n}\n"
  },
  {
    "path": "packages/use-intercept/test/index.test.js",
    "content": "import useInterceptInstall from '../install';\nconst { expect } = require('chai');\n\nfunction ensureAllTaskDone(taskList, done) {\n  let tasks = {};\n  taskList.forEach(v => (tasks[v] = false));\n\n  let _interval = setInterval(function() {\n    let alldone = true;\n    for (let k in tasks) {\n      alldone = alldone && tasks[k];\n    }\n    if (alldone) {\n      clearInterval(_interval);\n      done();\n    }\n  });\n  return {\n    done: function(key) {\n      tasks[key] = true;\n    }\n  };\n}\n\ndescribe('@wepy/use-intercept', function() {\n  let __storage = {\n    mydata: { a: 1 }\n  };\n\n  let wx = {\n    request: function(option) {\n      setTimeout(() => {\n        option.fail && option.fail(new Error('wx.request error'));\n        option.complete && option.complete({ a: 1 });\n      }, 1000);\n    },\n    getStorage: function(option) {\n      setTimeout(() => {\n        let res = __storage[option.key];\n        option.success && option.success(res);\n        option.complete && option.complete(res);\n      });\n    },\n    setStorage: function(option) {\n      setTimeout(() => {\n        __storage[option.key] = option.data;\n      });\n    },\n    setStorageSync: function(option) {\n      __storage[option.key] = option.data;\n    },\n    getStorageSync: function(key) {\n      let res = __storage[key];\n      return res;\n    },\n    someNewAPI: function(option) {\n      setTimeout(() => {\n        option.success(option.num);\n      });\n    },\n    showActionSheet: function(option) {\n      setTimeout(() => {\n        option.success && option.success(option);\n      });\n    }\n  };\n\n  before(function() {\n    global.wx = wx;\n  });\n\n  it('test callback success', function(done) {\n    let task = ensureAllTaskDone(['test-getStorage-config', 'test-getStorage-success', 'test-request-complete'], done);\n\n    let wepy = {};\n    useInterceptInstall(wepy);\n\n    const timeNow = +new Date();\n    const getStorage = wepy.intercept(wepy.wx.getStorage, {\n      config(p) {\n        p.t = timeNow;\n        expect(p.key).to.equal('sid');\n        task.done('test-getStorage-config');\n        return p;\n      },\n      success(res) {\n        res += ' world';\n        return res;\n      },\n      complete(res) {\n        res += ' complete';\n        return res;\n      }\n    });\n\n    expect(getStorage).is.a('function');\n\n    wx.setStorageSync({\n      key: 'sid',\n      data: 'hello'\n    });\n    getStorage({\n      key: 'sid',\n      success(res) {\n        expect(res).to.equal('hello world');\n        task.done('test-getStorage-success');\n      },\n      fail() {\n        throw new Error('never go here');\n      },\n      complete(res) {\n        expect(res).to.equal('hello complete');\n        task.done('test-request-complete');\n      }\n    });\n  });\n\n  it('test callback config promise', function(done) {\n    let task = ensureAllTaskDone(['test-getStorage-config', 'test-getStorage-success', 'test-request-complete'], done);\n\n    let wepy = {};\n    useInterceptInstall(wepy);\n\n    const timeNow = +new Date();\n    const getStorage = wepy.intercept(wepy.wx.getStorage, {\n      config(p) {\n        p.t = timeNow;\n        expect(p.key).to.equal('sid');\n        return new Promise(resolve => {\n          setTimeout(() => {\n            task.done('test-getStorage-config');\n            resolve(p);\n          });\n        });\n      },\n      success(res) {\n        res += ' world';\n        return res;\n      },\n      complete(res) {\n        res += ' complete';\n        return res;\n      }\n    });\n\n    expect(getStorage).is.a('function');\n\n    wx.setStorageSync({\n      key: 'sid',\n      data: 'hello'\n    });\n    getStorage({\n      key: 'sid',\n      success(res) {\n        expect(res).to.equal('hello world');\n        task.done('test-getStorage-success');\n      },\n      fail() {\n        throw new Error('never go here');\n      },\n      complete(res) {\n        expect(res).to.equal('hello complete');\n        task.done('test-request-complete');\n      }\n    });\n  });\n\n  it('test callback config promise reject', function(done) {\n    let task = ensureAllTaskDone(['test-getStorage-config', 'test-getStorage-fail'], done);\n\n    let wepy = {};\n    useInterceptInstall(wepy);\n\n    const timeNow = +new Date();\n    const getStorage = wepy.intercept(wepy.wx.getStorage, {\n      config(p) {\n        p.t = timeNow;\n        expect(p.key).to.equal('sid');\n        return new Promise((_, reject) => {\n          setTimeout(() => {\n            task.done('test-getStorage-config');\n            reject(new Error('test'));\n          });\n        });\n      },\n      fail(e) {\n        return new Error(e.message + ' from interceptor');\n      },\n      success(res) {\n        res += ' world';\n        return res;\n      },\n      complete(res) {\n        res += ' complete';\n        return res;\n      }\n    });\n\n    expect(getStorage).is.a('function');\n\n    wx.setStorageSync({\n      key: 'sid',\n      data: 'hello'\n    });\n    getStorage({\n      key: 'sid',\n      success() {\n        throw new Error('never go here');\n      },\n      fail(e) {\n        expect(e.message).to.equal('test from interceptor');\n        task.done('test-getStorage-fail');\n      },\n      complete() {\n        throw new Error('never call complete when interceptor config reject');\n      }\n    });\n  });\n\n  it('test callback failed', function(done) {\n    let task = ensureAllTaskDone(['test-request-config', 'test-request-fail', 'test-request-complete'], done);\n\n    let wepy = {};\n    useInterceptInstall(wepy);\n\n    const timeNow = +new Date();\n    const request = wepy.intercept(wepy.wx.request, {\n      config(params) {\n        params.t = timeNow;\n        task.done('test-request-config');\n        expect(params.url).to.equal('www.baidu.com');\n        return params;\n      },\n      fail(e) {\n        e.intercept_fail = true;\n        return e;\n      },\n      complete(res) {\n        res.intercept_complete = true;\n        return res;\n      }\n    });\n\n    expect(request).is.a('function');\n    request({\n      url: 'www.baidu.com',\n      success() {\n        throw new Error('never go here');\n      },\n      fail(e) {\n        expect(e.intercept_fail).to.equal(true);\n        task.done('test-request-fail');\n      },\n      complete(res) {\n        expect(res.a).to.equal(1);\n        expect(res.intercept_complete).to.equal(true);\n        task.done('test-request-complete');\n      }\n    });\n  });\n\n  after(function() {\n    delete global.wx;\n  });\n});\n"
  },
  {
    "path": "packages/use-promisify/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n# 2.1.0 (2020-07-04)\n\n**Note:** Version bump only for package @wepy/use-promisify\n\n\n\n\n\n# 2.1.0-alpha.10 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/use-promisify\n\n\n\n\n\n# 2.1.0-alpha.9 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/use-promisify\n\n\n\n\n\n# 2.1.0-alpha.8 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/use-promisify\n\n\n\n\n\n# 2.1.0-alpha.7 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/use-promisify\n\n\n\n\n\n# 2.1.0-alpha.6 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/use-promisify\n\n\n\n\n\n# 2.1.0-alpha.5 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/use-promisify\n\n\n\n\n\n# [2.1.0-alpha.4](https://github.com/Tencent/wepy/compare/v2.1.0-alpha.2...v2.1.0-alpha.4) (2020-06-20)\n\n**Note:** Version bump only for package @wepy/use-promisify\n"
  },
  {
    "path": "packages/use-promisify/README.md",
    "content": "[English](./README_EN.md) | 简体中文\n\n# @wepy/use-promisify\n\nPromisfy all weapp APIs.\n\n## 安装\n\n```\nnpm install @wepy/use-promisify --save\n```\n\n## 用法\n\n\n### 基本用法\n\n```\nimport wepy from '@wepy/core';\nimport promisify  from '@wepy/use-promisify';\n\nwepy.use(promisify);\n\nwepy.wx.getStorage('mykey').then(res => console.log(res));\n```\n\n### 忽略 APIs\n\n```\nwepy.use(promisify, ['getStorage', 'getSystemInfo']);\n\n// passing object\n// wepy.use(promisify, { someNewAPI: false, getStorage: true });\nwepy.wx.getStorage({\n  key: 'mykey',\n  succuess (res) { console.log(res) }\n})\n```\n\n### 函数调用\n\nSupport to use `wepy.promisify` to promisify a callback function.\n\n```\n/**\n * Promisify a callback function\n * @param  {Function} fn     callback function\n * @param  {Object}   caller caller\n * @param  {String}   type   weapp-style|error-first, default to weapp-style\n * @return {Function}        promisified function\n */\nwepy.promisify(fn, caller, type);\n```\n\n#### weapp-style\n\n支持 weapp-style的所有功能:\n\n```\nfunc({\n  success () {},\n  fail () {}\n})\nwepy.promisify(func)({key: 'mykey'}).then(console.log).catch(console.error);\n```\n\n#### error-first\n\n支持所有 `error-first` 功能，例如:\n\n```\nfunc(arg1, args2, function (err, data) {});\n\nwepy.promisify(func, null, 'error-first')(arg1, arg2).then(console.log).catch(console.error);\n```\n\n\n### 简化参数\n\n`weapp-style` 函数始终需要一个Object参数，并且此插件将简化参数。例如：\n\n```\nwepy.use(promisify);\n\n// wepy.wx.getStorage({ key: 'mykey' });\nwepy.wx.getStorage('mykey');\n\n// wepy.wx.request({ url: myurl });\nwepy.wx.request(myurl);\n\n// wepy.wx.openLocation({ latitude: 0, longitude: 0 });\nwepy.wx.openLocation(0, 0);\n```\n\n在这里我们可以看到所有的简化列表 [Simplify List](https://github.com/Tencent/wepy/blob/2.0.x/packages/use-promisify/index.js#L86-L152) "
  },
  {
    "path": "packages/use-promisify/README_EN.md",
    "content": "English | [简体中文](./README.md)\n\n# @wepy/use-promisify\n\nPromisfy all weapp APIs.\n\n## Install \n\n```\nnpm install @wepy/use-promisify --save\n```\n\n## Usage\n\n\n### Basic Usage\n\n```\nimport wepy from '@wepy/core';\nimport promisify  from '@wepy/use-promisify';\n\nwepy.use(promisify);\n\nwepy.wx.getStorage('mykey').then(res => console.log(res));\n```\n\n### Ignore APIs\n\n```\nwepy.use(promisify, ['getStorage', 'getSystemInfo']);\n\n// passing object\n// wepy.use(promisify, { someNewAPI: false, getStorage: true });\nwepy.wx.getStorage({\n  key: 'mykey',\n  succuess (res) { console.log(res) }\n})\n```\n\n### Function call\n\nSupport to use `wepy.promisify` to promisify a callback function.\n\n```\n/**\n * Promisify a callback function\n * @param  {Function} fn     callback function\n * @param  {Object}   caller caller\n * @param  {String}   type   weapp-style|error-first, default to weapp-style\n * @return {Function}        promisified function\n */\nwepy.promisify(fn, caller, type);\n```\n\n#### weapp-style\n\nSupports all function which is weapp-style:\n\n```\nfunc({\n  success () {},\n  fail () {}\n})\nwepy.promisify(func)({key: 'mykey'}).then(console.log).catch(console.error);\n```\n\n#### error-first\n\nSupports all `error-first` functions, like:\n\n```\nfunc(arg1, args2, function (err, data) {});\n\nwepy.promisify(func, null, 'error-first')(arg1, arg2).then(console.log).catch(console.error);\n```\n\n\n### Simplify Parameters\n\n`weapp-style` function always need a Object params, and this plugin will simplify the parameters. e.g.\n\n```\nwepy.use(promisify);\n\n// wepy.wx.getStorage({ key: 'mykey' });\nwepy.wx.getStorage('mykey');\n\n// wepy.wx.request({ url: myurl });\nwepy.wx.request(myurl);\n\n// wepy.wx.openLocation({ latitude: 0, longitude: 0 });\nwepy.wx.openLocation(0, 0);\n```\n\nHere we can see all the [Simplify List](https://github.com/Tencent/wepy/blob/2.0.x/packages/use-promisify/index.js#L86-L152) \n"
  },
  {
    "path": "packages/use-promisify/dist/index.js",
    "content": "'use strict';\n\n/**\n * Promisify a callback function\n * @param  {Function} fn     callback function\n * @param  {Object}   caller caller\n * @param  {String}   type   weapp-style|error-first, default to weapp-style\n * @return {Function}        promisified function\n */\nvar promisify = function(fn, caller, type) {\n  if ( type === void 0 ) type = 'weapp-style';\n\n  return function() {\n    var args = [], len = arguments.length;\n    while ( len-- ) args[ len ] = arguments[ len ];\n\n    return new Promise(function (resolve, reject) {\n      switch (type) {\n        case 'weapp-style':\n          fn.call(caller, Object.assign({}, args[0],\n            {success: function success(res) {\n                resolve(res);\n              },\n              fail: function fail(err) {\n                reject(err);\n              }}));\n          break;\n        case 'weapp-fix':\n          args = !args.length ? [{}] : args;\n          fn.apply(caller, args.concat(resolve).concat(reject));\n          break;\n        case 'error-first':\n          fn.apply(caller, args.concat( [function (err, res) { return (err ? reject(err) : resolve(res)); }]));\n          break;\n      }\n    });\n  };\n};\n\n// The methods no need to promisify\nvar noPromiseMethods = [\n  // 媒体\n  'stopRecord',\n  'getRecorderManager',\n  'pauseVoice',\n  'stopVoice',\n  'pauseBackgroundAudio',\n  'stopBackgroundAudio',\n  'getBackgroundAudioManager',\n  'createAudioContext',\n  'createInnerAudioContext',\n  'createVideoContext',\n  'createCameraContext',\n\n  // 位置\n  'createMapContext',\n\n  // 设备\n  'canIUse',\n  'startAccelerometer',\n  'stopAccelerometer',\n  'startCompass',\n  'stopCompass',\n  'onBLECharacteristicValueChange',\n  'onBLEConnectionStateChange',\n\n  // 界面\n  'hideToast',\n  'hideLoading',\n  'showNavigationBarLoading',\n  'hideNavigationBarLoading',\n  'navigateBack',\n  'createAnimation',\n  'pageScrollTo',\n  'createSelectorQuery',\n  'createCanvasContext',\n  'createContext',\n  'drawCanvas',\n  'hideKeyboard',\n  'stopPullDownRefresh',\n\n  // 拓展接口\n  'arrayBufferToBase64',\n  'base64ToArrayBuffer'\n];\n\nvar simplifyArgs = {\n  // network\n  request: 'url',\n  downloadFile: 'url',\n  connectSocket: 'url',\n  sendSocketMessage: 'data',\n\n  // media\n  previewImage: 'urls',\n  getImageInfo: 'src',\n  saveImageToPhotosAlbum: 'filePath',\n  playVoice: 'filePath',\n  playBackgroundAudio: 'dataUrl',\n  seekBackgroundAudio: 'position',\n  saveVideoToPhotosAlbum: 'filePath',\n\n  // files\n  saveFile: 'tempFilePath',\n  getFileInfo: 'filePath',\n  getSavedFileInfo: 'filePath',\n  removeSavedFile: 'filePath',\n  openDocument: 'filePath',\n\n  // device\n  setStorage: 'key,data',\n  getStorage: 'key',\n  removeStorage: 'key',\n  openLocation: 'latitude,longitude',\n  makePhoneCall: 'phoneNumber',\n  setClipboardData: 'data',\n  getConnectedBluetoothDevices: 'services',\n  createBLEConnection: 'deviceId',\n  closeBLEConnection: 'deviceId',\n  getBLEDeviceServices: 'deviceId',\n  startBeaconDiscovery: 'uuids',\n  setScreenBrightness: 'value',\n  setKeepScreenOn: 'keepScreenOn',\n\n  // screen\n  showToast: 'title',\n  showLoading: 'title,mask',\n  showModal: 'title,content',\n  showActionSheet: 'itemList,itemColor',\n  setNavigationBarTitle: 'title',\n  setNavigationBarColor: 'frontColor,backgroundColor',\n\n  // tabBar\n  setTabBarBadge: 'index,text',\n  removeTabBarBadge: 'idnex',\n  showTabBarRedDot: 'index',\n  hideTabBarRedDot: 'index',\n  showTabBar: 'animation',\n  hideTabBar: 'animation',\n\n  // topBar\n  setTopBarText: 'text',\n\n  // navigator\n  navigateTo: 'url',\n  redirectTo: 'url',\n  navigateBack: 'delta',\n  reLaunch: 'url',\n\n  // pageScroll\n  pageScrollTo: 'scrollTop,duration'\n};\n\nvar makeObj = function (arr) {\n  var obj = {};\n  arr.forEach(function (v) { return (obj[v] = 1); });\n  return obj;\n};\n\n/*\n * wx basic api promisify\n * useage:\n * wepy.use(wepy-use-promisify)\n * wepy.use(wepy-use-promisify([nopromise1, nopromise2]));\n * wepy.use(wepy-use-promisify({nopromise1: true, promise: false}));\n * wepy.login().then().catch()\n */\nfunction install(wepy, removeFromPromisify) {\n  var _wx = (wepy.wx = wepy.wx || Object.assign({}, wx));\n\n  var noPromiseMap = {};\n  if (removeFromPromisify) {\n    if (Array.isArray(removeFromPromisify)) {\n      noPromiseMap = makeObj(noPromiseMethods.concat(removeFromPromisify));\n    } else {\n      noPromiseMap = Object.assign({}, makeObj(noPromiseMethods), removeFromPromisify);\n    }\n  }\n\n  Object.keys(_wx).forEach(function (key) {\n    if (!noPromiseMap[key] && key.substr(0, 2) !== 'on' && key.substr(-4) !== 'Sync') {\n      _wx[key] = promisify(\n        function() {\n          var args = [], len = arguments.length;\n          while ( len-- ) args[ len ] = arguments[ len ];\n\n          var fixArgs = args[0];\n          var failFn = args.pop();\n          var successFn = args.pop();\n          if (simplifyArgs[key] && Object.prototype.toString.call(fixArgs) !== '[object Object]') {\n            fixArgs = {};\n            var ps = simplifyArgs[key];\n            if (args.length) {\n              ps.split(',').forEach(function (p, i) {\n                if (i in args) {\n                  fixArgs[p] = args[i];\n                }\n              });\n            }\n          }\n          fixArgs.success = successFn;\n          fixArgs.fail = failFn;\n\n          return wx[key].call(wx, fixArgs);\n        },\n        _wx,\n        'weapp-fix'\n      );\n    }\n  });\n\n  wepy.promisify = promisify;\n}\n\nvar index = {\n  install: install,\n  version: \"2.0.6\"\n};\n\nmodule.exports = index;\n"
  },
  {
    "path": "packages/use-promisify/index.js",
    "content": "import install from './install';\n\nexport default {\n  install,\n  version: __VERSION__\n};\n"
  },
  {
    "path": "packages/use-promisify/install.js",
    "content": "/**\n * Promisify a callback function\n * @param  {Function} fn     callback function\n * @param  {Object}   caller caller\n * @param  {String}   type   weapp-style|error-first, default to weapp-style\n * @return {Function}        promisified function\n */\nconst promisify = function(fn, caller, type = 'weapp-style') {\n  return function(...args) {\n    return new Promise((resolve, reject) => {\n      switch (type) {\n        case 'weapp-style':\n          fn.call(caller, {\n            ...args[0],\n            ...{\n              success(res) {\n                resolve(res);\n              },\n              fail(err) {\n                reject(err);\n              }\n            }\n          });\n          break;\n        case 'weapp-fix':\n          args = !args.length ? [{}] : args;\n          fn.apply(caller, args.concat(resolve).concat(reject));\n          break;\n        case 'error-first':\n          fn.apply(caller, [...args, (err, res) => (err ? reject(err) : resolve(res))]);\n          break;\n      }\n    });\n  };\n};\n\n// The methods no need to promisify\nconst noPromiseMethods = [\n  // 媒体\n  'stopRecord',\n  'getRecorderManager',\n  'pauseVoice',\n  'stopVoice',\n  'pauseBackgroundAudio',\n  'stopBackgroundAudio',\n  'getBackgroundAudioManager',\n  'createAudioContext',\n  'createInnerAudioContext',\n  'createVideoContext',\n  'createCameraContext',\n\n  // 位置\n  'createMapContext',\n\n  // 设备\n  'canIUse',\n  'startAccelerometer',\n  'stopAccelerometer',\n  'startCompass',\n  'stopCompass',\n  'onBLECharacteristicValueChange',\n  'onBLEConnectionStateChange',\n\n  // 界面\n  'hideToast',\n  'hideLoading',\n  'showNavigationBarLoading',\n  'hideNavigationBarLoading',\n  'navigateBack',\n  'createAnimation',\n  'pageScrollTo',\n  'createSelectorQuery',\n  'createCanvasContext',\n  'createContext',\n  'drawCanvas',\n  'hideKeyboard',\n  'stopPullDownRefresh',\n\n  // 拓展接口\n  'arrayBufferToBase64',\n  'base64ToArrayBuffer'\n];\n\nconst simplifyArgs = {\n  // network\n  request: 'url',\n  downloadFile: 'url',\n  connectSocket: 'url',\n  sendSocketMessage: 'data',\n\n  // media\n  previewImage: 'urls',\n  getImageInfo: 'src',\n  saveImageToPhotosAlbum: 'filePath',\n  playVoice: 'filePath',\n  playBackgroundAudio: 'dataUrl',\n  seekBackgroundAudio: 'position',\n  saveVideoToPhotosAlbum: 'filePath',\n\n  // files\n  saveFile: 'tempFilePath',\n  getFileInfo: 'filePath',\n  getSavedFileInfo: 'filePath',\n  removeSavedFile: 'filePath',\n  openDocument: 'filePath',\n\n  // device\n  setStorage: 'key,data',\n  getStorage: 'key',\n  removeStorage: 'key',\n  openLocation: 'latitude,longitude',\n  makePhoneCall: 'phoneNumber',\n  setClipboardData: 'data',\n  getConnectedBluetoothDevices: 'services',\n  createBLEConnection: 'deviceId',\n  closeBLEConnection: 'deviceId',\n  getBLEDeviceServices: 'deviceId',\n  startBeaconDiscovery: 'uuids',\n  setScreenBrightness: 'value',\n  setKeepScreenOn: 'keepScreenOn',\n\n  // screen\n  showToast: 'title',\n  showLoading: 'title,mask',\n  showModal: 'title,content',\n  showActionSheet: 'itemList,itemColor',\n  setNavigationBarTitle: 'title',\n  setNavigationBarColor: 'frontColor,backgroundColor',\n\n  // tabBar\n  setTabBarBadge: 'index,text',\n  removeTabBarBadge: 'idnex',\n  showTabBarRedDot: 'index',\n  hideTabBarRedDot: 'index',\n  showTabBar: 'animation',\n  hideTabBar: 'animation',\n\n  // topBar\n  setTopBarText: 'text',\n\n  // navigator\n  navigateTo: 'url',\n  redirectTo: 'url',\n  navigateBack: 'delta',\n  reLaunch: 'url',\n\n  // pageScroll\n  pageScrollTo: 'scrollTop,duration'\n};\n\nconst makeObj = arr => {\n  let obj = {};\n  arr.forEach(v => (obj[v] = 1));\n  return obj;\n};\n\n/*\n * wx basic api promisify\n * useage:\n * wepy.use(wepy-use-promisify)\n * wepy.use(wepy-use-promisify([nopromise1, nopromise2]));\n * wepy.use(wepy-use-promisify({nopromise1: true, promise: false}));\n * wepy.login().then().catch()\n */\nexport default function install(wepy, removeFromPromisify) {\n  let _wx = (wepy.wx = wepy.wx || Object.assign({}, wx));\n\n  let noPromiseMap = {};\n  if (removeFromPromisify) {\n    if (Array.isArray(removeFromPromisify)) {\n      noPromiseMap = makeObj(noPromiseMethods.concat(removeFromPromisify));\n    } else {\n      noPromiseMap = Object.assign({}, makeObj(noPromiseMethods), removeFromPromisify);\n    }\n  }\n\n  Object.keys(_wx).forEach(key => {\n    if (!noPromiseMap[key] && key.substr(0, 2) !== 'on' && key.substr(-4) !== 'Sync') {\n      _wx[key] = promisify(\n        function(...args) {\n          let fixArgs = args[0];\n          let failFn = args.pop();\n          let successFn = args.pop();\n          if (simplifyArgs[key] && Object.prototype.toString.call(fixArgs) !== '[object Object]') {\n            fixArgs = {};\n            let ps = simplifyArgs[key];\n            if (args.length) {\n              ps.split(',').forEach((p, i) => {\n                if (i in args) {\n                  fixArgs[p] = args[i];\n                }\n              });\n            }\n          }\n          fixArgs.success = successFn;\n          fixArgs.fail = failFn;\n\n          return wx[key].call(wx, fixArgs);\n        },\n        _wx,\n        'weapp-fix'\n      );\n    }\n  });\n\n  wepy.promisify = promisify;\n}\n"
  },
  {
    "path": "packages/use-promisify/package.json",
    "content": "{\n  \"name\": \"@wepy/use-promisify\",\n  \"version\": \"2.1.0\",\n  \"description\": \"wepy promisify\",\n  \"main\": \"/dist/index.js\",\n  \"scripts\": {\n    \"test\": \"mocha --require esm ./test/**/*\"\n  },\n  \"author\": {\n    \"name\": \"Gcaufy\",\n    \"email\": \"gcaufy@gmail.com\"\n  },\n  \"license\": \"MIT\",\n  \"readme\": \"ERROR: No README data found!\",\n  \"_id\": \"@wepy/use-promisify@2.0.7\",\n  \"_commitid\": \"6d2153b\",\n  \"gitHead\": \"5a25776457360bbbbc54a4d059f6bc7c032d5df3\"\n}\n"
  },
  {
    "path": "packages/use-promisify/test/index.test.js",
    "content": "import usePromisifyInstall from '../install';\nconst expect = require('chai').expect;\n\nfunction ensureAllTaskDone(taskList, done) {\n  let tasks = {};\n  taskList.forEach(v => (tasks[v] = false));\n\n  let _interval = setInterval(function() {\n    let alldone = true;\n    for (let k in tasks) {\n      alldone = alldone && tasks[k];\n    }\n    if (alldone) {\n      clearInterval(_interval);\n      done();\n    }\n  });\n  return {\n    done: function(key) {\n      tasks[key] = true;\n    }\n  };\n}\n\ndescribe('wepy@use-promisify', function() {\n  let __storage = {\n    mydata: { a: 1 }\n  };\n\n  let wx = {\n    request: function(option) {\n      setTimeout(() => {\n        option.fail && option.fail(new Error('timeout'));\n        option.complete && option.complete({ a: 1 });\n      }, 1000);\n    },\n    getStorage: function(option) {\n      setTimeout(() => {\n        let res = __storage[option.key];\n        option.success && option.success(res);\n        option.complete && option.complete(res);\n      });\n    },\n    setStorage: function(option) {\n      setTimeout(() => {\n        __storage[option.key] = option.data;\n        option.success && option.success();\n        option.complete && option.complete();\n      });\n    },\n    getStorageSync: function(key) {\n      let res = __storage[key];\n      return res;\n    },\n    someNewAPI: function(option) {\n      setTimeout(() => {\n        option.success(option.num);\n      });\n    },\n    showActionSheet: function(option) {\n      setTimeout(() => {\n        option.success && option.success(option);\n      });\n    },\n    checkSession: function(option) {\n      if (typeof option === 'function') {\n        throw new Error('option should not be a function');\n      }\n      setTimeout(() => {\n        option.success({ errMsg: 'checkSession:ok' });\n      });\n    }\n  };\n\n  before(function() {\n    global.wx = wx;\n  });\n\n  it('install', function(done) {\n    let task = ensureAllTaskDone(['test-request-catch', 'test-storage', 'test-checkSession'], done);\n\n    let wepy = {};\n    usePromisifyInstall(wepy);\n\n    expect(wepy.wx.request).is.a('function');\n\n    let promise = wepy.wx.request();\n\n    expect(promise).is.a('promise');\n\n    promise.catch(e => {\n      expect(e).is.an('error');\n      expect(e.message).to.equal('timeout');\n      task.done('test-request-catch');\n    });\n\n    wepy.wx.getStorage({ key: 'mydata' }).then(res => {\n      expect(res).to.deep.equal(__storage.mydata);\n      task.done('test-storage');\n    });\n\n    expect(wepy.wx.getStorageSync('mydata')).to.deep.equal(__storage.mydata);\n\n    wepy.wx.checkSession().then(res => {\n      expect(res).to.deep.equal({ errMsg: 'checkSession:ok' });\n      task.done('test-checkSession');\n    });\n  });\n\n  it('install appends array list', function(done) {\n    let wepy = {};\n\n    usePromisifyInstall(wepy, { someNewAPI: false, getStorage: true });\n\n    wepy.wx.someNewAPI({ num: 1 }).then(res => {\n      expect(res).to.equal(1);\n      done();\n    });\n  });\n\n  it('install get rid apis', function(done) {\n    let wepy = {};\n    usePromisifyInstall(wepy, ['getStorage']);\n    wepy.wx.getStorage({\n      key: 'mydata',\n      success: function(res) {\n        expect(res).is.deep.equal(__storage.mydata);\n        done();\n      }\n    });\n  });\n\n  it('params fix testing', function(done) {\n    let wepy = {};\n    usePromisifyInstall(wepy);\n\n    wepy.wx.setStorage('mydata', { b: 1 }).then(() => {\n      wepy.wx.getStorage('mydata').then(res => {\n        expect(res).to.deep.equal({ b: 1 });\n        expect(__storage.mydata).to.deep.equal(res);\n        done();\n      });\n    });\n  });\n\n  it('test err-first promisify', function(done) {\n    let task = ensureAllTaskDone(['test-greater', 'test-less'], done);\n\n    let isGreaterThan10 = function(num, callback) {\n      setTimeout(function() {\n        if (num > 10) {\n          callback(null, true);\n        } else {\n          callback(new Error('wrong'), false);\n        }\n      }, 300);\n    };\n\n    let wepy = {};\n    usePromisifyInstall(wepy);\n\n    let promisifyFn = wepy.promisify(isGreaterThan10, null, 'error-first');\n\n    promisifyFn(11).then(res => {\n      expect(res).to.equal(true);\n      task.done('test-greater');\n    });\n\n    promisifyFn(9)\n      .then(() => {\n        throw new Error('should not run here');\n      })\n      .catch(e => {\n        expect(e).is.an('error');\n        expect(e.message).to.equal('wrong');\n        task.done('test-less');\n      });\n  });\n\n  it('test weapp-style promisify', function(done) {\n    let task = ensureAllTaskDone(['test-greater', 'test-less'], done);\n\n    let isGreaterThan10 = function(option) {\n      if (option.num > 10) {\n        option.success(true);\n      } else {\n        option.fail(new Error('wrong'));\n      }\n    };\n\n    let wepy = {};\n    usePromisifyInstall(wepy);\n\n    let promisifyFn = wepy.promisify(isGreaterThan10);\n\n    promisifyFn({ num: 11 }).then(res => {\n      expect(res).to.equal(true);\n      task.done('test-greater');\n    });\n\n    promisifyFn({ num: 9 })\n      .then(() => {\n        throw new Error('should not run here');\n      })\n      .catch(e => {\n        expect(e).is.an('error');\n        expect(e.message).to.equal('wrong');\n        task.done('test-less');\n      });\n  });\n\n  it('test simplify', function(done) {\n    let wepy = {},\n      originParamsArr = [\n        {\n          itemList: 0,\n          itemColor: 0\n        },\n        {\n          itemList: ['A', 'B', 'C'],\n          itemColor: '#000'\n        },\n        {\n          itemList: 'test?id=1'\n        }\n      ],\n      task = ensureAllTaskDone(\n        (function() {\n          return originParamsArr.map((item, index) => index);\n        })(),\n        done\n      );\n\n    usePromisifyInstall(wepy);\n\n    for (let item of originParamsArr) {\n      let filterParams = Object.values(item);\n      wepy.wx\n        .showActionSheet(...filterParams)\n        .then(res => {\n          delete res.success;\n          delete res.fail;\n          expect(res).to.deep.equal(item);\n          task.done(originParamsArr.indexOf(item));\n        })\n        .catch(e => {\n          // eslint-disable-next-line no-console\n          console.log(e);\n        });\n    }\n  });\n\n  after(function() {\n    delete global.wx;\n  });\n});\n"
  },
  {
    "path": "packages/x/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n# 2.1.0 (2020-07-04)\n\n**Note:** Version bump only for package @wepy/x\n\n\n\n\n\n# 2.1.0-alpha.10 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/x\n\n\n\n\n\n# 2.1.0-alpha.9 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/x\n\n\n\n\n\n# 2.1.0-alpha.8 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/x\n\n\n\n\n\n# 2.1.0-alpha.7 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/x\n\n\n\n\n\n# 2.1.0-alpha.6 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/x\n\n\n\n\n\n# 2.1.0-alpha.5 (2020-06-21)\n\n**Note:** Version bump only for package @wepy/x\n\n\n\n\n\n# [2.1.0-alpha.4](https://github.com/Tencent/wepy/compare/v2.1.0-alpha.2...v2.1.0-alpha.4) (2020-06-20)\n\n**Note:** Version bump only for package @wepy/x\n"
  },
  {
    "path": "packages/x/README.md",
    "content": "[English](./README_EN.md) | 简体中文\n\n# WePY 2.0中的Vuex \n\n## 安装\n\n```\nnpm install @wepy/x vuex --save\n```\n\n## 用法\n\n1. 安装Vuex \n\n```\n// app.wpy\nimport wepy from '@wepy/core';\nimport vuex from '@wepy/x';\n\nwepy.use(vuex);\n```\n\n2. 初始化store\n\n```\n// ~/store.js\nimport Vuex from '@wepy/x';\n\nexport default new Vuex.Store({\n  state: {\n    num: 0\n  },\n  mutations: {\n    increment (state) {\n      state.num++;\n    }\n  },\n  actions: {\n    increment ({ commit }) {\n      commit('increment');\n    },\n    incrementAsync ({ commit }) {\n      setTimeout(() => commit('increment'), 1000);\n    }\n  }\n})\n```\n\n3. 映射到组件\n\n```\n// ~/counter.wpy\n<template>\n  <div> {{num}} </div>\n  <button @tap=\"increment\"> Increment </button>\n  <button @tap=\"incrementAsync\"> Increment Async </button>\n</template>\n<script>\nimport wepy from '@wepy/core';\nimport { mapState, mapActions } from '@wepy/x';\n\nwepy.component({\n  computed: {\n    ...mapState([ 'num' ])\n  },\n  methods: {\n    ...mapActions([ 'increment', 'incrementAsync' ])\n  }\n})\n```\n\n## 文件\n\n[https://vuex.vuejs.org/](https://vuex.vuejs.org/)\n\n## 其他\n\n目前不支持 [Vuex 模块](https://vuex.vuejs.org/guide/modules.html) 。  在此处检查 [问题](https://github.com/Tencent/wepy/issues/2191) 。"
  },
  {
    "path": "packages/x/README_EN.md",
    "content": "English | [简体中文](./README.md)\n\n# Vuex in WePY 2.0 \n\n## Install\n\n```\nnpm install @wepy/x vuex --save\n```\n\n## Usage\n\n1. Install Vuex \n```\n// app.wpy\nimport wepy from '@wepy/core';\nimport vuex from '@wepy/x';\n\nwepy.use(vuex);\n```\n\n2. Initialize a store\n```\n// ~/store.js\nimport Vuex from '@wepy/x';\n\nexport default new Vuex.Store({\n  state: {\n    num: 0\n  },\n  mutations: {\n    increment (state) {\n      state.num++;\n    }\n  },\n  actions: {\n    increment ({ commit }) {\n      commit('increment');\n    },\n    incrementAsync ({ commit }) {\n      setTimeout(() => commit('increment'), 1000);\n    }\n  }\n})\n```\n\n3. Map to Component\n```\n// ~/counter.wpy\n<template>\n  <div> {{num}} </div>\n  <button @tap=\"increment\"> Increment </button>\n  <button @tap=\"incrementAsync\"> Increment Async </button>\n</template>\n<script>\nimport wepy from '@wepy/core';\nimport { mapState, mapActions } from '@wepy/x';\n\nwepy.component({\n  computed: {\n    ...mapState([ 'num' ])\n  },\n  methods: {\n    ...mapActions([ 'increment', 'incrementAsync' ])\n  }\n})\n```\n\n## Document \n[https://vuex.vuejs.org/](https://vuex.vuejs.org/)\n\n## Other\n[Vuex Module](https://vuex.vuejs.org/guide/modules.html) is not supportted currently. Check the [Issue](https://github.com/Tencent/wepy/issues/2191) here.\n"
  },
  {
    "path": "packages/x/dist/index.js",
    "content": "'use strict';\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nvar vuex = require('vuex');\n\nvar version = \"2.0.4\";\n\nfunction wepyInstall(wepy) {\n  vuex.install(wepy);\n\n  wepy.mixin({\n    created: function() {\n      var this$1 = this;\n\n      var computed = this.$options.computed;\n      var loop = function ( k ) {\n        if (computed[k].vuex) {\n          this$1.$watch(\n            k,\n            function() {\n              this._computedWatchers[k].evaluate();\n            },\n            { deep: true }\n          );\n        }\n      };\n\n      for (var k in computed) loop( k );\n    }\n  });\n}\n\nvar index = {\n  Store: vuex.Store,\n  install: wepyInstall,\n  version: version,\n  mapState: vuex.mapState,\n  mapMutations: vuex.mapMutations,\n  mapGetters: vuex.mapGetters,\n  mapActions: vuex.mapActions,\n  createNamespacedHelpers: vuex.createNamespacedHelpers\n};\n\nexports.Store = vuex.Store;\nexports.mapState = vuex.mapState;\nexports.mapMutations = vuex.mapMutations;\nexports.mapGetters = vuex.mapGetters;\nexports.mapActions = vuex.mapActions;\nexports.createNamespacedHelpers = vuex.createNamespacedHelpers;\nexports.default = index;\nexports.install = wepyInstall;\nexports.version = version;\n"
  },
  {
    "path": "packages/x/index.js",
    "content": "import { Store, install, mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers } from 'vuex';\n\nconst version = __VERSION__;\n\nfunction wepyInstall(wepy) {\n  install(wepy);\n\n  wepy.mixin({\n    created: function() {\n      let computed = this.$options.computed;\n      for (let k in computed) {\n        if (computed[k].vuex) {\n          this.$watch(\n            k,\n            function() {\n              this._computedWatchers[k].evaluate();\n            },\n            { deep: true }\n          );\n        }\n      }\n    },\n    // When page unload, page instance will lose.\n    // But the store data dependences they are still present\n    onUnload: function () {\n      // List all keys in computed watchers\n      for (let key in this._computedWatchers) {\n        const item = this._computedWatchers[key];\n        // Clean deps\n        item.deps = item.deps.filter(dep => {\n          // If sub.vm === current page, then remove it\n          dep.subs = dep.subs.filter(sub => sub.vm !== this);\n          if (dep.subs.length === 0) {\n            // Remove dep ids\n            item.depIds.delete(dep.id);\n            return false;\n          }\n          return true;\n        })\n      }\n    }\n  });\n}\n\nexport default {\n  Store,\n  install: wepyInstall,\n  version,\n  mapState,\n  mapMutations,\n  mapGetters,\n  mapActions,\n  createNamespacedHelpers\n};\n\nexport {\n  Store,\n  wepyInstall as install,\n  version,\n  mapState,\n  mapMutations,\n  mapGetters,\n  mapActions,\n  createNamespacedHelpers\n};\n"
  },
  {
    "path": "packages/x/package.json",
    "content": "{\n  \"name\": \"@wepy/x\",\n  \"version\": \"2.1.1-alpha.0\",\n  \"description\": \"Vuex in WePY\",\n  \"main\": \"dist/index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/Tencent/wepy.git\"\n  },\n  \"keywords\": [\n    \"Vuex\",\n    \"WePY\"\n  ],\n  \"author\": {\n    \"name\": \"Gcaufy\",\n    \"email\": \"gcaufy@gmail.com\"\n  },\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/Tencent/wepy/issues\"\n  },\n  \"homepage\": \"https://github.com/Tencent/wepy#readme\",\n  \"dependencies\": {\n    \"vuex\": \"^3.1.1\"\n  },\n  \"readme\": \"ERROR: No README data found!\",\n  \"_id\": \"@wepy/x@2.1.1-alpha.0\",\n  \"_commitid\": \"8358ad2\",\n  \"gitHead\": \"5a25776457360bbbbc54a4d059f6bc7c032d5df3\"\n}\n"
  },
  {
    "path": "scripts/bootstrap.sh",
    "content": "#!/bin/bash\nset -e\n\nprod=$1\n\ninfo() {\n    printf \"\\e[34m[➧]\\e[0m ${1}\\n\"\n}\n\nerror() {\n    printf \"\\e[31m[✘]\\e[0m ${1}\\n\"\n}\n\nsuccess() {\n    printf \"\\e[32m[✔]\\e[0m ${1}\\n\"\n}\n\nfunction toWinPath() {\n    echo \"$1\" | sed -e 's/^\\///' -e 's/\\//\\\\/g' -e 's/^./\\0:/'\n}\n\nfunction toPosixPath() {\n    echo \"/$1\" | sed -e 's/\\\\/\\//g' -e 's/://' -e 's/\\/\\//\\//g'\n}\n\n# Install packages, if yarn is installed then use yarn to install packages.\nfunction installPackage() {\n    if type yarn >/dev/null 2>&1; then\n        yarn install $prod\n    else\n        npm install $prod\n    fi\n}\n\nglobalDirForWin=$(npm config get prefix)\ncurrentDirForPosix=$(pwd)\n\ncurrentDirForWin=$(toWinPath $currentDirForPosix)\nglobalDirForPosix=$(toPosixPath $globalDirForWin)\n\n\nos=\"win\"\nuname=$(uname)\n\nif [ \"$uname\"x = \"Darwin\"x ]; then\n    os=\"mac\"\n    globalDirForPosix=\"$globalDirForPosix/bin\"\nfi\n\n\nif [ \"$prod\"x = \"--production\"x ]; then\n\n# Generate dev and debug bin file\n  array=( dev debug )\n  for mod in \"${array[@]}\"\n  do\n    params=\"\"\n    if [ \"$mod\"x = \"debug\"x ]; then\n        params=\" --inspect-brk\"\n    fi\n\n    cat > \"$globalDirForPosix/wepy-$mod\" <<- EOF\n#!/bin/sh\nbasedir=\\$(dirname \"\\$(echo \"\\$0\" | sed -e 's,\\\\\\\\,/,g')\")\n\ncase \\`uname\\` in\n    *CYGWIN*) basedir=\\`cygpath -w \"\\$basedir\"\\`;;\nesac\n\nif [ -x \"\\$basedir/node\" ]; then\n  \"\\$basedir/node\"$params \"$currentDirForPosix/packages/wepy-cli/bin/wepy.js\" \"\\$@\"\n  ret=\\$?\nelse\n  node$params \"$currentDirForPosix/packages/wepy-cli/bin/wepy.js\" \"\\$@\"\n  ret=\\$?\nfi\nexit \\$ret\nEOF\n\n    chmod +x \"$globalDirForPosix/wepy-$mod\"\n    success \"generated: $globalDirForPosix/wepy-$mod\"\n\n\n    # If it's win then generate cmd file\n    if [ \"$os\"x = \"win\"x  ]; then\n\n      cat > \"$globalDirForPosix/wepy-$mod.cmd\" <<- EOF\n@IF EXIST \"%~dp0\\node.exe\" (\n  \"%~dp0\\node.exe\"$params \"$currentDirForWin\\packages\\wepy-cli\\bin\\wepy.js\" %*\n) ELSE (\n  @SETLOCAL\n  @SET PATHEXT=%PATHEXT:;.JS;=;%\n  node$params \"$currentDirForWin\\packages\\wepy-cli\\bin\\wepy.js\" %*\n\n)\nEOF\n\n      success \"generated: $globalDirForPosix/wepy-$mod.cmd\"\n\n    fi\n  done\n\nfi\n\ncd $currentDirForPosix\n\ninstallPackage\n\n# Run npm install for every packages\n# Change to install wepy-cli only\npackages=$(ls -1 ./packages | grep \"wepy-cli\")\nfor package in ${packages[@]}\ndo\n    cd \"$currentDirForPosix/packages/$package\"\n    info \"install npm packages for $package\"\n\n    installPackage\n\ndone\n"
  },
  {
    "path": "scripts/build.js",
    "content": "const path = require('path');\nconst fs = require('fs-extra');\nconst rollup = require('rollup');\nconst zlib = require('zlib');\nconst config = require('./config');\n\nfunction build(config) {\n  let output = config.output;\n  let { file } = output;\n\n  return rollup\n    .rollup(config)\n    .then(bundle => bundle.generate(output))\n    .then(rst => {\n      write(file, rst.code);\n    })\n    .catch(e => {\n      throw e;\n    });\n}\n\nfunction write(dest, code, zip) {\n  return new Promise((resolve, reject) => {\n    function report(extra) {\n      // eslint-disable-next-line\n      console.log(blue(path.relative(process.cwd(), dest)) + ' ' + getSize(code) + (extra || ''));\n      resolve();\n    }\n\n    fs.outputFile(dest, code)\n      .then(() => {\n        if (zip) {\n          zlib.gzip(code, (err, zipped) => {\n            if (err) return reject(err);\n            report(' (gzipped: ' + getSize(zipped) + ')');\n          });\n        } else {\n          report();\n        }\n      })\n      .catch(reject);\n  });\n}\n\nfunction getSize(code) {\n  return (code.length / 1024).toFixed(2) + 'kb';\n}\n\nfunction blue(str) {\n  return '\\x1b[1m\\x1b[34m' + str + '\\x1b[39m\\x1b[22m';\n}\n\nlet configs = config.getAllBuilds();\n\nconfigs.forEach(config => {\n  build(config);\n});\n"
  },
  {
    "path": "scripts/build.sh",
    "content": "#!/bin/bash\nset -e\n\nif [ -z \"$TEST_GREP\" ]; then\n   TEST_GREP=\"\"\nfi\n\nnode=\"node\"\n\nif [ \"$TEST_DEBUG\" ]; then\n   node=\"node --inspect --debug-brk\"\nfi\n\n\ncd packages/wepy/\nbabel --presets es2015,stage-1 src/ --out-dir lib/ --source-maps\n\ncd ../wepy-cli/\nbabel --presets es2015,stage-1 src/ --out-dir lib/ --source-maps\n"
  },
  {
    "path": "scripts/ci-release.js",
    "content": "/* eslint no-console: 0 */\n\nconst execa = require('execa');\n\nconst ALLOW_VERSION = ['major', 'minor', 'patch', 'premajor', 'preminor', 'prepatch', 'prerelease'];\nconst ALLOW_TAG = ['alpha', 'beta', 'next'];\n\n// release: major release\n// release: patch release on alpha\n// release: prepatch release on beta\n\nfunction parseMsg(msg) {\n  if (!msg.startsWith('release:')) {\n    throw Error('This is not a release message');\n  }\n  const words = msg.replace('release: ', '').split(' ');\n  const version = words[0];\n  const tag = words[3];\n\n  if (ALLOW_VERSION.indexOf(version) === -1) {\n    throw new Error(`Invalid version: ${version}`);\n  }\n\n  if (tag && ALLOW_TAG.indexOf(tag) === -1) {\n    throw new Error(`Invalid tag: ${tag}`);\n  }\n\n  return {\n    version,\n    tag\n  };\n}\n\nfunction release(version, tag) {\n  console.log(`Ready to release a ${version} version${tag ? ' on ' + tag : ''}.`);\n\n  const cmds = [\n    'lerna',\n    'version',\n    version,\n    '--yes',\n    '--force-publish',\n    '--conventional-commits',\n    '--create-release',\n    'github'\n  ];\n\n  if (tag) {\n    // cmds.push('--dist-tag', tag);\n  }\n  console.log('EXEC: ' + cmds.join(' '));\n\n  execa('npx', cmds)\n    .then(res => console.log(res.stdout))\n    .then(() => {\n      const cmds = ['lerna', 'exec', '--', 'npm', 'publish', '--access', 'public'];\n      if (tag) {\n        cmds.push('--tag', tag);\n      }\n      return execa('npx', cmds);\n    })\n    .then(res => console.log(res.stdout))\n    .catch(e => console.log(e));\n}\n\nconst commitMsg = process.env.COMMIT_MESSAGE;\n\nif (commitMsg) {\n  const { version, tag } = parseMsg(commitMsg);\n\n  release(version, tag);\n}\n\n"
  },
  {
    "path": "scripts/clean.js",
    "content": "const rimraf = require('rimraf');\n\nconsole.log('Clear all dependencies');\n\nrimraf.sync('node_modules');\nrimraf.sync('yarn.lock');\nrimraf.sync('package-lock.json');\nrimraf.sync('packages/*/node_modules');\nrimraf.sync('packages/*/yarn.lock');\nrimraf.sync('packages/*/package-lock.json');\n"
  },
  {
    "path": "scripts/config.js",
    "content": "const buble = require('rollup-plugin-buble');\nconst replace = require('rollup-plugin-replace');\nconst path = require('path');\n\nconst banner = `\n /* Tencent is pleased to support the open source community by making WePY available.\n * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.\n *\n * Licensed under the MIT License (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n * http://opensource.org/licenses/MIT\n * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n */`;\n\nconst resolvePkgInfo = pkg => {\n  const pkgPath = path.resolve(__dirname, '../packages', pkg, 'package.json');\n  return require(pkgPath);\n};\n\nconst builds = {\n  core: {\n    entry: 'packages/core/index.js',\n    dest: 'packages/core/dist/wepy.js',\n    env: 'development',\n    format: 'cjs',\n    version: resolvePkgInfo('core').version,\n    banner\n  },\n  'core-ant': {\n    entry: 'packages/core/index.ant.js',\n    dest: 'packages/core/dist/wepy.ant.js',\n    env: 'development',\n    format: 'cjs',\n    version: resolvePkgInfo('core').version,\n    banner\n  },\n  redux: {\n    entry: 'packages/redux/index.js',\n    dest: 'packages/redux/dist/index.js',\n    env: 'development',\n    format: 'cjs',\n    version: resolvePkgInfo('redux').version,\n    banner\n  },\n  x: {\n    entry: 'packages/x/index.js',\n    dest: 'packages/x/dist/index.js',\n    env: 'development',\n    format: 'cjs',\n    version: resolvePkgInfo('x').version,\n    banner\n  },\n  'use-promisify': {\n    entry: 'packages/use-promisify/index.js',\n    dest: 'packages/use-promisify/dist/index.js',\n    env: 'development',\n    format: 'cjs',\n    version: resolvePkgInfo('use-promisify').version,\n    banner\n  },\n  'use-intercept': {\n    entry: 'packages/use-intercept/index.js',\n    dest: 'packages/use-intercept/dist/index.js',\n    env: 'development',\n    format: 'cjs',\n    version: resolvePkgInfo('use-intercept').version,\n    banner\n  }\n};\n\nfunction getConfig(name) {\n  let opt = builds[name];\n  let config = {\n    input: opt.entry,\n    external: opt.external,\n    plugins: [\n      buble({\n        objectAssign: 'Object.assign'\n      })\n    ].concat(opt.options || []),\n    output: {\n      file: opt.dest,\n      format: opt.format,\n      banner: opt.banner,\n      name: opt.moduleName || 'WePY'\n    }\n  };\n  if (opt.env) {\n    config.plugins.push(\n      replace({\n        'process.env.NODE_ENV': JSON.stringify(opt.env),\n        __VERSION__: JSON.stringify(opt.version)\n      })\n    );\n  }\n  return config;\n}\nif (process.env.TARGET) {\n  module.exports = getConfig(process.env.TARGET);\n} else {\n  exports.getBuild = getConfig;\n  exports.getAllBuilds = () => Object.keys(builds).map(getConfig);\n}\n"
  },
  {
    "path": "scripts/install_dev.sh",
    "content": "#!/bin/bash\nset -e\n\nprod=$1\n\ninfo() {\n    printf \"\\e[34m[➧]\\e[0m ${1}\\n\"\n}\n\nerror() {\n    printf \"\\e[31m[✘]\\e[0m ${1}\\n\"\n}\n\nsuccess() {\n    printf \"\\e[32m[✔]\\e[0m ${1}\\n\"\n}\n\nfunction toWinPath() {\n    echo \"$1\" | sed -e 's/^\\///' -e 's/\\//\\\\/g' -e 's/^./\\0:/'\n}\n\nfunction toPosixPath() {\n    echo \"/$1\" | sed -e 's/\\\\/\\//g' -e 's/://' -e 's/\\/\\//\\//g'\n}\n\n\nglobalDirForWin=$(npm config get prefix)\ncurrentDirForPosix=$(pwd)\n\ncurrentDirForWin=$(toWinPath $currentDirForPosix)\nglobalDirForPosix=$(toPosixPath $globalDirForWin)\n\n\nos=\"win\"\nuname=$(uname)\n\nif [ \"$uname\"x = \"Darwin\"x ]; then\n    os=\"mac\"\n    globalDirForPosix=\"$globalDirForPosix/bin\"\nfi\n\n\n# Generate dev and debug bin file\narray=( dev debug )\nfor mod in \"${array[@]}\"\ndo\n  params=\"\"\n  if [ \"$mod\"x = \"debug\"x ]; then\n      params=\" --inspect-brk\"\n  fi\n\n  cat > \"$globalDirForPosix/wepy-$mod\" <<- EOF\n#!/bin/sh\nbasedir=\\$(dirname \"\\$(echo \"\\$0\" | sed -e 's,\\\\\\\\,/,g')\")\n\ncase \\`uname\\` in\n  *CYGWIN*) basedir=\\`cygpath -w \"\\$basedir\"\\`;;\nesac\n\nif [ -x \"\\$basedir/node\" ]; then\n\"\\$basedir/node\"$params \"$currentDirForPosix/packages/cli/bin/wepy.js\" \"\\$@\"\nret=\\$?\nelse\nnode$params \"$currentDirForPosix/packages/cli/bin/wepy.js\" \"\\$@\"\nret=\\$?\nfi\nexit \\$ret\nEOF\n\n  chmod +x \"$globalDirForPosix/wepy-$mod\"\n  success \"generated: $globalDirForPosix/wepy-$mod\"\n\n\n  # If it's win then generate cmd file\n  if [ \"$os\"x = \"win\"x  ]; then\n\n    cat > \"$globalDirForPosix/wepy-$mod.cmd\" <<- EOF\n@IF EXIST \"%~dp0\\node.exe\" (\n\"%~dp0\\node.exe\"$params \"$currentDirForWin\\packages\\cli\\bin\\wepy.js\" %*\n) ELSE (\n@SETLOCAL\n@SET PATHEXT=%PATHEXT:;.JS;=;%\nnode$params \"$currentDirForWin\\packages\\cli\\bin\\wepy.js\" %*\n\n)\nEOF\n\n    success \"generated: $globalDirForPosix/wepy-$mod.cmd\"\n\n  fi\ndone\n"
  },
  {
    "path": "scripts/npm-ci-release.js",
    "content": "/* eslint no-console: 0 */\n\nconst path = require('path');\nconst execa = require('execa');\n\nconst version = process.argv[2];\n// @wepy/cli@2.0.0-alpha.11\n\nif (!version.startsWith('@wepy')) {\n  console.log('Do nothing with this version: \"' + version + '\"');\n  process.exit();\n}\nconst client = 'npm';\n// eslint-disable-next-line no-unused-vars\nconst [_, packageName, ver] = version.split('@');\nconst dirname = packageName.split('/')[1];\n\nif (!dirname || !ver) {\n  console.log('Invalid version: \"' + version + '\"');\n  process.exit();\n}\n\nconst tag = ver.indexOf('alpha') > -1 ? 'alpha' : ver.indexOf('beta') > -1 ? 'beta' : '';\n\nlet publishParams = ['publish', '--access', 'public'];\n\nif (tag) {\n  publishParams = publishParams.concat(['--tag', tag]);\n}\n\nconst cwd = path.join(process.cwd(), 'packages', dirname);\n\nconsole.log('CWD: ' + cwd);\nconsole.log('EXEC: ' + [client].concat(publishParams).join(' '));\n\nexeca(client, publishParams, { cwd })\n  .then(res => {\n    console.log(res.stdout);\n    const distTagParams = ['dist-tag', 'add', version, 'next'];\n    console.log('EXEC: ' + [client].concat(distTagParams).join(' '));\n    return execa(client, distTagParams, { cwd });\n  })\n  .catch(e => {\n    console.log(e);\n  });\n"
  },
  {
    "path": "scripts/npm-tags.js",
    "content": "const fs = require('fs');\nconst path = require('path');\nconst { spawnSync } = require('child_process');\n\n/**\n *\n * Useage:\n * node ./scripts/npm-tags.js beta next\n */\n\nconst packages = fs.readdirSync(path.join(__dirname, '..', 'packages'));\n\nfunction updateAllTag(oldTag, newTag) {\n  packages.forEach(pkg => {\n    updateOneTag(pkg, oldTag, newTag);\n  });\n}\n\nfunction updateOneTag(pkg, oldTag, newTag) {\n  process.env.FORCE_COLOR = 1;\n\n  const npmPkgName = `@wepy/${pkg}`;\n\n  const viewCmd = ['npm', 'view', npmPkgName, 'dist-tags.' + oldTag];\n\n  console.log('EXEC: ' + viewCmd.join(' '));\n\n  const res = spawnSync(viewCmd.shift(), viewCmd);\n\n  const version = res.stdout.toString('utf-8').trim();\n\n  console.log('OUTPUT: ' + version);\n\n  const addCmd = ['npm', 'dist-tag', 'add', npmPkgName + '@' + version, newTag];\n\n  console.log('EXEC: ' + addCmd.join(' '));\n\n  const outputRes = spawnSync(addCmd.shift(), addCmd);\n\n  const output = outputRes.stdout.toString('utf-8').trim();\n\n  console.log('OUTPUT: ' + output);\n}\n\n// eslint-disable-next-line no-unused-vars\n(function main([bin, file, ...args]) {\n  updateAllTag.apply(null, args);\n})(process.argv);\n"
  },
  {
    "path": "scripts/npm_publish/index.js",
    "content": "#!/usr/bin/env node\n\nconst commander = require('commander');\nconst autoPublish = require('./lib/auto');\nconst interactPublish = require('./lib/interact');\nconst isGitWorkTreeClean = require('./lib/check_repo_clean');\nconst log = require('./lib/log');\n\nisGitWorkTreeClean()\n  .then(() => {\n    commander\n      .command('publish [name]')\n      .option('-t, --tag <tag>', 'publish tag')\n      .option('-v, --version <ver>', 'publish version')\n      .option('-i, --increase <increase>', 'version increase')\n      .option('-q, --no-interact', 'with out interact')\n      .action(function(name, opt) {\n        name = name || '*';\n\n        if (opt.interact) {\n          interactPublish(name, opt);\n        } else {\n          autoPublish(name, opt);\n        }\n      });\n\n    commander.parse(process.argv);\n  })\n  .catch(e => {\n    log.error(e.message);\n  });\n"
  },
  {
    "path": "scripts/npm_publish/lib/auto.js",
    "content": "const path = require('path');\nconst readPkg = require('read-pkg');\nconst writePkg = require('write-pkg');\nconst semver = require('semver');\n\nconst execa = require('execa');\n\nconst log = require('./log');\n\nconst githash = () => execa('git', ['rev-parse', '--short', 'HEAD']).then(rst => rst.stdout);\n\nconst gitadd = files => execa('git', ['add'].concat(files));\n\nconst gitcommit = msg => execa('git', ['commit', '-m', `${msg}`, '--no-verify']);\n\nconst gittag = msg => execa('git', ['tag', `${msg}`]);\n\nconst gitpush = () => execa('git', ['push']);\n\nconst gitpushtag = () => execa('git', ['push', '--tags']);\n\nconst publishParams = ['publish', '.', '--access=public'];\n\nconst npmpublish = tag => execa('npm', tag ? publishParams.concat(['--tag', tag]) : publishParams);\n\n/*\n * auto publish a npm package\n */\nmodule.exports = function autoPublish(nameOrPkg, opt) {\n  let pkg;\n  if (!opt.interact) {\n    if (!opt.name) {\n      log.error('Missing a package name');\n      return;\n    }\n    if (!opt.ver && !opt.increase) {\n      log.error('You have to set a version or a increase');\n      return;\n    }\n  }\n\n  if (typeof nameOrPkg === 'string') {\n    // Enter directory\n    let cwd = path.join('packages', nameOrPkg);\n    process.chdir(cwd);\n    pkg = readPkg.sync({ cwd: './' });\n  } else {\n    pkg = nameOrPkg;\n  }\n\n  // Only give a increase\n  if (!opt.interact && opt.increase && !opt.ver) {\n    opt.ver = opt.tag ? semver.inc(pkg.version, opt.increase, opt.tag) : semver.inc(pkg.version, opt.increase);\n  }\n\n  return githash()\n    .then(hash => {\n      let id = `${pkg.name}@${opt.ver}`;\n      log.info('Writing package.json');\n      return writePkg(Object.assign({}, pkg, { version: opt.ver, _id: id, _commitid: hash })).then(() => {\n        log.info('Tag: ' + id);\n        gitadd('package.json')\n          .then(() => {\n            return gitcommit('release: ' + id);\n          })\n          .then(() => {\n            return gittag(id);\n          })\n          .then(() => {\n            return gitpush();\n          })\n          .then(() => {\n            return gitpushtag();\n          })\n          .then(() => {\n            log.info('Pushing to npm');\n            if (opt.tag && opt.tag !== 'release') {\n              return npmpublish(opt.tag);\n            } else {\n              return npmpublish();\n            }\n          })\n          .then(() => {\n            log.success('done');\n            return true;\n          });\n      });\n    })\n    .catch(e => {\n      log.error(e);\n    });\n};\n"
  },
  {
    "path": "scripts/npm_publish/lib/check_repo_clean.js",
    "content": "const execa = require('execa');\n\n// check if the work tree is clean\nmodule.exports = function isWorkTreeClean() {\n  return execa('git', ['status', '-s']).then(rst => {\n    if (rst.stderr) {\n      throw new Error(rst.stderr);\n    } else if (rst.stdout) {\n      throw new Error('Work tree is not clean, check \"git status\"');\n    }\n    return true;\n  });\n};\n"
  },
  {
    "path": "scripts/npm_publish/lib/interact.js",
    "content": "const path = require('path');\nconst readPkg = require('read-pkg');\nconst semver = require('semver');\nconst chalk = require('chalk');\nconst { Select, Input } = require('enquirer');\n\nconst autoPublish = require('./auto');\nconst log = require('./log');\n\nconst PACKAGES_DIR = './packages/';\n\n/*\n * interact publish a npm package\n */\nmodule.exports = function interactPublish(name, opt) {\n  let flow = Promise.resolve(name);\n\n  if (name === '*') {\n    const util = require('util');\n    const fs = require('fs');\n    const readdir = util.promisify(fs.readdir);\n\n    flow = readdir(PACKAGES_DIR)\n      .then(dirs => {\n        return dirs.filter(dir => fs.statSync(path.join(PACKAGES_DIR, dir)).isDirectory());\n      })\n      .then(dirs => {\n        return new Select({\n          name: 'package',\n          message: 'Pick a package:',\n          choices: dirs\n        }).run();\n      });\n  }\n\n  flow\n    .then(name => {\n      // Enter directory\n      let cwd = path.join('packages', name);\n      process.chdir(cwd);\n\n      let pkg = readPkg.sync({ cwd: './' });\n      let pkgVersion = pkg.version;\n\n      log.info('Publish package: ' + chalk.cyan(`${pkg.name}@${pkg.version}`));\n\n      let publishOpt = {\n        version: opt.ver || '',\n        tag: opt.tag || ''\n      };\n\n      return new Select({\n        name: 'tag',\n        message: 'Pick a tag:',\n        choices: ['release', 'alpha', 'beta', 'custom']\n      })\n        .run()\n        .then(tag => {\n          if (tag === 'custom') {\n            return new Input({\n              message: 'Input custom tag'\n            }).run();\n          }\n          publishOpt.tag = tag;\n          return tag;\n        })\n        .then(tag => {\n          let choices = [];\n          choices = ['patch', 'minor', 'major'].map(v => {\n            if (tag !== 'release') {\n              v = 'pre' + v;\n            }\n            let ver = semver.inc(pkgVersion, v, tag === 'release' ? '' : tag);\n            return {\n              message: `${v} (${ver})`,\n              value: ver\n            };\n          });\n          if (tag !== 'release') {\n            let prerelease = semver.inc(pkgVersion, 'prerelease', tag);\n            choices.push({\n              message: `prerelease (${prerelease})`,\n              value: prerelease\n            });\n          }\n          return new Select({\n            name: 'version',\n            message: 'Chooice a publish version:',\n            choices: choices\n          }).run();\n        })\n        .then(version => {\n          publishOpt.ver = version;\n          publishOpt.interact = true;\n          return autoPublish(pkg, publishOpt);\n        });\n    })\n    .catch(e => {\n      if (e !== '') {\n        // Command + C cancelled the selection.\n        log.error(e);\n      }\n    });\n};\n"
  },
  {
    "path": "scripts/npm_publish/lib/log.js",
    "content": "const chalk = require('chalk');\n\nmodule.exports = {\n  info(msg) {\n    // eslint-disable-next-line no-console\n    console.log(chalk.yellow('⦿ ') + msg);\n  },\n  success(msg) {\n    // eslint-disable-next-line no-console\n    console.log(chalk.green('✔ ') + msg);\n  },\n  error(e) {\n    // eslint-disable-next-line no-console\n    console.log(chalk.red('✘ ') + e);\n  }\n};\n"
  },
  {
    "path": "scripts/release.js",
    "content": "const semver = require('semver');\nconst execa = require('execa');\nconst { Select, Input } = require('enquirer');\n\n/*\n * interact publish a npm package\n */\nfunction interactPublish() {\n  let flow = Promise.resolve();\n  return flow\n    .then(() => {\n      let publishOpt = {\n        version: '',\n        tag: ''\n      };\n\n      const pkgVersion = require('../lerna.json').version;\n\n      return new Select({\n        name: 'tag',\n        message: 'Pick a tag:',\n        choices: ['release', 'alpha', 'beta', 'custom']\n      })\n        .run()\n        .then(tag => {\n          if (tag === 'custom') {\n            return new Input({\n              message: 'Input custom tag'\n            }).run();\n          }\n          publishOpt.tag = tag;\n          return tag;\n        })\n        .then(tag => {\n          let choices = [];\n          choices = ['patch', 'minor', 'major'].map(v => {\n            if (tag !== 'release') {\n              v = 'pre' + v;\n            }\n            let ver = semver.inc(pkgVersion, v, tag === 'release' ? '' : tag);\n            return {\n              message: `${v} (${ver})`,\n              value: v\n            };\n          });\n          if (tag !== 'release') {\n            let prerelease = semver.inc(pkgVersion, 'prerelease', tag);\n            choices.push({\n              message: `prerelease (${prerelease})`,\n              value: 'prerelease'\n            });\n          }\n          return new Select({\n            name: 'version',\n            message: 'Chooice a publish version:',\n            choices: choices\n          }).run();\n        })\n        .then(version => {\n          publishOpt.version = version;\n          return publishOpt;\n        });\n    })\n    .catch(e => {\n      // eslint-disable-next-line\n      console.log(e);\n    });\n}\n\ninteractPublish().then(opt => {\n  let msg = `release: ${opt.version} release`;\n  if (opt.tag) {\n    msg += ` on ${opt.tag}`;\n  }\n  const cmds = ['git', 'commit', '-m', `\"${msg}\"`, '--allow-empty', '--no-verify'];\n\n  execa(cmds.shift(), cmds).then(res => {\n    // eslint-disable-next-line\n    console.log(res.stdout);\n  });\n});\n"
  },
  {
    "path": "scripts/test-build.sh",
    "content": "#!/bin/bash\n\n# test wepy new demo\n\n# Start in tasks/ even if run from root directory\ncd \"$(dirname \"$0\")\"\n\nfunction cleanup() {\n    echo 'Cleaning up.'\n}\n\n\n# Error messages are redirected to stderr\nfunction handle_error() {\n    echo \"$(basename $0): ERROR! An error was encountered executing line $1.\" 1>&2;\n    cleanup\n    echo 'Exiting with error.' 1>&2;\n    exit 1\n}\n\n\nfunction handle_exit() {\n    cleanup\n    echo 'Exiting without error.' 1>&2;\n    exit\n}\n\n\n# Exit the script with a helpful error message when any error is encountered\ntrap 'set +x; handle_error $LINENO $BASH_COMMAND' ERR\n\n# Cleanup before exit on any termination signal\ntrap 'set +x; handle_exit' SIGQUIT SIGTERM SIGINT SIGKILL SIGHUP\n\n# Echo every command being executed\nset -x\n\n\n# Go to root\ncd ..\nroot_path=$PWD\n\n\nnpm link packages/cli\n\nwepy -v\n\nwepy list\n\nmkdir -p /tmp/templates/\ncd /tmp/templates/\n\nexps=\"${root_path}/scripts/exps\"\nfor exp in ${exps}/*; do\n    name=$(basename $exp .exp)\n\texpect \"$root_path\"/scripts/exps/\"$name\".exp \"/tmp/templates/${name}\"\n    pwd\n    ls -la\n\tcd \"/tmp/templates/${name}\"\n\tnpm install\n\tnode \"$root_path\"/packages/cli/bin/wepy.js build\ndone\n\n# Build multiple version for standard project.\ncd /tmp/templates/standard\n\nnode \"$root_path\"/packages/cli/bin/wepy.js build\n\n# Test build demos\ncd /tmp/templates\n\n# node \"$root_path\"/packages/cli/bin/wepy.js init wepyjs/wepy-wechat-demo wepy-wechat-demo\ngit clone https://github.com/wepyjs/wepy-wechat-demo.git --branch 2.0\n\ncd wepy-wechat-demo\nnpm install\nnpm run build\n\ncd ..\n\n# Cleanup\ncleanup\n"
  },
  {
    "path": "scripts/unittest.js",
    "content": "const path = require('path');\nconst { spawnSync } = require('child_process');\n\nconst packages = [\n  'babel-plugin-import-regenerator',\n  'cli',\n  //'compiler-babel',\n  'compiler-less',\n  'compiler-sass',\n  //'compiler-stylus',\n  //'compiler-typescript',\n  'core',\n  'plugin-define'\n  //'plugin-eslint',\n  //'plugin-uglifyjs',\n  //'redux',\n  //'use-promisify',\n  //'x',\n];\n\nfunction testAll(pkgs) {\n  if (pkgs.length === 0) {\n    pkgs = packages;\n  }\n  pkgs.forEach(pkg => {\n    testOne(pkg);\n  });\n}\n\nfunction testOne(name) {\n  process.env.FORCE_COLOR = 1;\n  spawnSync('npm', ['run', 'test'], {\n    cwd: path.join(process.cwd(), 'packages', name),\n    env: process.env,\n    stdio: 'inherit'\n  });\n}\n\n// eslint-disable-next-line no-unused-vars\n(function main([bin, file, ...args]) {\n  testAll(args);\n})(process.argv);\n"
  },
  {
    "path": "test/build-cases/empty.sh",
    "content": "#!/bin/bash\n\nname=$(basename \"$0\" .sh)\ncd /tmp/templates/\n\nwepy init empty $name --no-interactive\n\ncd \"$name\"\nnpm install\n"
  },
  {
    "path": "test/build-cases/standard.sh",
    "content": "#!/bin/bash\n\nname=$(basename \"$0\" .sh)\ncd /tmp/templates/\n\nwepy init standard $name --no-interactive --name test-interactive\n\ncd \"$name\"\nnpm install\n"
  },
  {
    "path": "test/build.sh",
    "content": "#!/bin/bash\n\n# test wepy new demo\n\n# Start in tasks/ even if run from root directory\ncd \"$(dirname \"$0\")\"\n\nfunction cleanup() {\n    echo 'Cleaning up.'\n}\n\n\n# Error messages are redirected to stderr\nfunction handle_error() {\n    echo \"$(basename $0): ERROR! An error was encountered executing line $1.\" 1>&2;\n    cleanup\n    echo 'Exiting with error.' 1>&2;\n    exit 1\n}\n\n\nfunction handle_exit() {\n    cleanup\n    echo 'Exiting without error.' 1>&2;\n    exit\n}\n\n\n# Exit the script with a helpful error message when any error is encountered\ntrap 'set +x; handle_error $LINENO $BASH_COMMAND' ERR\n\n# Cleanup before exit on any termination signal\ntrap 'set +x; handle_exit' SIGQUIT SIGTERM SIGINT SIGKILL SIGHUP\n\n# Echo every command being executed\nset -x\n\n\n# Go to root\ncd ..\nroot_path=$PWD\n\n\nnpm link packages/cli\n\nwepy -v\n\nwepy list\n\nmkdir -p /tmp/templates/\ncd /tmp/templates/\n\nbuildcases=\"${root_path}/test/build-cases\"\nfor bc in ${buildcases}/*; do\n  name=$(basename $bc .sh)\n\t\"$root_path\"/test/build-cases/\"$name\".sh\n\tcd \"/tmp/templates/${name}\"\n\tnode \"$root_path\"/packages/cli/bin/wepy.js build\ndone\n\n# Test build demos\ncd /tmp/templates\n\n# node \"$root_path\"/packages/cli/bin/wepy.js init wepyjs/wepy-wechat-demo wepy-wechat-demo\ngit clone https://github.com/wepyjs/wepy-wechat-demo.git --branch 2.0\n\ncd wepy-wechat-demo\nnpm install\nnpm run build\n\ncd ..\n\n# Cleanup\ncleanup\n"
  },
  {
    "path": "test/scripts/ci-release.test.js",
    "content": ""
  },
  {
    "path": "test/unit.js",
    "content": "const path = require('path');\nconst { spawnSync } = require('child_process');\n\nconst packages = [\n  'babel-plugin-import-regenerator',\n  'cli',\n  //'compiler-babel',\n  'compiler-less',\n  'compiler-sass',\n  //'compiler-stylus',\n  //'compiler-typescript',\n  'core',\n  'plugin-define',\n  //'plugin-eslint',\n  //'plugin-uglifyjs',\n  //'redux',\n  'use-intercept',\n  'use-promisify'\n  //'x',\n];\n\nfunction testAll(pkgs) {\n  if (pkgs.length === 0) {\n    pkgs = packages;\n  }\n  pkgs.forEach(pkg => {\n    testOne(pkg);\n  });\n}\n\nfunction testOne(name) {\n  process.env.FORCE_COLOR = 1;\n  const command = process.platform === 'win32' ? 'npm.cmd' : 'npm';\n  const result = spawnSync(command, ['run', 'test'], {\n    cwd: path.join(process.cwd(), 'packages', name),\n    env: process.env,\n    stdio: 'inherit'\n  });\n  if (result.status !== 0) {\n    throw new Error('Test cases failed in: ' + name);\n  }\n}\n\n// eslint-disable-next-line no-unused-vars\n(function main([bin, file, ...args]) {\n  testAll(args);\n})(process.argv);\n"
  },
  {
    "path": "verpub.config.js",
    "content": "module.exports = {\n  publish: false\n};\n"
  }
]