Merge pull request #3351 from Hanks10100/feature/cleanup

[js] clean up front-end assets and fix test
diff --git a/.gitignore b/.gitignore
index 1c5e235..b7d80e3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,7 +6,6 @@
 *.sw*
 
 # Created by Builder
-examples/build
 web-entry
 test/build
 weex_tmp
@@ -26,22 +25,6 @@
 *.pid
 *.seed
 
-# e2e test
-html5/test/e2e/reports
-html5/test/e2e/screenshots
-html5/test/e2e/logs
-
-# render test
-html5/test/render/vue/data/build
-examples/vue/test/
-
-# Created by Weex Web Packer
-html5/browser/extend/packer.js
-html5/render/browser/extend/packer.js
-
-# Created by weex-vue-bundle-util
-weex-vue-plugins.js
-
 android/playground/app/gradlew
 android/playground/app/gradlew.bat
 android/playground/app/gradle/wrapper/gradle-wrapper.jar
diff --git a/build/rollup.browser.common.config.js b/build/rollup.browser.common.config.js
deleted file mode 100644
index dd8c41c..0000000
--- a/build/rollup.browser.common.config.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-import { rollup } from 'rollup'
-import postcss from 'rollup-plugin-postcss'
-import json from 'rollup-plugin-json'
-import eslint from 'rollup-plugin-eslint'
-import nodeResolve from 'rollup-plugin-node-resolve'
-import commonjs from 'rollup-plugin-commonjs'
-import buble from 'rollup-plugin-buble'
-
-const pkg = require('../package.json')
-const version = pkg.subversion.browser
-const date = new Date().toISOString().split('T')[0].replace(/\-/g, '')
-const banner = `\
-console.log('START WEEX HTML5: ${version} Build ${date}');
-`
-
-export default {
-  entry: './html5/render/browser/index.js',
-  dest: './dist/browser.common.js',
-  banner,
-  format: 'cjs',
-  plugins: [
-    postcss(),
-    json(),
-    eslint({
-      exclude: ['./package.json', '**/*.css']
-    }),
-    nodeResolve({
-      jsnext: true,
-      main: true,
-      browser: true
-    }),
-    commonjs(),
-    buble()
-  ]
-}
diff --git a/build/webpack.examples.config.js b/build/webpack.examples.config.js
deleted file mode 100644
index 5d8b25d..0000000
--- a/build/webpack.examples.config.js
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-var path = require('path');
-var fs = require('fs');
-var webpack = require('webpack');
-// var bannerWebpackPlugin = require('./examples-banner-plugin')
-
-var entry = {};
-var bannerExcludeFiles = [];
-
-function walk(dir) {
-  dir = dir || '.'
-  var directory = path.join(__dirname, '../examples', dir);
-  fs.readdirSync(directory)
-    .forEach(function(file) {
-      var fullpath = path.join(directory, file);
-      var stat = fs.statSync(fullpath);
-      var extname = path.extname(fullpath);
-      if (stat.isFile() && (extname === '.we' || extname === '.vue')) {
-        var name = path.join('examples', 'build', dir, path.basename(file, extname));
-        entry[name] = fullpath + '?entry=true';
-        if (extname === '.we') {
-          bannerExcludeFiles.push(name + '.js')
-        }
-      } else if (stat.isDirectory() && file !== 'build' && file !== 'include') {
-        var subdir = path.join(dir, file);
-        walk(subdir);
-      }
-    });
-}
-
-walk();
-
-var banner = '// { "framework": "Vue" }\n'
-
-var bannerPlugin = new webpack.BannerPlugin(banner, {
-  raw: true,
-  exclude: bannerExcludeFiles
-})
-
-module.exports = {
-  entry: entry,
-  output : {
-    path: '.',
-    filename: '[name].js'
-  },
-  module: {
-    loaders: [
-      {
-        test: /\.(we|vue)(\?[^?]+)?$/,
-        loader: 'weex'
-      }
-    ]
-  },
-  plugins: [bannerPlugin]
-}
diff --git a/build/webpack.examples.web.config.js b/build/webpack.examples.web.config.js
deleted file mode 100644
index c28db57..0000000
--- a/build/webpack.examples.web.config.js
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-
-var path = require('path');
-var fs = require('fs-extra');
-var webpack = require('webpack');
-
-var entry = {};
-var bannerExcludeFiles = [];
-var webSrcDirectory = path.join(__dirname, '../examples/web-entry');
-
-function getEntryFileContent (entryPath, vueFilePath) {
-  const relativePath = path.relative(path.join(entryPath, '../'), vueFilePath);
-  return 'var App = require(\'' + relativePath + '\')\n'
-    + 'App.el = \'#root\'\n'
-    + 'new Vue(App)\n'
-}
-
-function walk(dir) {
-  dir = dir || '.';
-  var directory = path.join(__dirname, '../examples', dir);
-  var entryDirectory = path.join(webSrcDirectory, dir);
-  fs.readdirSync(directory)
-    .forEach(function(file) {
-      var fullpath = path.join(directory, file);
-      var stat = fs.statSync(fullpath);
-      var extname = path.extname(fullpath);
-      if (stat.isFile() && extname === '.vue') {
-        var entryFile = path.join(entryDirectory, path.basename(file, extname) + '.js');
-        fs.outputFileSync(entryFile, getEntryFileContent(entryFile, fullpath));
-        var name = path.join('examples', 'build/vue-web', /*path.relative('vue', dir)*/dir, path.basename(file, extname));
-        entry[name] = entryFile + '?entry=true';
-      } else if (stat.isDirectory() && file !== 'build' && file !== 'include') {
-        var subdir = path.join(dir, file);
-        walk(subdir);
-      }
-    });
-}
-
-walk();
-
-var banner = '// NOTE: for vue2.0 and platform:web only.\n'
-
-var bannerPlugin = new webpack.BannerPlugin(banner, {
-  raw: true,
-  exclude: bannerExcludeFiles
-})
-
-module.exports = {
-  entry: entry,
-  output: {
-    path: '.',
-    filename: '[name].js'
-  },
-  module: {
-    loaders: [
-      {
-        test: /\.js$/,
-        loaders: ['babel-loader'],
-        exclude: /node_modules/
-      }, {
-        test: /\.vue(\?[^?]+)?$/,
-        loaders: ['vue-loader']
-      }
-    ]
-  },
-  vue: {
-    optimizeSSR: false,
-    /**
-     * important! should use postTransformNode to add $processStyle for
-     * inline style prefixing.
-     */
-    compilerModules: [
-      {
-        postTransformNode: el => {
-          el.staticStyle = `$processStyle(${el.staticStyle})`
-          el.styleBinding = `$processStyle(${el.styleBinding})`
-        }
-      }
-    ],
-  },
-  plugins: [bannerPlugin]
-}
diff --git a/examples/.gitignore b/examples/.gitignore
deleted file mode 100644
index 2642f80..0000000
--- a/examples/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-local-*
-archive/
\ No newline at end of file
diff --git a/examples/README.md b/examples/README.md
deleted file mode 100644
index 6df102f..0000000
--- a/examples/README.md
+++ /dev/null
@@ -1,21 +0,0 @@
-# Example Guide
-
-## Add an example
-
-* Add a file `newExample.we` copied from [template](./template.we) with [UI Gallery](#ui-gallery) (recommended).
-* In [index.we](./index.we), add an item `{name: 'newExample', title: 'New Example'}` for array `data.cases`
-
-## Rule
-
-0. File name is dash (`-`) separated words, and each word is lower case, e.g. `index.we`, `style-demo.we`
-0. ***DO NOT*** use [builtin components](../doc/components) name as file name, it may fail to run. 
-
-## UI Gallery
-
-> Inspired by Bootstrap.
-
-We import a simple UI Gallery for a consistent UI style. See [UI Gallery Example](./showcase/ui.we) for details.
-
-<img src="http://gtms04.alicdn.com/tps/i4/TB1_v6FMpXXXXXfXXXX7XWpVpXX-278-519.gif" width="160" /> <img src="http://gtms03.alicdn.com/tps/i3/TB13LTOMpXXXXceXXXXIxc4RpXX-944-1316.png" width="214" />
-
-Reference: https://www.npmjs.com/package/weex-components
diff --git a/examples/vanilla/index.js b/examples/vanilla/index.js
deleted file mode 100644
index 6ab399f..0000000
--- a/examples/vanilla/index.js
+++ /dev/null
@@ -1,42 +0,0 @@
-// { "framework": "Vanilla" }
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-
-var body = document.createElement('div', {
-  classStyle: { alignItems: 'center', marginTop: 120 }
-})
-
-var image = document.createElement('image', {
-  attr: { src: 'https://alibaba.github.io/weex/img/weex_logo_blue@3x.png' },
-  classStyle: { width: 360, height: 82 }
-})
-
-var text = document.createElement('text', {
-  attr: { value: 'Hello World' },
-  classStyle: { fontSize: 48 }
-})
-
-body.appendChild(image)
-body.appendChild(text)
-document.documentElement.appendChild(body)
-
-body.addEvent('click', function () {
-  text.setAttr('value', 'Hello Weex')
-})
diff --git a/examples/vue/animation.vue b/examples/vue/animation.vue
deleted file mode 100644
index ef6afcf..0000000
--- a/examples/vue/animation.vue
+++ /dev/null
@@ -1,149 +0,0 @@
-<template>
-  <div>
-    <panel title="Transform" type="primary">
-      <button value="Rotate" @click.native="rotate" type="primary" size="middle"></button>
-      <button value="Scale" @click.native="scale" type="primary" size="middle" style="margin-top:12px;"></button>
-      <button value="Translate" @click.native="translate" type="primary" size="middle"
-                 style="margin-top:12px;"></button>
-      <button value="Transform" @click.native="transform" type="success" size="middle"
-                 style="margin-top:12px;"></button>
-    </panel>
-
-    <panel title="Others" type="primary">
-      <button value="BgColor" @click.native="color" type="primary" size="middle"></button>
-      <button value="Opacity" @click.native="opacity" type="primary" size="middle"
-                 style="margin-top:12px;"></button>
-      <button value="All" @click.native="composite" type="success" size="middle" style="margin-top:12px;"></button>
-    </panel>
-
-    <div ref="block" class="block" :style="{ transformOrigin: transformOrigin }">
-      <text class="block-txt">Anim</text>
-    </div>
-  </div>
-</template>
-
-<script>
-  var animation = weex.requireModule('animation')
-  module.exports = {
-    data: function () {
-      return {
-        transformOrigin: 'center center',
-        current_rotate: 0,
-        current_scale: 1,
-        current_color: '#FF0000',
-        current_opacity: 1,
-        current_translate: '',
-        current_transform: '',
-        isStop: true
-      }
-    },
-    components: {
-      panel: require('./include/panel.vue'),
-      button: require('./include/button.vue')
-    },
-    methods: {
-      anim: function(styles, timingFunction, duration, callback) {
-        animation.transition(this.$refs.block, {
-          styles: styles,
-          timingFunction: timingFunction,
-          duration: duration
-        }, callback);
-      },
-      rotate: function() {
-        var self = this;
-        self.current_rotate += 90;
-        self.anim({
-          transform: 'rotate(' + self.current_rotate + 'deg)'
-        }, 'ease-in-out', 500, function() {
-          if (self.current_rotate === 360) {
-            self.current_rotate = 0;
-          }
-          else {
-            self.rotate();
-          }
-        });
-      },
-      translate: function() {
-        this.current_translate = this.current_translate ? '' : 'translate(50%, 50%)';
-        this.anim({
-          transform: this.current_translate
-        }, 'ease-in', 500, function() {
-        });
-      },
-      scale: function() {
-        var self = this;
-        self.current_scale = self.current_scale === 2 ? .5 : 2
-        self.anim({
-          transform: 'scale(' + self.current_scale + ')'
-        }, 'linear', 500, function() {
-        });
-      },
-      transform: function() {
-        var self = this;
-        this.current_transform = this.current_transform ? '' : 'rotate(45deg) scale(1.5)';
-        this.anim({
-          transform: this.current_transform,
-          transformOrigin: 'left top'
-        }, 'ease-out', 500, function() {
-          if (self.current_transform !== '') {
-            self.anim({
-              transform: 'rotate(-90deg) scale(1.2)',
-              transformOrigin: 'left top'
-            }, 'ease-out', 500, function() {
-            })
-          }
-          else {
-
-          }
-        });
-      },
-      composite: function() {
-        var self = this;
-        self.current_transform = self.current_transform ? '' : 'rotate(45deg) scale(1.5) translate(50%, 50%)';
-        self.current_color = self.current_color === '#F0AD4E' ? '#D9534F' : '#F0AD4E';
-        self.current_opacity = self.current_opacity === 1 ? 0.1 : 1;
-        this.anim({
-          transform: this.current_transform,
-          transformOrigin: 'left top',
-          backgroundColor: self.current_color,
-          opacity: self.current_opacity
-        }, 'ease-out', 1000, function() {
-        });
-      },
-      color: function() {
-        var self = this;
-        self.current_color = self.current_color === '#F0AD4E' ? '#D9534F' : '#F0AD4E';
-        self.anim({
-          backgroundColor: self.current_color
-        }, 'linear', 500, function() {
-        });
-      },
-      opacity: function() {
-        var self = this;
-        self.current_opacity = self.current_opacity === 1 ? 0.1 : 1;
-        self.anim({
-          opacity: self.current_opacity
-        }, 'linear', 500, function() {
-        });
-      }
-    }
-  };
-</script>
-
-<style scoped>
-  .block {
-    position: absolute;
-    width: 250px;
-    height: 250px;
-    top: 300px;
-    left: 400px;
-    background-color: #F0AD4E;
-    align-items: center;
-    justify-content: center;
-  }
-
-  .block-txt {
-    color: #FFFFFF;
-    font-size: 70px;
-  }
-</style>
diff --git a/examples/vue/components/a.vue b/examples/vue/components/a.vue
deleted file mode 100644
index ff0149b..0000000
--- a/examples/vue/components/a.vue
+++ /dev/null
@@ -1,24 +0,0 @@
-<template>
-  <scroller>
-    <panel title="Hyperlink" type="primary">
-      <a href="http://alibaba.github.io/weex/index.html">
-        <tip type="info" style="margin-bottom: 20px;"
-          value="Click me to see how 'A' element opens a new world."></tip>
-      </a>
-    </panel>
-  </scroller>
-</template>
-
-<script>
-  module.exports = {
-    data: function () {
-      return {
-        img: '//gw.alicdn.com/tps/i2/TB1DpsmMpXXXXabaXXX20ySQVXX-512-512.png_400x400.jpg'
-      }
-    },
-    components: {
-      panel: require('../include/panel.vue'),
-      tip: require('../include/tip.vue')
-    }
-  }
-</script>
diff --git a/examples/vue/components/countdown.vue b/examples/vue/components/countdown.vue
deleted file mode 100644
index 487d1c4..0000000
--- a/examples/vue/components/countdown.vue
+++ /dev/null
@@ -1,88 +0,0 @@
-<template>
-  <scroller>
-    <panel title="Countdown" type="primary">
-      <countdown
-        @tick="tick($event, 'countdown1')"
-        :remain="countdown1.remain"
-        style="width: 750; margin-top: 20; margin-bottom: 20;">
-        <text class="ctno1">{{countdown1.time.D}}</text>
-        <text class="ctno1" style="background-color: #FFFFFF; color: #AAAAAA;">day(s)</text>
-        <text class="ctno1">{{countdown1.time.hh}}</text>
-        <text class="ctno1" style="background-color: #FFFFFF; color: #AAAAAA;">hour(s)</text>
-        <text class="ctno1">{{countdown1.time.mm}}</text>
-        <text class="ctno1" style="background-color: #FFFFFF; color: #AAAAAA;">minute(s)</text>
-        <text class="ctno1">{{countdown1.time.ss}}</text>
-        <text class="ctno1" style="background-color: #FFFFFF; color: #AAAAAA;">second(s)</text>
-      </countdown>
-
-      <countdown
-        @tick="tick($event, 'countdown2')"
-        :remain="countdown2.remain"
-        style="width: 600;">
-        <text class="ctno2">{{countdown2.time.MM}}</text>
-        <text class="ctno2" style="background-color: #FFFFFF; color: #AAAAAA;">:</text>
-        <text class="ctno2">{{countdown2.time.ss}}</text>
-      </countdown>
-    </panel>
-  </scroller>
-</template>
-
-<style scoped>
-  .ctno1 {
-    border-radius: 8;
-    padding-top: 6;
-    padding-bottom: 6;
-    padding-right: 4;
-    padding-left: 4;
-    margin-left: 2;
-    margin-right: 2;
-    background-color: rgb(242, 222, 222);
-    color: rgb(169, 68, 66);
-  }
-
-  .ctno2 {
-    border-radius: 8;
-    padding-top: 30;
-    padding-bottom: 30;
-    padding-left: 16;
-    padding-right: 16;
-    background-color: rgb(217, 237, 247);
-    color: rgb(49, 112, 143);
-    text-align: center;
-    font-size: 40;
-  }
-</style>
-
-<script>
-  module.exports = {
-    data: function () {
-      return {
-        countdown1: {
-          remain: 5000,
-          time: {
-            D: '0',
-            hh: '00',
-            mm: '00',
-            ss: '00'
-          }
-        },
-        countdown2: {
-          remain: 5000,
-          time: {
-            MM: '0',
-            ss: '0'
-          }
-        }
-      }
-    },
-    components: {
-      panel: require('../include/panel.vue'),
-      countdown: require('../include/countdown.vue')
-    },
-    methods: {
-      tick: function (e, k) {
-        this[k].time = JSON.parse(JSON.stringify(e))
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/components/image.vue b/examples/vue/components/image.vue
deleted file mode 100644
index 74b7430..0000000
--- a/examples/vue/components/image.vue
+++ /dev/null
@@ -1,57 +0,0 @@
-<template>
-  <scroller>
-    <panel title="width x height" type="primary">
-      <tip type="warning" value="Weex screen width is 750" style="margin-bottom: 20px;"></tip>
-      <div style="flex-direction:row">
-        <image class="img" style="width: 300px; height: 300px;" :src="img"></image>
-        <image class="img" style="width: 200px; height: 200px;" :src="img"></image>
-        <image class="img" style="width: 50px; height: 50px;" :src="img"></image>
-      </div>
-    </panel>
-    <panel title="GIF Animation" type="primary">
-      <tip type="warning" value="Depanding on Native ImageSDK" style="margin-bottom: 20px;"></tip>
-      <div style="flex-direction:row">
-        <image class="img" style="width: 96px; height: 96px;" src="https://gtd.alicdn.com/tps/i4/T1HcvHXd4nXXb6ROYh-48-48.gif"></image>
-        <image class="img" style="width: 68px; height: 68px;margin-left:20px;" src="https://gw.alicdn.com/tps/TB1El.mKXXXXXXyapXXXXXXXXXX-34-34.gif"></image>
-      </div>
-    </panel>
-    <panel title="Base64" type="primary">
-      <tip type="warning" value="Depanding on Native ImageSDK" style="margin-bottom: 20px;"></tip>
-      <div style="flex-direction:row">
-        <image class="img" style="width: 96px; height: 96px;" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAhCAMAAABgOjJdAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAO1QTFRFhomSb3J8XGBrdnqDgYWNlJefV1tmfoGKU1diT1NfgISNgoWOYmZwio2Vi4+Wc3eAkJObZGhzUlZiaGt2U1djfYCKZGdyhYiQeHyFio6VgYWOVVllbHB6XWFsY2ZxaWx3jZCYXmFsfYCJcnZ/UVVham54V1tng4aPb3N8WV1pX2JtZWl0YWVvVlpmiYyUWVxohomRd3uEdHiBeX2GZ2t1hIeQVFhkf4OMbnJ8fYGKdnqEb3N9kJScY2dycnaAjpKZdHeBjpKajI+Yc3eBhYiRf4KLXmFtio6Wi4+XjZCZkJSbkZScjI+XlJifTlJe+rAZcwAAAZBJREFUeNp0lOeWgjAQhSdUBQRRbFjX7tpW3XUt23tL3v9xNigJIHh/zRk+5iR3ZgIkULWmwgv+A7VWDWWBR/nSt2gLUzIVbLH1lo8RRW1wEfqxPtCKUaKTMUhURuUhTIi6Q07l6LuAEFdpEld6tWNEx00CKKJ3jsR1xSHJcj4bB+LmkpxT49Yj8mqQUVBBciUk8ITepESJ+5AqY1+uwny5IjDPcADoN0BIwjLOsjKZOewtbi/9fvi338a44CetIai2H/cokPLj9tfEj2wVzD4rIWMlfpu+CXc5Pw4qh5X7AUw4gZIswUENGT8lAN1fMBVeAxIIxYR3Nin0imOe52emdxkyP8aY+0S9Y2d63cNoxvACRTaeI70slst+cjYCAnXmuuS1RKKmy1hKBX0hzaC3KOsxsmz2Ir2NzMcEbVCo+cf5oDOWOzNAucpxxoglnZlT1+KzXk4kymKwL4ttN+73dhHeuWV85zLL073Vw3v7MdDuE3a/JRrCmqwFQ2yV8gmvg/d+aPCMH0GLvB//AgwAo1MTpxsaxVoAAAAASUVORK5CYII="></image>
-        <image class="img" style="width: 68px; height: 68px;margin-left:20px;" src="data:image/gif;base64,R0lGODlhIgAiANU7AMvLy83Nzdra2srKysnJyejo6MbGxtzc3M7Ozuzs7NTU1N3d3fz8/NfX1/j4+Ovr6+/v79DQ0Obm5v39/d/f3/f398/Pz9vb2+np6fn5+f7+/tXV1fX19dnZ2erq6tHR0fb29sjIyMfHx+Li4vLy8u7u7ufn5/r6+uPj49bW1tPT09LS0sTExPT09ODg4O3t7eHh4eTk5MXFxd7e3vHx8fPz8/Dw8OXl5djY2P///8zMzP///wAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/wtYTVAgRGF0YVhNUDw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo0Q0QxODlDNENEOEQxMUUzOEIzM0I1ODVGNjU1MjBBQiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo0Q0QxODlDNUNEOEQxMUUzOEIzM0I1ODVGNjU1MjBBQiI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjRDRDE4OUMyQ0Q4RDExRTM4QjMzQjU4NUY2NTUyMEFCIiBzdFJl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"></image>
-      </div>
-    </panel>
-    <panel title="resize" type="primary">
-      <panel title="resize=stretch(default) 600 x 200 ">
-        <image class="img" style=" width: 600px; height: 200px;border-style: solid;border-width: 1px;border-color: #333;" :src="img" resize="stretch"></image>
-      </panel>
-      <panel title="resize=contain 600 x 200 ">
-        <image class="img" style=" width: 600px; height: 200px;border-style: solid;border-width: 1px;border-color: #333;" :src="img" resize="contain"></image>
-      </panel>
-      <panel title="resize=cover 600 x 200">
-        <image class="img" style=" width: 600px; height: 200px;border-style: solid;border-width: 1px;border-color: #333;" :src="img" resize="cover"></image>
-      </panel>
-    </panel>
-  </scroller>
-</template>
-
-<style scoped>
-  .img {
-    margin-bottom: 20px;
-  }
-</style>
-
-<script>
-  module.exports = {
-    data: function () {
-      return {
-        img: '//gw.alicdn.com/tps/i2/TB1DpsmMpXXXXabaXXX20ySQVXX-512-512.png_400x400.jpg'
-      }
-    },
-    components: {
-      panel: require('../include/panel.vue'),
-      tip: require('../include/tip.vue')
-    }
-  }
-</script>
diff --git a/examples/vue/components/input.vue b/examples/vue/components/input.vue
deleted file mode 100644
index ab950a4..0000000
--- a/examples/vue/components/input.vue
+++ /dev/null
@@ -1,210 +0,0 @@
-<template>
-  <div>
-    <div>
-      <text style="font-size: 40px">oninput: {{txtInput}}</text>
-      <text style="font-size: 40px">onchange: {{txtChange}}</text>
-      <text style="font-size: 40px">onreturntype: {{txtReturnType}}</text>
-      <text style="font-size: 40px">selection: {{txtSelection}}</text>
-
-    </div>
-    <scroller>
-      <div>
-        <div style="background-color: #286090">
-          <text class="title" style="height: 80 ;padding: 20;color: #FFFFFF">input type = text</text>
-        </div>
-        <input type="text" placeholder="Input Text" class="input" :autofocus=true value="" @change="onchange" @input="oninput"/>
-      </div>
-
-      <div>
-        <div style="background-color: #286090">
-          <text class="title" style="height: 80 ;padding: 20;color: #FFFFFF">input type = password</text>
-        </div>
-        <input type="password" placeholder="Input Password" class="input" @change="onchange" @input="oninput"/>
-      </div>
-
-      <div>
-        <div style="background-color: #286090">
-          <text class="title" style="height: 80 ;padding: 20;color: #FFFFFF">input type = url</text>
-        </div>
-        <input type="url" placeholder="Input URL" class="input" @change="onchange" @input="oninput"/>
-      </div>
-
-      <div>
-        <div style="background-color: #286090">
-          <text class="title" style="height: 80 ;padding: 20;color: #FFFFFF">input type = email</text>
-        </div>
-        <input type="email" placeholder="Input Email" class="input" @change="onchange" @input="oninput"/>
-      </div>
-
-      <div>
-        <div style="background-color: #286090">
-          <text class="title" style="height: 80 ;padding: 20;color: #FFFFFF">input type = tel</text>
-        </div>
-        <input type="tel" placeholder="Input Tel" class="input" @change="onchange" @input="oninput"/>
-      </div>
-
-      <div>
-        <div style="background-color: #286090">
-          <text class="title" style="height: 80 ;padding: 20;color: #FFFFFF">input type = time</text>
-        </div>
-        <input type="time" placeholder="Input Time" class="input" @change="onchange" @input="oninput"/>
-      </div>
-
-      <div>
-        <div style="background-color: #286090">
-          <text class="title" style="height: 80 ;padding: 20;color: #FFFFFF">input type = number</text>
-        </div>
-        <input type="number" placeholder="Input number" class="input" @change="onchange" @input="oninput"/>
-      </div>
-
-      <div>
-        <div style="background-color: #286090">
-          <text class="title" style="height: 80 ;padding: 20;color: #FFFFFF">input type = date</text>
-        </div>
-        <input type="date" placeholder="Input Date" class="input" @change="onchange" @input="oninput" max="2017-12-12" min="2015-01-01"/>
-      </div>
-
-      <div>
-        <div style="background-color: #286090">
-          <text class="title" style="height: 80 ;padding: 20;color: #FFFFFF">input return-key-type = default</text>
-        </div>
-        <input type="text" placeholder="please input" return-key-type="default" class="input" @change="onchange" @return = "onreturn" @input="oninput" />
-      </div>
-
-      <div>
-        <div style="background-color: #286090">
-          <text class="title" style="height: 80 ;padding: 20;color: #FFFFFF">input return-key-type = go</text>
-        </div>
-        <input type="text" placeholder="please input" return-key-type="go" class="input" @change="onchange" @return = "onreturn" @input="oninput" />
-      </div>
-
-      <div>
-        <div style="background-color: #286090">
-          <text class="title" style="height: 80 ;padding: 20;color: #FFFFFF">input return-key-type = next</text>
-        </div>
-        <input type="text" placeholder="please input" return-key-type="next" class="input" @change="onchange" @return = "onreturn" @input="oninput" />
-      </div>
-
-      <div>
-        <div style="background-color: #286090">
-          <text class="title" style="height: 80 ;padding: 20;color: #FFFFFF">input return-key-type = search</text>
-        </div>
-        <input type="text" placeholder="please input" return-key-type="search" class="input" @change="onchange" @return = "onreturn" @input="oninput" />
-      </div>
-
-      <div>
-        <div style="background-color: #286090">
-          <text class="title" style="height: 80 ;padding: 20;color: #FFFFFF">input return-key-type = send</text>
-        </div>
-        <input type="text" placeholder="please input" return-key-type="send" class="input" @change="onchange" @return = "onreturn" @input="oninput" />
-      </div>
-
-      <div>
-        <div style="background-color: #286090">
-          <text class="title" style="height: 80 ;padding: 20;color: #FFFFFF">input return-key-type = done</text>
-        </div>
-        <input type="text" placeholder="please input" return-key-type="done" class="input" @change="onchange" @return = "onreturn" @input="oninput" />
-      </div>
-
-
-      <div>
-        <div style="background-color: #286090">
-          <text class="title" style="height: 80 ;padding: 20;color: #FFFFFF">function focus() & blur()</text>
-        </div>
-        <div style="flex-direction: row;margin-bottom: 16px;justify-content: space-between">
-          <text class="button" value="Focus" type="primary" @click="focus"></text>
-          <text class="button" value="Blur" type="primary" @click="blur"></text>
-        </div>
-
-        <input type="text" placeholder="Input1" class="input" value="" ref="input1"/>
-      </div>
-
-
-      <div>
-        <div style="background-color: #286090">
-          <text class="title" style="height: 80 ;padding: 20;color: #FFFFFF">input selection</text>
-        </div>
-        <div style="flex-direction: row;margin-bottom: 16px;justify-content: space-between">
-          <text class="button" value="setRange" type="primary" @click="setRange"></text>
-          <text class="button" value="getSelectionRange" type="primary" @click="getSelectionRange"></text>
-        </div>
-        <input type="text"  ref="inputselection" placeholder="please input" value="123456789"  class="input" @change="onchange" @return = "onreturn" @input="oninput"/>
-      </div>
-
-
-
-    </scroller>
-  </div>
-</template>
-
-<style scoped>
-  .input {
-    font-size: 60px;
-    height: 80px;
-    width: 750px;
-  }
-  .button {
-    font-size: 36;
-    width: 200;
-    color: #41B883;
-    text-align: center;
-    padding-top: 10;
-    padding-bottom: 10;
-    border-width: 2;
-    border-style: solid;
-    margin-right: 20;
-    border-color: rgb(162, 217, 192);
-    background-color: rgba(162, 217, 192, 0.2);
-  }
-</style>
-
-<script>
-  module.exports = {
-    data: function () {
-      return {
-        txtInput: '',
-        txtChange: '',
-        txtReturnType: '',
-        txtSelection:'',
-        autofocus: false
-      };
-    },
-    methods: {
-      ready: function () {
-        var self = this;
-        setTimeout(function () {
-          self.autofocus = true;
-        }, 1000);
-      },
-      onchange: function (event) {
-        this.txtChange = event.value;
-        console.log('onchange', event.value);
-      },
-      onreturn: function (event) {
-        this.txtReturnType = event.returnKeyType;
-        console.log('onreturn', event.type);
-      },
-      oninput: function (event) {
-        this.txtInput = event.value;
-        console.log('oninput', event.value);
-      },
-      focus: function () {
-        this.$refs['input1'].focus();
-      },
-      blur: function () {
-        this.$refs['input1'].blur();
-      },
-      setRange: function() {
-        console.log(this.$refs["inputselection"]);
-        this.$refs["inputselection"].setSelectionRange(2, 6);
-      },
-      getSelectionRange: function() {
-        console.log(this.$refs["inputselection"]);
-        var self = this;
-        this.$refs["inputselection"].getSelectionRange(function(e) {
-          self.txtSelection = e.selectionStart +'-' + e.selectionEnd;
-        });
-      }
-    }
-  };
-</script>
diff --git a/examples/vue/components/list.vue b/examples/vue/components/list.vue
deleted file mode 100644
index c894258..0000000
--- a/examples/vue/components/list.vue
+++ /dev/null
@@ -1,119 +0,0 @@
-<template>
-  <div>
-    <list class="list">
-      <cell
-        v-for="(v,i) in rows"
-        append="tree"
-        :index="i"
-        :key="i"
-        class="row"
-        @appear="onappear(i, $event)"
-        @disappear="ondisappear(i, $event)">
-        <div class="item">
-          <text class="item-title">row {{v.id}}</text>
-        </div>
-      </cell>
-    </list>
-    <text class="count" :value="'Appear items: ' + appearMin + ' ~ ' + appearMax"></text>
-  </div>
-</template>
-
-<style scoped>
-  .list {
-    height:850px
-  }
-  .count {
-    font-size: 48px;
-    margin:10px;
-  }
-  .indicator {
-    height: 40px;
-    width: 40px;
-    color:#45b5f0;
-  }
-  .row {
-    width: 750px;
-  }
-  .item {
-    justify-content: center;
-    border-bottom-width: 2px;
-    border-bottom-color: #c0c0c0;
-    height: 100px;
-    padding:20px;
-  }
-  .item:active {
-     background-color: #00BDFF;
-   }
-  .item-title {
-  }
-</style>
-
-<script>
-  module.exports = {
-    methods: {
-      onappear: function (idx, e) {
-        var appearId = this.rows[idx].id;
-        console.log('+++++', appearId);
-        var appearIds = this.appearIds;
-        appearIds.push(appearId);
-        this.getMinAndMaxIds(appearIds);
-      },
-      ondisappear:function (idx, e) {
-        var disAppearId = this.rows[idx].id;
-        console.log('+++++', disAppearId);
-        var appearIds = this.appearIds;
-        var index = appearIds.indexOf(disAppearId);
-        if (index > -1) {
-          appearIds.splice(index, 1);
-        }
-        this.getMinAndMaxIds(appearIds);
-      },
-      getMinAndMaxIds:function (appearIds) {
-        appearIds.sort(function(a, b) {
-          return a - b;
-        });
-        this.appearIds = appearIds;
-        this.appearMax = appearIds[appearIds.length - 1];
-        this.appearMin = appearIds[0];
-      }
-    },
-    data: function () {
-      return {
-        appearMin:1,
-        appearMax:1,
-        appearIds:[],
-        rows:[
-          {id: 1},
-          {id: 2},
-          {id: 3},
-          {id: 4},
-          {id: 5},
-          {id: 6},
-          {id: 7},
-          {id: 8},
-          {id: 9},
-          {id: 10},
-          {id: 11},
-          {id: 12},
-          {id: 13},
-          {id: 14},
-          {id: 15},
-          {id: 16},
-          {id: 17},
-          {id: 18},
-          {id: 19},
-          {id: 20},
-          {id: 21},
-          {id: 22},
-          {id: 23},
-          {id: 24},
-          {id: 25},
-          {id: 26},
-          {id: 27},
-          {id: 28},
-          {id: 29}
-        ]
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/components/marquee.vue b/examples/vue/components/marquee.vue
deleted file mode 100644
index e197153..0000000
--- a/examples/vue/components/marquee.vue
+++ /dev/null
@@ -1,68 +0,0 @@
-<template>
-  <scroller>
-    <panel title="Marquee" type="primary">
-      <marquee
-        :step="marquee.height * 2"
-        :count="marquee.list.length"
-        :interval="marquee.interval"
-        :duration="marquee.duration"
-        :style="{
-          width: 700,
-          height: marquee.height * 2,
-          backgroundColor: 'rgb(223, 240, 216)',
-          borderRadius: 8,
-          paddingLeft: 10,
-          paddingRight: 10
-        }"
-        @change="marqueeChange">
-        <div
-          v-for="(item,i) in marquee.list"
-          :key="i"
-          :style="{
-            height: marquee.height * marquee.length,
-            paddingTop: marquee.height * 0.5,
-            paddingBottom: marquee.height * 0.5,
-            overflow: 'hidden'
-          }">
-          <text
-            :style="{
-              height: marquee.height,
-              color: 'rgb(60, 118, 61)',
-              fontSize: 28
-            }">{{item.text}}</text>
-        </div>
-      </marquee>
-    </panel>
-  </scroller>
-</template>
-
-<script>
-  module.exports = {
-    data: function () {
-      return {
-        marquee: {
-          height: 30,
-          duration: 1500,
-          interval: 2000,
-          list: [
-            {text: 'Introducing Bots on Messenger'},
-            {text: 'Capturing 3D 360-Stereo VR Video'},
-            {text: 'The Future of Video on Facebook'},
-            {text: 'Announcing Vue.js 2.0'},
-            {text: 'Not Your Average Virtual-DOM'},
-            {text: 'Templates, JSX, or Hyperscript?'}
-          ]
-        }
-      }
-    },
-    components: {
-      panel: require('../include/panel.vue'),
-      marquee: require('../include/marquee.vue')
-    },
-    methods: {
-      marqueeChange: function (e) {
-        console.log(e)
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/components/navigator.vue b/examples/vue/components/navigator.vue
deleted file mode 100644
index ab1423f..0000000
--- a/examples/vue/components/navigator.vue
+++ /dev/null
@@ -1,74 +0,0 @@
-<template>
-  <navpage
-    dataRole="none"
-    :height="navBarHeight"
-    :title="title"
-    backgroundColor="#ff5898"
-    titleColor="white"
-    leftItemTitle="More"
-    leftItemColor="white"
-    rightItemSrc="http://gtms02.alicdn.com/tps/i2/TB1ED7iMpXXXXXEXXXXWA_BHXXX-48-48.png"
-    @naviBarLeftItemClick="naviBarLeftItemClick"
-    @naviBarRightItemClick="naviBarRightItemClick">
-    <panel title="push a new page">
-      <button type="primary" size="small" value="push" @click.native="push"></button>
-    </panel>
-    <panel title="pop to the last page">
-      <button type="success" size="small" value="pop" @click.native="pop"></button>
-    </panel>
-  </navpage>
-</template>
-
-<script>
-  var navigator = weex.requireModule('navigator')
-  var getBaseURL = require('../include/base-url.js').getBaseURL
-  module.exports = {
-    data: function () {
-      return {
-        navBarHeight: 88,
-        title: 'Navigator',
-        dir: 'examples',
-        baseURL: '',
-        subPath: weex.config.env.platform === 'Web' ? 'vue-web/' : ''
-      }
-    },
-    components: {
-      panel: require('../include/panel.vue'),
-      navpage: require('../include/navpage.vue'),
-      button: require('../include/button.vue')
-    },
-    created: function() {
-      this.$getConfig(function (config) {
-        var env = config.env;
-        if(env.platform == 'iOS'){
-          var scale = env.scale;
-          var deviceWidth = env.deviceWidth / scale;
-          this.navBarHeight = 64.0 * 750.0 / deviceWidth;
-        }
-      }.bind(this));
-      this.baseURL = getBaseURL(this)
-    },
-    methods: {
-      naviBarLeftItemClick: function (e) {
-        modal.toast({ message: 'naviBarLeftItemClick', duration: 2 })
-      },
-      naviBarRightItemClick: function (e) {
-        modal.toast({ message: 'naviBarRightItemClick', duration: 2 })
-      },
-      push: function () {
-        var params = {
-          'url':  this.baseURL + this.subPath + 'vue/components/navigator.js?test=1',
-          'animated' : 'true',
-        }
-        navigator.push(params, function () {});
-      },
-      pop: function () {
-        var params = {
-          'url':  this.baseURL + this.subPath + 'vue/components/navigator.js?test=1',
-          'animated' : 'true',
-        }
-        navigator.pop(params, function () {});
-      },
-    }
-  }
-</script>
diff --git a/examples/vue/components/scroller.vue b/examples/vue/components/scroller.vue
deleted file mode 100644
index 8336ea0..0000000
--- a/examples/vue/components/scroller.vue
+++ /dev/null
@@ -1,190 +0,0 @@
-<template>
-  <scroller class="list" append="tree" ref="scroller">
-    <refresh class="refresh-view" :display="refresh_display" @refresh="onrefresh" @pullingdown="pullingdown">
-      <img id="roate" ref="roate" src="http://gw.alicdn.com/bao/uploaded/TB1xDrVNFXXXXbEXFXXXXXXXXXX-48-48.png" style="width: 50px;height: 50px;"></img>
-    </refresh>
-    <div v-for="(sec, i) in sections" :key="i" class="section">
-      <div class="header">
-        <text class="header-title">{{sec.title}}</text>
-      </div>
-      <div v-for="item in sec.items" class="item" :key="item.index">
-        <text class="item-title">row {{item.id}}</text>
-      </div>
-    </div>
-    <loading class="loading-view" :display="loading_display" @loading="onloading">
-      <loading-indicator style="height: 60px; width: 60px;"></loading-indicator>
-    </loading>
-  </scroller>
-</template>
-
-<style scoped>
-  .refresh-view {
-    height: 120px;
-    width: 750px;
-    display: -ms-flex;
-    display: -webkit-flex;
-    display: flex;
-    -ms-flex-align: center;
-    -webkit-align-items: center;
-    -webkit-box-align: center;
-    align-items: center;
-  }
-
-  .refresh-arrow {
-    font-size: 30px;
-    color: #45b5f0;
-  }
-
-  .loading-view {
-    height: 80px;
-    width: 750px;
-    justify-content: center;
-    align-items: center;
-    background-color: #c0c0c0;
-  }
-
-  .indicator {
-    height: 40px;
-    width: 40px;
-    color: #45b5f0;
-  }
-
-  .header {
-    background-color: #45b5f0;
-    padding: 20px;
-    height: 88px;
-    justify-content: center;
-  }
-
-  .header-title {
-    color: white;
-    font-weight: bold;
-  }
-
-  .item {
-    justify-content: center;
-    border-bottom-width: 2px;
-    border-bottom-color: #c0c0c0;
-    height: 100px;
-    padding: 20px;
-  }
-
-  .item-title {
-  }
-</style>
-
-<script>
-  const dom = weex.requireModule('dom')
-  console.log(dom)
-  module.exports = {
-    mounted () {
-      const result = dom.getComponentRect(this.$refs.scroller, option => {
-        console.log('getComponentRect:', option)
-      })
-    },
-    methods: {
-      onrefresh: function(e) {
-        var self = this;
-        self.refresh_display = 'show';
-        setTimeout(function () {
-          self.refresh_display = 'hide';
-        }, 3000)
-      },
-      onloading: function(e) {
-        var self = this;
-        self.loading_display = 'show';
-        setTimeout(function () {
-          self.loading_display = 'hide';
-        }, 3000)
-      },
-      pullingdown: function(e){
-        var dy = e.dy;
-        var pullingDistance = e.pullingDistance;
-        var viewHeight = e.viewHeight;
-      }
-    },
-    data: function () {
-      return {
-        refresh_display: 'hide',
-        loading_display: 'hide',
-        sections: [
-          {
-            title: 'Header 1',
-            items: [
-              {id: 1},
-              {id: 2},
-              {id: 3},
-              {id: 4},
-              {id: 5}
-            ]
-          },
-          {
-            title: 'Header 2',
-            items: [
-              {id: 6},
-              {id: 7},
-              {id: 8},
-              {id: 9},
-              {id: 10},
-              {id: 11}
-            ]
-          },
-          {
-            title: 'Header 3',
-            items: [
-              {id: 6},
-              {id: 7},
-              {id: 8},
-              {id: 9},
-              {id: 10},
-              {id: 11}
-            ]
-          }
-        ],
-        moreSections: [
-          {
-            title: 'Header 3',
-            items: [
-              {id: 12},
-              {id: 13},
-              {id: 14},
-              {id: 15},
-              {id: 16},
-              {id: 17},
-              {id: 18}
-            ]
-          },
-          {
-            title: 'Header 4',
-            items: [
-              {id: 19},
-              {id: 20},
-              {id: 21},
-              {id: 22}
-            ]
-          },
-          {
-            title: 'Header 5',
-            items: [
-            {id: 23},
-            {id: 24},
-            {id: 25},
-            {id: 26},
-            {id: 27}
-            ]
-          },
-          {
-            title: 'Header 6',
-            items: [
-            {id: 28},
-            {id: 29},
-            {id: 30},
-            {id: 31},
-            {id: 32}
-            ]
-          }
-          ]
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/components/slider.vue b/examples/vue/components/slider.vue
deleted file mode 100644
index 5985b68..0000000
--- a/examples/vue/components/slider.vue
+++ /dev/null
@@ -1,264 +0,0 @@
-<template>
-  <scroller class="body">
-    <panel title="auto-play" type="primary">
-      <panel title="auto-play = false" padding-body="0">
-        <slider class="slider" append="tree"
-          :interval="sliders[1].interval"
-          autoPlay="false">
-          <indicator class="indicator"></indicator>
-          <slider-page v-for="(v,i) in sliders[1].sliderPages" :items="v.items" :key="i"></slider-page>
-        </slider>
-      </panel>
-      <panel title="auto-play = true" padding-body="0">
-        <slider class="slider" append="tree"
-          :interval="sliders[0].interval"
-          :autoPlay="sliders[0].autoPlay">
-          <indicator class="indicator"></indicator>
-          <slider-page v-for="v in sliders[0].sliderPages" :key="v.index" :items="v.items"></slider-page>
-        </slider>
-      </panel>
-    </panel>
-    <panel :title="'Event, ' + eventCnt + ' change'" type="primary">
-      <slider class="slider" append="tree"
-        :interval="sliders[0].interval"
-        :autoPlay="sliders[0].autoPlay"
-        @change="handleSliderChange">
-        <indicator class="indicator"></indicator>
-        <slider-page v-for="v in sliders[0].sliderPages" :key="v.index" :items="v.items"></slider-page>
-      </slider>
-    </panel>
-    <panel title="Indicator" type="primary">
-      <panel title="default style" padding-body="0">
-        <slider class="slider" append="tree"
-          :interval="sliders[0].interval"
-          :autoPlay="sliders[0].autoPlay"
-          @change="handleSliderChange">
-          <indicator class="indicator"></indicator>
-          <slider-page v-for="v in sliders[0].sliderPages" :key="v.index" :items="v.items"></slider-page>
-        </slider>
-      </panel>
-      <panel title="width & height" padding-body="0">
-        <slider class="slider" append="tree"
-          :interval="sliders[0].interval"
-          :autoPlay="sliders[0].autoPlay">
-          <indicator style="itemColor: #dddddd;width:714px;height:460px;"></indicator>
-          <slider-page v-for="v in sliders[0].sliderPages" :key="v.index" :items="v.items"></slider-page>
-        </slider>
-      </panel>
-      <panel title="left & top" padding-body="0">
-        <slider class="slider" append="tree"
-          :interval="sliders[1].interval"
-          :autoPlay="sliders[1].autoPlay">
-          <indicator class="indicator" style="top:-140px;left:-240px"></indicator>
-          <slider-page v-for="(v,i) in sliders[1].sliderPages" :items="v.items" :key="i"></slider-page>
-        </slider>
-      </panel>
-      <panel title="itemColor & itemSelectedColor" padding-body="0">
-        <slider class="slider" append="tree"
-          :interval="sliders[2].interval"
-          :autoPlay="sliders[2].autoPlay">
-          <indicator class="indicator" style="item-selected-color:rgb(217, 83, 79);"></indicator>
-          <slider-page v-for="v in sliders[2].sliderPages" :key="v.index" :items="v.items"></slider-page>
-        </slider>
-      </panel>
-      <panel title="itemSize" padding-body="0">
-        <slider class="slider" append="tree"
-          :interval="sliders[1].interval"
-          :autoPlay="sliders[1].autoPlay">
-          <indicator style="itemColor: #dddddd;item-size:40px;top:140px;left:180px;width:700px;height:380px;"></indicator>
-          <slider-page v-for="(v,i) in sliders[1].sliderPages" :items="v.items" :key="i"></slider-page>
-        </slider>
-      </panel>
-    </panel>
-  </scroller>
-</template>
-
-<script>
-  var img0 = '//gw.alicdn.com/tps/i2/TB1DpsmMpXXXXabaXXX20ySQVXX-512-512.png_400x400.jpg';
-  var img1 = '//gw.alicdn.com/tps/i1/TB1M3sQMpXXXXakXXXXApNeJVXX-360-360.png';
-  module.exports = {
-    data: function () {
-      return {
-        eventCnt: 0,
-        togglePlayMsg: 'pause',
-        sliders: [
-          {
-            interval: 1000,
-            autoPlay: true,
-            sliderPages: [
-              {
-                items: [
-                  {
-                    image: img0,
-                    link: '//h5.m.taobao.com/1'
-                  },
-                  {
-                    image: img0,
-                    link: '//h5.m.taobao.com/1'
-                  }
-                ]
-              },
-              {
-                items: [
-                  {
-                    image: img1,
-                    link: '//h5.m.taobao.com/1'
-                  },
-                  {
-                    image: img1,
-                    link: '//h5.m.taobao.com/1'
-                  }
-                ]
-              },
-              {
-                items: [
-                  {
-                    image: img0,
-                    link: '//h5.m.taobao.com/1'
-                  },
-                  {
-                    image: img1,
-                    link: '//h5.m.taobao.com/1'
-                  }
-                ]
-              }
-            ]
-          },
-          {
-            interval: 3000,
-            autoPlay: true,
-            sliderPages: [
-              {
-                items: [
-                {
-                  image: img0,
-                  link: '//h5.m.taobao.com/1'
-                },
-                {
-                  image: img0,
-                  link: '//h5.m.taobao.com/1'
-                }
-                ]
-              },
-              {
-                items: [
-                {
-                  image: img1,
-                  link: '//h5.m.taobao.com/1'
-                },
-                {
-                  image: img1,
-                  link: '//h5.m.taobao.com/1'
-                }
-                ]
-              },
-              {
-                items: [
-                {
-                  image: img0,
-                  link: '//h5.m.taobao.com/1'
-                },
-                {
-                  image: img1,
-                  link: '//h5.m.taobao.com/1'
-                }
-                ]
-              }
-              ]
-            },
-            {
-              interval: 5000,
-              autoPlay: true,
-              sliderPages: [
-              {
-                items: [
-                {
-                  image: img0,
-                  link: '//h5.m.taobao.com/1'
-                },
-                {
-                  image: img0,
-                  link: '//h5.m.taobao.com/1'
-                }
-                ]
-              },
-              {
-                items: [
-                {
-                  image: img1,
-                  link: '//h5.m.taobao.com/1'
-                },
-                {
-                  image: img1,
-                  link: '//h5.m.taobao.com/1'
-                }
-                ]
-              },
-              {
-                items: [
-                {
-                  image: img0,
-                  link: '//h5.m.taobao.com/1'
-                },
-                {
-                  image: img1,
-                  link: '//h5.m.taobao.com/1'
-                }
-                ]
-              }
-              ]
-            }
-            ]
-      }
-    },
-    components: {
-      panel: require('../include/panel.vue'),
-      sliderPage: require('../include/slider-page.vue')
-    },
-    methods: {
-      togglePlay: function() {
-        var autoPlay = this.sliders[0].autoPlay
-        autoPlay = !autoPlay
-        this.sliders[0].autoPlay = autoPlay
-        this.togglePlayMsg = autoPlay ? 'pause' : 'play'
-      },
-      handleSliderChange: function() {
-        var nowCnt = this.eventCnt + 1
-        this.eventCnt = nowCnt
-      },
-      setInterval1: function() {
-        this.sliders[0].interval = 1000;
-      },
-      setInterval3: function() {
-        this.sliders[0].interval = 3000;
-      },
-      setInterval5: function() {
-        this.sliders[0].interval = 5000;
-      }
-    }
-  };
-</script>
-
-<style scoped>
-  .body {
-    background-color: #ffffff;
-  }
-
-  .slider {
-    flex-direction: row;
-    /*margin-left: 18;*/
-    /*margin-right: 18;*/
-    width: 690px;
-    height: 360px;
-  }
-
-  .indicator {
-    position: absolute;
-    width: 690px;
-    height: 420px;
-    top: 140px;
-    left: 240px;
-    itemColor: #dddddd;
-    itemSelectedColor: rgb(40, 96, 144);
-  }
-</style>
diff --git a/examples/vue/components/sliderinfinite.vue b/examples/vue/components/sliderinfinite.vue
deleted file mode 100644
index 4a3702e..0000000
--- a/examples/vue/components/sliderinfinite.vue
+++ /dev/null
@@ -1,46 +0,0 @@
-<template>
-  <div>
-    <slider class="slider" interval="3000" auto-play="true">
-      <div class="frame" v-for="img in imageList">
-        <image class="image" resize="cover" :src="img.src"></image>
-      </div>
-    </slider>
-  </div>
-</template>
-
-<style scoped>
-  .image {
-    width: 700px;
-    height: 300px;
-  }
-  .slider {
-    margin-top: 25px;
-    margin-left: 25px;
-    width: 700px;
-    height: 300px;
-    border-width: 2px;
-    border-style: solid;
-    border-color: #41B883;
-  }
-  .frame {
-    width: 700px;
-    height: 300px;
-    position: relative;
-  }
-</style>
-
-<script>
-  export default {
-    data () {
-      return {
-        imageList: [
-          { src: 'https://gw.alicdn.com/tfs/TB1SA2wQXXXXXXDapXXXXXXXXXX-1400-600.png'},
-          { src: 'https://gw.alicdn.com/tfs/TB1KS_OQXXXXXcSXVXXXXXXXXXX-1400-600.png'},
-          { src: 'https://gw.alicdn.com/tfs/TB1Ez7XQXXXXXbNXXXXXXXXXXXX-1400-600.png'},
-          { src: 'https://gw.alicdn.com/tfs/TB1XLn6QXXXXXb2XpXXXXXXXXXX-1400-600.png'}
-        ]
-
-      }
-    }
-  }
-</script>
\ No newline at end of file
diff --git a/examples/vue/components/tabbar.vue b/examples/vue/components/tabbar.vue
deleted file mode 100644
index 7cc54ae..0000000
--- a/examples/vue/components/tabbar.vue
+++ /dev/null
@@ -1,63 +0,0 @@
-<template>
-  <div style="flex-direction: column;">
-    <tabbar :tabItems="tabItems" @tabBarOnClick="tabBarOnClick"></tabbar>
-  </div>
-</template>
-
-<script>
-  var getBaseURL = require('../include/base-url.js').getBaseURL
-  module.exports = {
-    data: function () {
-      return {
-        dir: 'examples',
-        tabItems: [
-          {
-            index: 0,
-            title: 'tab1',
-            titleColor: '#000000',
-            icon: '',
-            image: 'http://gtms01.alicdn.com/tps/i1/TB1qw.hMpXXXXagXXXX9t7RGVXX-46-46.png',
-            selectedImage: 'http://gtms04.alicdn.com/tps/i4/TB16jjPMpXXXXazXVXX9t7RGVXX-46-46.png',
-            src: 'component/tabbar/tabbar-item.js?itemId=tab1',
-            visibility: 'visible',
-          },
-          {
-            index: 1,
-            title: 'tab2',
-            titleColor: '#000000',
-            icon: '',
-            image: 'http://gtms03.alicdn.com/tps/i3/TB1LEn9MpXXXXaUXpXX9t7RGVXX-46-46.png',
-            selectedImage: 'http://gtms02.alicdn.com/tps/i2/TB1qysbMpXXXXcnXXXX9t7RGVXX-46-46.png',
-            src: 'component/tabbar/tabbar-item.js?itemId=tab2',
-            visibility: 'hidden',
-          },
-          {
-            index: 2,
-            title: 'tab3',
-            titleColor: '#000000',
-            icon: '',
-            image: 'http://gtms01.alicdn.com/tps/i1/TB1B0v5MpXXXXcvXpXX9t7RGVXX-46-46.png',
-            selectedImage: 'http://gtms04.alicdn.com/tps/i4/TB1NxY5MpXXXXcrXpXX9t7RGVXX-46-46.png',
-            src: 'component/tabbar/tabbar-item.js?itemId=tab3',
-            visibility: 'hidden',
-          }
-        ],
-      }
-    },
-    components: {
-      tabbar: require('../include/tabbar.vue')
-    },
-    created: function() {
-      var baseURL = getBaseURL(this)
-      for(var i = 0; i < this.tabItems.length; i++) {
-        var tabItem = this.tabItems[i];
-        tabItem.src = baseURL + tabItem.src;
-      }
-    },
-    methods: {
-      tabBarOnClick: function (e) {
-        console.log('tabBarOnClick', e.index)
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/components/text.vue b/examples/vue/components/text.vue
deleted file mode 100644
index 19f34aa..0000000
--- a/examples/vue/components/text.vue
+++ /dev/null
@@ -1,60 +0,0 @@
-<template>
-  <scroller>
-    <panel title="color" type="primary">
-      <text class="txt">default is black</text>
-      <text class="txt" style="color:#286090">#286090</text>
-      <text class="txt" style="color:#0f0">#0f0</text>
-      <text class="txt" style="color:red">keyword</text>
-      <text class="txt" style="color:rgb(238, 162, 54)">rgb(238, 162, 54)</text>
-      <text class="txt" style="color:rgba(238, 162, 54, 0.5)">rgba(238, 162, 54, 0.5)</text>
-    </panel>
-    <panel title="font-size" type="primary">
-      <text class="txt" style="font-size: 32px;">32</text>
-      <text class="txt" style="font-size: 64px;">64</text>
-      <text class="txt" style="font-size: 100px;">100</text>
-    </panel>
-    <panel title="font-style" type="primary">
-      <text class="txt" style="font-style: normal">normal</text>
-      <text class="txt" style="font-style: italic">italic</text>
-    </panel>
-    <panel title="font-weight" type="primary">
-      <text class="txt" style="font-weight: normal">normal</text>
-      <text class="txt" style="font-weight: bold">bold</text>
-    </panel>
-    <panel title="text-decoration" type="primary">
-      <text class="txt" style="text-decoration: none">none</text>
-      <text class="txt" style="text-decoration: underline">underline</text>
-      <text class="txt" style="text-decoration: line-through">line-through</text>
-    </panel>
-    <panel title="text-align" type="primary">
-      <text class="txt" style="text-align: left">left</text>
-      <text class="txt" style="text-align: center">center</text>
-      <text class="txt" style="text-align: right">right</text>
-    </panel>
-    <panel title="text-overflow" type="primary">
-      <text class="txt" style="lines:1">no text-overflow, no text-overflow</text>
-      <text class="txt" style="text-overflow:clip;width:450px;lines:1">text-overflow: clip, text-overflow: clip</text>
-      <text class="txt" style="text-overflow:ellipsis;width:450px;lines:1">text-overflow: ellipsis, text-overflow: ellipsis</text>
-    </panel>
-    <panel title="line-height" type="primary">
-      <text class="txt">no lineheight setting</text>
-      <text class="txt" style="line-height: 50px">lineheight 50</text>
-      <text class="txt" style="line-height: 80px"> lineheight 80</text>
-    </panel>
-  </scroller>
-</template>
-
-<style scoped>
-  .txt {
-    margin-bottom: 12px;
-    font-size: 40px;
-  }
-</style>
-
-<script>
-  module.exports = {
-    components: {
-      panel: require('../include/panel.vue')
-    }
-  }
-</script>
diff --git a/examples/vue/components/textarea.vue b/examples/vue/components/textarea.vue
deleted file mode 100644
index 580e390..0000000
--- a/examples/vue/components/textarea.vue
+++ /dev/null
@@ -1,57 +0,0 @@
-<template>
-  <scroller>
-    <panel title="textarea" type="primary">
-      <textarea
-        class="textarea"
-        autofocus="true"
-        return-key-type="done"
-        @return="onreturn"
-        @change="onchange"
-        @input="oninput"
-      />
-      <text>oninput: {{txtInput}}</text>
-      <text>onchange: {{txtChange}}</text>
-      <text>enter key type: {{returnType}}</text>
-      <text>action: {{msg}}</text>
-    </panel>
-  </scroller>
-</template>
-
-<style scoped>
-  .textarea {
-    font-size: 30px;
-    height: 280px;
-    width: 400px;
-    border-width: 2px;
-    border-color: #ccc;
-  }
-</style>
-
-<script>
-  var modal = weex.requireModule('modal')
-  module.exports = {
-    data: function () {
-      return {
-        txtInput: '',
-        txtChange: '',
-        returnType: '',
-        msg: ''
-      }
-    },
-    components: {
-      panel: require('../include/panel.vue')
-    },
-    methods: {
-      onchange: function(event) {
-        this.txtChange = event.value;
-      },
-      oninput: function(event) {
-        this.txtInput = event.value;
-      },
-      onreturn: function(event) {
-        this.returnType = event.returnKeyType;
-        this.msg = 'You are "' + this.returnType + '" ' + event.value;
-      }
-    }
-  };
-</script>
diff --git a/examples/vue/components/video.vue b/examples/vue/components/video.vue
deleted file mode 100644
index 677cad9..0000000
--- a/examples/vue/components/video.vue
+++ /dev/null
@@ -1,60 +0,0 @@
-<template>
-  <scroller>
-    <video class="video" onpause="onpause" onstart="onstart" onfinish="onfinish" onfail="onfail"
-           src="http://g.tbcdn.cn/ali-wireless-h5/res/0.0.6/toy.mp4"
-           auto-play="true" :playStatus="playStatus">
-    </video>
-    <div style="flex-direction: row; justify-content: center;">
-      <button value="Pause" @click.native="pause"></button>
-      <button value="Play" @click.native="play" type="primary" style="margin-left:20px;"></button>
-    </div>
-  </scroller>
-</template>
-
-<style scoped>
-  .video {
-    width: 750px;
-    height: 460px;
-    margin-bottom: 80px;
-  }
-</style>
-
-<script>
-  var modal = weex.requireModule('modal')
-  module.exports = {
-    data: function () {
-      return {
-        playStatus: 'play'
-      }
-    },
-    components: {
-      button: require('../include/button.vue')
-    },
-    methods: {
-      pause: function() {
-        this.playStatus = 'pause'
-        modal.toast({ 'message': 'click pause' })
-      },
-      play: function() {
-        this.playStatus = 'play'
-        modal.toast({ 'message': 'click play' })
-      },
-      onpause: function(e) {
-        this.playStatus = e.playStatus
-        modal.toast({ 'message': 'video pause' })
-      },
-      onstart: function(e) {
-        this.playStatus = e.playStatus
-        modal.toast({ 'message': 'video start' })
-      },
-      onfinish: function(e) {
-        this.playStatus = e.playStatus
-        modal.toast({ 'message': 'video finish' })
-      },
-      onfail: function(e) {
-        this.playStatus = e.playStatus
-        modal.toast({ 'message': 'video fail' })
-      }
-    }
-  };
-</script>
diff --git a/examples/vue/components/waterfall.vue b/examples/vue/components/waterfall.vue
deleted file mode 100644
index 8ed7f66..0000000
--- a/examples/vue/components/waterfall.vue
+++ /dev/null
@@ -1,459 +0,0 @@
-<template>
-  <waterfall class="page"
-  v-bind:style="{padding:padding}"
-  :columnWidth="columnWidth" :columnCount="columnCount" :columnGap="columnGap"
-  :show-scrollbar="showScrollbar" :scrollable="scrollable"
-  @scroll="recylerScroll"
-  >
-    <refresh class="refresh" @refresh="onrefresh" @pullingdown="onpullingdown" :display="refreshing ? 'show' : 'hide'">
-      <loading-indicator class="indicator"></loading-indicator>
-      <text class="refreshText">{{refreshText}}</text>
-    </refresh>
-    <header class="header" ref="header" v-if="showHeader">
-      <div class="banner" src="https://gw.alicdn.com/tps/TB1ESN1PFXXXXX1apXXXXXXXXXX-1000-600.jpg" resize="cover">
-        <div class="bannerInfo">
-          <image class="avatar" src="https://gw.alicdn.com/tps/TB1EP9bPFXXXXbpXVXXXXXXXXXX-150-110.jpg" resize="cover"></image>
-          <text class="name">Adam Cat</text>
-          <div class="titleWrap">
-            <text class="title">Genius</text>
-          </div>
-        </div>
-        <div class="bannerPhotoWrap">
-          <image class="bannerPhoto" v-for="photo in banner.photos" :src="photo.src"></image>
-        </div>
-      </div>
-    </header>
-    <header class="stickyHeader">
-      <div v-if="stickyHeaderType === 'none'" class="stickyWrapper">
-        <text class="stickyText">Sticky Header</text>
-      </div>
-      <div v-if="stickyHeaderType === 'appear'" class="stickyWrapper">
-        <div class="stickyTextImageWrapper">
-          <text class="stickyText">Last Appear:</text>
-          <image class="stickyImage" :src="appearImage"></image>
-        </div>
-        <div class="stickyTextImageWrapper">
-          <text class="stickyText">Last Disappear:</text>
-          <image class="stickyImage" :src="disappearImage"></image>
-        </div>
-      </div>
-      <div v-if="stickyHeaderType === 'scroll'" class="stickyWrapper">
-        <text class="stickyText">Content Offset:{{contentOffset}}</text>
-      </div>
-    </header>
-    <cell v-for="(item, index) in items" :key="index" :ref="`cell${index}`" class="cell">
-      <div class="item" @click="onItemclick(item.behaviour, index)" @appear="itemAppear(item.src)" @disappear="itemDisappear(item.src)">
-        <text v-if="item.name" class="itemName">{{item.name}}</text>
-        <image class="itemPhoto" :src="item.src"></image>
-        <text v-if="item.desc" class="itemDesc">{{item.desc}}</text>
-        <text v-if="item.behaviourName" class="itemClickBehaviour"> {{item.behaviourName}}</text>
-      </div>
-    </cell>
-    <div class="fixedItem" @click="scrollToTop">
-      <text class="fixedText">Top</text>
-    </div>
-  </waterfall>
-</template>
-
-<style scoped>
-  .page {
-    background-color: #EFEFEF;
-  }
-  .refresh {
-    height: 128px;
-    width: 750px;
-    flex-direction: row;
-    align-items: center;
-    justify-content: center;
-  }
-  .refreshText {
-    color: #888888;
-    font-weight: bold;
-  }
-  .indicator {
-    color: #888888;
-    height: 40px;
-    width: 40px;
-    margin-right: 30px;
-  }
-  .header {
-    background-color: #fff;
-  }
-  .banner {
-    height: 377px;
-    flex-direction: row;
-  }
-  .bannerInfo {
-    width: 270px;
-    align-items: center;
-    justify-content: center;
-  }
-  .avatar {
-    width: 148px;
-    height: 108px;
-    border-radius: 54px;
-    border-width: 4px;
-    border-color: #FFFFFF;
-    margin-bottom: 14px;
-  }
-  .name {
-    font-weight: bold;
-    font-size:32px;
-    color:#ffffff;
-    line-height:32px;
-    text-align:center;
-    margin-bottom: 16px;
-  }
-  .titleWrap {
-    width: 100px;
-    height: 24px;
-    margin-bottom: 10px;
-    background-color: rgba(255,255,255,0.80);
-    border-radius: 12px;
-    justify-content: center;
-    align-items: center;
-  }
-  .title {
-    font-size: 20px;
-    color: #000000;
-  }
-  .bannerPhotoWrap {
-    width: 449px;
-    height: 305px;
-    background-color: #FFFFFF;
-    border-radius: 12px;
-    margin-top: 35px;
-    padding: 12px;
-    flex-direction: row;
-    justify-content: space-between;
-    flex-wrap:wrap;
-  }
-  .bannerPhoto {
-    width: 137px;
-    height: 137px;
-    margin-bottom: 6px;
-  }
-  .stickyHeader {
-    position: sticky;
-    height: 94px;
-    flex-direction: row;
-    padding-bottom:6px;
-  }
-  .stickyWrapper {
-    flex-direction: row;
-    background-color:#00cc99;
-    justify-content: center;
-    align-items: center;
-    flex: 1;
-  }
-  .stickyTextImageWrapper {
-    flex: 1;
-    justify-content: center;
-    align-items: center;
-    flex-direction: row;
-  }
-  .stickyText {
-    color: #FFFFFF;
-    font-weight: bold;
-    font-size: 32px;
-    margin-right: 12px;
-  }
-  .stickyImage {
-    width: 64px;
-    height: 64px;
-    border-radius: 32px;
-  }
-
-  .cell {
-    padding-top: 6px;
-    padding-bottom: 6px;
-  }
-  .item {
-    background-color: #FFFFFF;
-    align-items: center;
-  }
-  .itemName {
-    font-size: 28px;
-    color:#333333;
-    line-height: 42px;
-    text-align:left;
-    margin-top: 24px;
-  }
-  .itemPhoto {
-    margin-top: 18px;
-    width: 220px;
-    height: 220px;
-    margin-bottom: 18px;
-  }
-  .itemDesc {
-    font-size: 24px;
-    margin: 12px;
-    color: #999999;
-    line-height: 36px;
-    text-align: left;
-  }
-  .itemClickBehaviour {
-    font-size: 36px;
-    color: #00cc99;
-    line-height: 36px;
-    text-align:center;
-    margin-top: 6px;
-    margin-left: 24px;
-    margin-right: 24px;
-    margin-bottom: 30px;
-  }
-
-  .fixedItem {
-    position: fixed;
-    width: 78px;
-    height: 78px;
-    background-color: #00cc99;
-    right: 32px;
-    bottom: 32px;
-    border-radius: 39px;
-    align-items: center;
-    justify-content: center;
-  }
-  .fixedText {
-    font-size: 36px;
-    color: white;
-    line-height: 36px;
-  }
-
-</style>
-
-<script>
-  export default {
-    data: function() {
-      const items = [
-        {
-          src:'https://gw.alicdn.com/tps/TB1Jl1CPFXXXXcJXXXXXXXXXXXX-370-370.jpg',
-          name: 'Thomas Carlyle',
-          desc:'Genius only means hard-working all one\'s life',
-          behaviourName: 'Change count',
-          behaviour: 'changeColumnCount'
-        },
-        {
-          src:'https://gw.alicdn.com/tps/TB1Hv1JPFXXXXa3XXXXXXXXXXXX-370-370.jpg',
-          desc:'The man who has made up his mind to win will never say "impossible "',
-          behaviourName: 'Change gap',
-          behaviour: 'changeColumnGap'
-        },
-        {
-          src:'https://gw.alicdn.com/tps/TB1eNKuPFXXXXc_XpXXXXXXXXXX-370-370.jpg',
-          desc:'There is no such thing as a great talent without great will - power',
-          behaviourName: 'Show scrollbar',
-          behaviour: 'showScrollbar',
-        },
-        {
-          src:'https://gw.alicdn.com/tps/TB1DCh8PFXXXXX7aXXXXXXXXXXX-370-370.jpg',
-          name:'Addison',
-          desc:'Cease to struggle and you cease to live',
-          behaviourName: 'Change width',
-          behaviour: 'changeColumnWidth',
-        },
-        {
-          src:'https://gw.alicdn.com/tps/TB1ACygPFXXXXXwXVXXXXXXXXXX-370-370.jpg',
-          desc:'A strong man will struggle with the storms of fate',
-          behaviourName: 'Listen appear',
-          behaviour: 'listenAppear',
-        },
-        {
-          src:'https://gw.alicdn.com/tps/TB1IGShPFXXXXaqXVXXXXXXXXXX-370-370.jpg',
-          name:'Ruskin',
-          desc:'Living without an aim is like sailing without a compass',
-          behaviourName: 'Set scrollable',
-          behaviour: 'setScrollable',
-        },
-        {
-          src:'https://gw.alicdn.com/tps/TB1xU93PFXXXXXHaXXXXXXXXXXX-240-240.jpg',
-          behaviourName: 'waterfall padding',
-          behaviour: 'setPadding',
-        },
-        {
-          src:'https://gw.alicdn.com/tps/TB19hu0PFXXXXaXaXXXXXXXXXXX-240-240.jpg',
-          name:'Balzac',
-          desc:'There is no such thing as a great talent without great will - power',
-          behaviourName: 'listen scroll',
-          behaviour: 'listenScroll',
-        },
-        {
-          src:'https://gw.alicdn.com/tps/TB1ux2vPFXXXXbkXXXXXXXXXXXX-240-240.jpg',
-          behaviourName: 'Remove cell',
-          behaviour: 'removeCell',
-        },
-        {
-          src:'https://gw.alicdn.com/tps/TB1tCCWPFXXXXa7aXXXXXXXXXXX-240-240.jpg',
-          behaviourName: 'Move cell',
-          behaviour: 'moveCell',
-        }
-      ]
-
-      let repeatItems = [];
-      for (let i = 0; i < 3; i++) {
-        repeatItems.push(...items)
-      }
-
-      return {
-        padding: 0,
-        refreshing: false,
-        refreshText: '↓   pull to refresh...',
-        columnCount: 2,
-        columnGap: 12,
-        columnWidth: 'auto',
-        contentOffset: '0',
-        showHeader: true,
-        showScrollbar: false,
-        scrollable: true,
-        showStickyHeader: false,
-        appearImage: null,
-        disappearImage: null,
-        stickyHeaderType: 'none',
-        banner: {
-          photos: [
-            {src:'https://gw.alicdn.com/tps/TB1JyaCPFXXXXc9XXXXXXXXXXXX-140-140.jpg'},
-            {src:'https://gw.alicdn.com/tps/TB1MwSFPFXXXXbdXXXXXXXXXXXX-140-140.jpg'},
-            {src:'https://gw.alicdn.com/tps/TB1U8avPFXXXXaDXpXXXXXXXXXX-140-140.jpg'},
-            {src:'https://gw.alicdn.com/tps/TB17Xh8PFXXXXbkaXXXXXXXXXXX-140-140.jpg'},
-            {src:'https://gw.alicdn.com/tps/TB1cTmLPFXXXXXRXXXXXXXXXXXX-140-140.jpg'},
-            {src:'https://gw.alicdn.com/tps/TB1oCefPFXXXXbVXVXXXXXXXXXX-140-140.jpg'}
-          ]
-        },
-        items: repeatItems
-      }
-    },
-
-    methods: {
-      recylerScroll: function(e) {
-        this.contentOffset = e.contentOffset.y
-      },
-      showOrRemoveHeader: function() {
-        this.showHeader = !this.showHeader
-      },
-      onItemclick: function (behaviour, index) {
-        console.log(`click...${behaviour} at index ${index}`)
-        switch (behaviour) {
-          case 'changeColumnCount':
-            this.changeColumnCount()
-            break
-          case 'changeColumnGap':
-            this.changeColumnGap()
-            break
-          case 'changeColumnWidth':
-            this.changeColumnWidth()
-            break
-          case 'showScrollbar':
-            this.showOrHideScrollbar()
-            break
-          case 'listenAppear':
-            this.listenAppearAndDisappear()
-            break
-          case 'setScrollable':
-            this.setScrollable()
-            break
-          case 'setPadding':
-            this.setRecyclerPadding()
-            break
-          case 'listenScroll':
-            this.listenScrollEvent()
-            break
-          case 'removeCell':
-            this.removeCell(index)
-            break
-          case 'moveCell':
-            this.moveCell(index)
-            break
-        }
-      },
-
-      itemAppear: function(src) {
-        this.appearImage = src;
-      },
-
-      itemDisappear: function(src) {
-        this.disappearImage = src;
-      },
-
-      changeColumnCount: function() {
-        if (this.columnCount === 2) {
-          this.columnCount = 3
-        } else {
-          this.columnCount = 2
-        }
-      },
-
-      changeColumnGap: function() {
-        if (this.columnGap === 12) {
-          this.columnGap = 'normal'
-        } else {
-          this.columnGap = 12
-        }
-      },
-
-      changeColumnWidth: function() {
-        if (this.columnWidth === 'auto') {
-          this.columnWidth = 600
-        } else {
-          this.columnWidth = 'auto'
-        }
-      },
-
-      showOrHideScrollbar: function() {
-        this.showScrollbar = !this.showScrollbar
-      },
-
-      setScrollable: function() {
-        this.scrollable = !this.scrollable
-      },
-
-      listenAppearAndDisappear: function() {
-        this.stickyHeaderType = (this.stickyHeaderType === 'appear' ? 'none' : 'appear')
-      },
-
-      listenScrollEvent: function() {
-        this.stickyHeaderType = (this.stickyHeaderType === 'scroll' ? 'none' : 'scroll')
-      },
-
-      scrollToTop: function() {
-        // weex.requireModule('dom').scrollToElement(this.$refs.cell0)
-        weex.requireModule('dom').scrollToElement(this.$refs.header)
-      },
-
-      setRecyclerPadding: function() {
-        debugger;
-        this.padding = (this.padding == 0 ? 12 : 0);
-      },
-
-      removeCell: function(index) {
-        this.items.splice(index, 1)
-      },
-
-      moveCell: function(index) {
-        
-        if (index == 0) {
-          this.items.splice(this.items.length - 1, 0, this.items.splice(index, 1)[0]);
-        } else {
-          this.items.splice(0, 0, this.items.splice(index, 1)[0]);
-        }
-      },
-
-      onrefresh (event) {
-        this.refreshing = true
-        this.refreshText = "loading..."
-        setTimeout(() => {
-          this.refreshing = false
-          this.refreshText = '↓   pull to refresh...'
-        }, 2000)
-      },
-
-      onpullingdown (event) {
-        // console.log(`${event.pullingDistance}`)
-        if (event.pullingDistance < -64) {
-          this.refreshText = '↑   release to refresh...'
-        } else {
-          this.refreshText = '↓   pull to refresh...'
-        }
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/components/web.vue b/examples/vue/components/web.vue
deleted file mode 100644
index 47282cb..0000000
--- a/examples/vue/components/web.vue
+++ /dev/null
@@ -1,74 +0,0 @@
-<template>
-  <div class="wrapper">
-    <div class="toolbar" append="tree">
-      <button type="primary" size="small" value="back"
-        style="margin-left:30px;width:210px; margin-top:5px; margin-bottom:5px"
-        @click.native="goback"></button>
-      <button type="primary" size="small" value="forward"
-        style="margin-left:30px;width:210px; margin-top:5px; margin-bottom:5px"
-        @click.native="goforward"></button>
-      <button type="primary" size="small" value="refresh"
-        style="margin-left:30px;width:210px; margin-top:5px; margin-bottom:5px"
-        @click.native="refresh"></button>
-    </div>
-    <web class="content" ref="webview" src='http://alibaba.github.io/weex/index.html'
-      @pagestart="startload" @pagefinish="finishload" @error="failload"></web>
-  </div>
-</template>
-
-<style scoped>
-  .wrapper {
-    width: 750;
-    position: absolute;
-    top: 0;
-    left: 0;
-    right: 0;
-    bottom: 0;
-  }
-  .content {
-    position: absolute;
-    top: 0;
-    left: 0;
-    right: 0;
-    bottom: 0;
-    margin-top: 0;
-    margin-bottom: 70;
-  }
-  .toolbar {
-    flex-direction: row;
-    position: fixed;
-    bottom: 0;
-    left: 0;
-    right: 0;
-    height: 70;
-  }
-</style>
-
-<script>
-  var webview = weex.requireModule('webview');
-  module.exports = {
-    components: {
-      button: require('../include/button.vue')
-    },
-    methods: {
-      goback: function() {
-        var el = this.$refs.webview
-        webview.goBack(el)
-      },
-      goforward: function() {
-        var el = this.$refs.webview
-        webview.goForward(el)
-      },
-      refresh: function() {
-        var el = this.$refs.webview
-        webview.reload(el)
-      },
-      startload: function(e) {
-      },
-      finishload: function(e) {
-      },
-      failload: function(e) {
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/hello.vue b/examples/vue/hello.vue
deleted file mode 100644
index 76272f7..0000000
--- a/examples/vue/hello.vue
+++ /dev/null
@@ -1,5 +0,0 @@
-<template>
-  <div>
-    <text style="font-size: 100px;">Hello World.</text>
-  </div>
-</template>
\ No newline at end of file
diff --git a/examples/vue/iconfont.vue b/examples/vue/iconfont.vue
deleted file mode 100644
index 0141863..0000000
--- a/examples/vue/iconfont.vue
+++ /dev/null
@@ -1,93 +0,0 @@
-<template>
-  <scroller style='align-items:center'>
-    <div style='margin-top:20px'>
-      <text style="color:red;font-size:50px">only support font for ttf and woff</text>
-    </div>
-    <text class="title2" style='margin-top:50px;width:500px'>http ttf: &#xe606;&#xe605;&#xe604;&#xe603;&#xe602;&#xe601;&#xe600;</text>
-    <text class="title3" style='margin-top:50px;width:500px'>http woff: &#xe606;&#xe605;&#xe604;&#xe603;&#xe602;&#xe601;&#xe600;</text>
-    
-    <div style='flex-direction:row;margin-top:50px'>
-      <text style='font-family:iconfont4;font-size:50;color:green'>&#xe614;&#xe612;&#xe613;</text>
-      <text style='font-family:iconfont4;font-size:50;'>&#xe614;&#xe612;&#xe613;&#xe61d;&#xe714;</text>
-      <text style='font-family:iconfont4;font-size:60;color:blue'>&#xe711;</text>
-      <text style='font-family:iconfont4;font-size:60;color:green'>&#xe71c;&#xe60b;</text>
-    </div>
-    <div style='flex-direction:row;margin-top:50px'>
-      <text style='font-family:iconfont4;font-size:50;color:green'>&#xe71b;</text>
-      <text style='font-family:iconfont4;font-size:50;'>&#xe713;</text>
-      <text style='font-family:iconfont4;font-size:60;color:blue'>&#xe714;</text>
-      <text style='font-family:iconfont4;font-size:60;color:green'>&#xe71f;&#xe602;&#xe715;&#xe60a;&#xe606;&#xe717;&#xe657;&#xe654;&#xe64f;&#xe637;</text>
-    </div>
-    <div>
-      <text style='font-family:iconfont4;font-size:100; margin-top:50px'>&#xe631;&#xe630;&#xe627;&#xe63e;&#xe649;&#xe641;&#xe643;</text>
-    </div>
-
-    <div>
-      <text style='font-family:iconfont4;font-size:100;color:green;margin-top:50px'>&#xe61e;&#xe600;&#xe62b;&#xe646;</text>
-      <text style='font-family:iconfont4;font-size:100;margin-top:50px'> </text>
-    </div>
-
-    <div style='flex-direction:row'>
-      <text style='font-family:iconfont4;font-size:70;width:750px'>&#xe748;&#xe747;&#xe746;&#xe746;&#xe745;&#xe744;&#xe742;&#xe740;&#xe73f;&#xe73a;&#xe731;&#xe6e0;&#xe72c;&#xe730;&#xe740;&#xe6e1;&#xe6d7;&#xe739;&#xe73d;&#xe735;&#xe72a;&#xe6e3;&#xe738;</text>
-    </div>
-    
-  </scroller>
-  
-</template>
-<style>
-  .title1 {
-    color: red;
-    font-size: 36;
-    font-family: iconfont1;
-  }
-
-  .title2 {
-    color: gray;
-    font-size: 36;
-    font-family: iconfont2;
-  }
-
-  .title3 {
-    color: pink;
-    font-size: 36;
-    font-family: iconfont3;
-  }
-
-  .title4 {
-    color: red;
-    font-size: 36;
-    font-family: iconfont4;
-  }
-</style>
-
-<script>
-  module.exports = {
-    created: function() {
-
-      var domModule = weex.requireModule('dom');
-      //目前支持ttf、woff文件,不支持svg、eot类型,moreItem at http://www.iconfont.cn/
-      
-      domModule.addRule('fontFace', {
-        'fontFamily': "iconfont2",
-        'src': "url('http://at.alicdn.com/t/font_1469606063_76593.ttf')"
-      });
-      domModule.addRule('fontFace', {
-        'fontFamily': "iconfont3",
-        'src': "url('http://at.alicdn.com/t/font_1469606522_9417143.woff')"
-      });
-      
-        domModule.addRule('fontFace', {
-        'fontFamily': "iconfont4",
-        'src': "url('http://at.alicdn.com/t/font_zn5b3jswpofuhaor.ttf')"
-      });
-
-
-      // you can use the absolute path or the local:// scheme path
-      //  domModule.addRule('fontFace', {
-      //   'fontFamily': "iconfont4",
-      //   'src': "url('file:///storage/emulated/0/Android/data/com.alibaba.weex/cache/http:__at.alicdn.com_t_font_1469606063_76593.ttf')"
-      // });
-      
-    }
-  }
-</script>
\ No newline at end of file
diff --git a/examples/vue/include/base-url.js b/examples/vue/include/base-url.js
deleted file mode 100644
index f3f4e5d..0000000
--- a/examples/vue/include/base-url.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-exports.getBaseURL = function (vm) {
-  var bundleUrl = weex.config.bundleUrl;
-  var nativeBase;
-  var isAndroidAssets = bundleUrl.indexOf('your_current_IP') >= 0 || bundleUrl.indexOf('file://assets/')>=0;
-  var isiOSAssets = bundleUrl.indexOf('file:///') >= 0 && bundleUrl.indexOf('WeexDemo.app') > 0;
-  if (isAndroidAssets) {
-    nativeBase = 'file://assets/';
-  }
-  else if (isiOSAssets) {
-    // file:///var/mobile/Containers/Bundle/Application/{id}/WeexDemo.app/
-    // file:///Users/{user}/Library/Developer/CoreSimulator/Devices/{id}/data/Containers/Bundle/Application/{id}/WeexDemo.app/
-    nativeBase = bundleUrl.substring(0, bundleUrl.lastIndexOf('/') + 1);
-  }
-  else {
-    var host = 'localhost:12580';
-    var matches = /\/\/([^\/]+?)\//.exec(weex.config.bundleUrl);
-    if (matches && matches.length >= 2) {
-      host = matches[1];
-    }
-    nativeBase = 'http://' + host + '/' + vm.dir + '/build/';
-  }
-  var h5Base = './index.html?page=./' + vm.dir + '/build/';
-  // in Native
-  var base = nativeBase;
-  if (typeof window === 'object') {
-    // in Browser or WebView
-    base = h5Base;
-  }
-  return base
-}
diff --git a/examples/vue/include/button.vue b/examples/vue/include/button.vue
deleted file mode 100644
index 7c9565a..0000000
--- a/examples/vue/include/button.vue
+++ /dev/null
@@ -1,162 +0,0 @@
-<!-- Inspired by bootstrap http://getbootstrap.com/ -->
-<template>
-  <div :class="['btn', 'btn-' + type, 'btn-sz-' + size]">
-    <text :class="['btn-txt', 'btn-txt-' + type, 'btn-txt-sz-' + size]">{{value}}</text>
-  </div>
-</template>
-
-<script>
-  module.exports = {
-    props: {
-      type: { default: 'default' },
-      size: { default: 'large' },
-      value: { default: '' }
-    }
-  }
-</script>
-
-<style scoped>
-  .btn {
-    margin-bottom: 0;
-    align-items: center;
-    justify-content: center;
-    border-width: 1px;
-    border-style: solid;
-    border-color: #333;
-
-    /*white-space: nowrap;*/
-    /*vertical-align: middle;*/
-    /*touch-action: manipulation;*/
-    /*cursor: pointer;*/
-    /*-webkit-user-select: none;*/
-    /*background-image: none;*/
-    /*border-image-source: initial;*/
-    /*border-image-slice: initial;*/
-    /*border-image-width: initial;*/
-    /*border-image-outset: initial;*/
-    /*border-image-repeat: initial;*/
-  }
-
-  .btn-txt {
-
-  }
-
-  /**TYPE**/
-
-  .btn-default {
-    color: rgb(51, 51, 51);
-  }
-
-  .btn-primary {
-    background-color: rgb(40, 96, 144);
-    border-color: rgb(40, 96, 144);
-  }
-
-  .btn-success {
-    background-color: rgb(92, 184, 92);
-    border-color: rgb(76, 174, 76);
-  }
-
-  .btn-info {
-    background-color: rgb(91, 192, 222);
-    border-color: rgb(70, 184, 218);
-  }
-
-  .btn-warning {
-    background-color: rgb(240, 173, 78);
-    border-color: rgb(238, 162, 54);
-  }
-
-  .btn-danger {
-    background-color: rgb(217, 83, 79);
-    border-color: rgb(212, 63, 58);
-  }
-
-  .btn-link {
-    border-color: transparent;
-    border-radius: 0;
-  }
-
-  .btn-txt-default {
-    color: rgb(51, 51, 51);
-  }
-
-  .btn-txt-primary {
-    color: rgb(255, 255, 255);
-  }
-
-  .btn-txt-success {
-    color: rgb(255, 255, 255);
-  }
-
-  .btn-txt-info {
-    color: rgb(255, 255, 255);
-  }
-
-  .btn-txt-warning {
-    color: rgb(255, 255, 255);
-  }
-
-  .btn-txt-danger {
-    color: rgb(255, 255, 255);
-  }
-
-  .btn-txt-link {
-    color: rgb(51, 122, 183);
-    /*font-weight: 400;*/
-  }
-
-  /**SIZE**/
-
-  .btn-sz-large {
-    width: 300px;
-    height: 100px;
-    padding-top: 25px;
-    padding-bottom: 25px;
-    padding-left: 40px;
-    padding-right: 40px;
-    /*line-height: 1.33333;*/
-    border-radius: 15px;
-  }
-
-  .btn-sz-middle {
-    width: 240px;
-    height: 80px;
-    padding-top: 15px;
-    padding-bottom: 15px;
-    padding-left: 30px;
-    padding-right: 30px;
-    /*line-height: 1.42857;*/
-    border-radius: 10px;
-  }
-
-  .btn-sz-small {
-    width: 170px;
-    height: 60px;
-    padding-top: 12px;
-    padding-bottom: 12px;
-    padding-left: 25px;
-    padding-right: 25px;
-    /*line-height: 1.5;*/
-    border-radius: 7px;
-  }
-
-  .btn-txt-sz-large {
-    font-size: 45px;
-  }
-
-  .btn-txt-sz-middle {
-    font-size: 35px;
-  }
-
-  .btn-txt-sz-small {
-    font-size: 30px;
-  }
-
-  /*DISABLED*/
-
-  .disabled {
-
-  }
-
-</style>
diff --git a/examples/vue/include/countdown.vue b/examples/vue/include/countdown.vue
deleted file mode 100644
index b9b6002..0000000
--- a/examples/vue/include/countdown.vue
+++ /dev/null
@@ -1,93 +0,0 @@
-<template>
-  <div style="overflow: hidden; flex-direction: row;"
-  v-on:appear="appeared"
-  v-on:disappear="disappeared">
-  <slot></slot>
-</div>
-</template>
-
-<style scoped>
-.wrap {
-  overflow: hidden;
-}
-</style>
-
-<script>
-function format (str) {
-  if (str.length >= 2) {
-    return str;
-  } else {
-    return '0' + str;
-  }
-}
-
-function getTime(target, now) {
-  var remain = parseInt((target - now) / 1000)
-  var D = String(parseInt(remain / 86400))
-  var DD = format(D)
-  var h = String(parseInt((remain - parseInt(D) * 86400) / 3600))
-  var hh = format(h)
-  var H = String(parseInt(remain / 3600))
-  var HH = format(H)
-  var m = String(parseInt((remain - parseInt(H) * 3600) / 60))
-  var mm = format(m)
-  var M = String(parseInt(remain / 60))
-  var MM = format(M)
-  var s = String(remain - parseInt(M) * 60)
-  var ss = format(s)
-  var S = String(remain)
-  var SS = format(S)
-  return {
-    D: D, DD: DD,
-    h: h, hh: hh,
-    H: H, HH: HH,
-    m: m, mm: mm,
-    M: M, MM: MM,
-    s: s, ss: ss,
-    S: S, SS: SS
-  }
-}
-
-module.exports = {
-  props: {
-    remain: {
-      default: 0
-    }
-  },
-  data: function () {
-    return {
-      now: 0,
-      target: 0,
-      outofview: false
-    }
-  },
-  created: function() {
-    this.now = Date.now();
-    this.target = this.now + this.remain * 1000
-    if (this.remain > 0) {
-      this.run();
-    }
-  },
-  methods: {
-    run: function() {
-      if (!this.outofview) {
-        this.now = Date.now()
-      }
-      var time = getTime(this.target, this.now)
-      if (this.target >= this.now) {
-        this.$emit('tick', time)
-      } else {
-        this.$emit('alarm', time)
-        return
-      }
-      setTimeout(this.run.bind(this), 1000)
-    },
-    appeared: function() {
-      this.outofview = false
-    },
-    disappeared: function() {
-      this.outofview = true
-    }
-  }
-}
-</script>
diff --git a/examples/vue/include/example-list-item.vue b/examples/vue/include/example-list-item.vue
deleted file mode 100644
index 9c16204..0000000
--- a/examples/vue/include/example-list-item.vue
+++ /dev/null
@@ -1,30 +0,0 @@
-<template>
-  <list-item v-on:click="redirect">
-    <text class="item-txt">{{title}}</text>
-  </list-item>
-</template>
-
-<style scoped>
-  .item-txt {
-    font-size: 48px;
-    color: #555;
-  }
-</style>
-
-<script>
-  var event = weex.requireModule('event')
-  module.exports = {
-    props: {
-      title: { default: '456' },
-      url: { default: '' }
-    },
-    components: {
-      listItem: require('./list-item.vue')
-    },
-    methods: {
-      redirect: function() {
-        event.openURL(this.url)
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/include/example-list.vue b/examples/vue/include/example-list.vue
deleted file mode 100644
index d9a2a7e..0000000
--- a/examples/vue/include/example-list.vue
+++ /dev/null
@@ -1,35 +0,0 @@
-<template>
-  <list>
-    <cell v-for="(item, i) in items" :key="i" append="tree">
-      <example-list-item :title="item.title" :url="item.url"></example-list-item>
-    </cell>
-  </list>
-</template>
-
-<script>
-  var getBaseURL = require('./base-url.js').getBaseURL
-  module.exports = {
-    props: {
-      dir: {
-        default: 'examples'
-      }, // examples, test ...
-      items: {
-        default: [
-          {name: 'hello', title: 'Hello World', url: ''}
-        ]
-      }
-    },
-    components: {
-      exampleListItem: require('./example-list-item.vue')
-    },
-    created: function() {
-      var base = getBaseURL(this)
-      for (var i in this.items) {
-        var item = this.items[i];
-        if (!item.url) {
-          item.url = base + item.name + '.js';
-        }
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/include/foo.vue b/examples/vue/include/foo.vue
deleted file mode 100644
index 53bf218..0000000
--- a/examples/vue/include/foo.vue
+++ /dev/null
@@ -1,12 +0,0 @@
-<template>
-  <text>{{ title }}</text>
-</template>
-
-<script>
-  module.exports = {
-    props: ['title'],
-    data: function () {
-      return {title: 'x'}
-    }
-  }
-</script>
diff --git a/examples/vue/include/h1.vue b/examples/vue/include/h1.vue
deleted file mode 100644
index 78c0191..0000000
--- a/examples/vue/include/h1.vue
+++ /dev/null
@@ -1,13 +0,0 @@
-<template>
-  <text class="h1">{{value}}</text>
-</template>
-
-<style scoped>
-  .h1 {font-size: 64px; font-weight: bold;
-    padding: 20px; margin-top: 20px; margin-bottom: 20px;
-    background-color: #eee;}
-</style>
-
-<script>
-  exports.props = ['value']
-</script>
diff --git a/examples/vue/include/h2.vue b/examples/vue/include/h2.vue
deleted file mode 100644
index 6362093..0000000
--- a/examples/vue/include/h2.vue
+++ /dev/null
@@ -1,13 +0,0 @@
-<template>
-  <text class="h2">{{value}}</text>
-</template>
-
-<style scoped>
-  .h2 {font-size: 48px; font-weight: bold;
-    padding: 20px; margin-top: 20px; margin-bottom: 20px;
-    background-color: #eee;}
-</style>
-
-<script>
-  exports.props = ['value']
-</script>
diff --git a/examples/vue/include/h3.vue b/examples/vue/include/h3.vue
deleted file mode 100644
index 338b340..0000000
--- a/examples/vue/include/h3.vue
+++ /dev/null
@@ -1,13 +0,0 @@
-<template>
-  <text class="h3">{{value}}</text>
-</template>
-
-<style scoped>
-  .h3 {font-size: 36px; font-weight: bold;
-    padding: 20px; margin-top: 20px; margin-bottom: 20px;
-    background-color: #eee;}
-</style>
-
-<script>
-  exports.props = ['value']
-</script>
diff --git a/examples/vue/include/hn.vue b/examples/vue/include/hn.vue
deleted file mode 100644
index 39e18b6..0000000
--- a/examples/vue/include/hn.vue
+++ /dev/null
@@ -1,47 +0,0 @@
-<template>
-  <div :class="['h' + level]" style="justify-content: center;">
-    <text :class="['txt-h' + level]">{{value}}</text>
-  </div>
-</template>
-
-<script>
-  module.exports = {
-    props: {
-      level: { default: 1 },
-      value: { default: '' }
-    }
-  }
-</script>
-
-<style scoped>
-  .h1 {
-    height: 110px;
-    padding-top: 20px;
-    padding-bottom: 20px;
-  }
-
-  .h2 {
-    height: 110px;
-    padding-top: 20px;
-    padding-bottom: 20px;
-  }
-
-  .h3 {
-    height: 110px;
-    padding-top: 20px;
-    padding-bottom: 20px;
-  }
-  
-
-  .txt-h1 {
-    font-size: 70px;
-  }
-
-  .txt-h2 {
-    font-size: 52px;
-  }
-
-  .txt-h3 {
-    font-size: 42px;
-  }
-</style>
diff --git a/examples/vue/include/list-item.vue b/examples/vue/include/list-item.vue
deleted file mode 100644
index 88a835e..0000000
--- a/examples/vue/include/list-item.vue
+++ /dev/null
@@ -1,46 +0,0 @@
-<template>
-  <div
-    :style="{ backgroundColor: bgColor }"
-    class="item"
-    v-on:click="click"
-    v-on:touchstart="touchstart"
-    v-on:touchend="touchend">
-    <slot></slot>
-  </div>
-</template>
-
-<script>
-  module.exports = {
-    props:  {
-      bgColor: { default: '#ffffff' }
-    },
-    methods: {
-      click: function () {
-        this.$emit('click')
-      },
-      touchstart: function() {
-        // FIXME android touch
-        // TODO adaptive opposite bgColor
-        // this.bgColor = '#e6e6e6';
-      },
-      touchend: function() {
-        // FIXME android touchend not triggered
-        // this.bgColor = '#ffffff';
-      }
-    }
-  }
-</script>
-
-<style scoped>
-  .item {
-    padding-top: 25px;
-    padding-bottom: 25px;
-    padding-left: 35px;
-    padding-right: 35px;
-    height: 160px;
-    justify-content: center;
-    /*margin-bottom: 1px; FUTURE */
-    border-bottom-width: 1px;
-    border-color: #dddddd;
-  }
-</style>
diff --git a/examples/vue/include/marquee.vue b/examples/vue/include/marquee.vue
deleted file mode 100644
index eeb59de..0000000
--- a/examples/vue/include/marquee.vue
+++ /dev/null
@@ -1,78 +0,0 @@
-<template>
-  <div
-    class="wrap"
-    @appear="appeared"
-    @disappear="disappeared">
-    <div
-      ref="anim"
-      class="anim">
-      <slot></slot>
-    </div>
-  </div>
-</template>
-
-<style scoped>
-  .wrap {
-    overflow: hidden;
-    position: relative;
-  }
-  .anim {
-    flex-direction: column;
-    position: absolute;
-    transform: translateY(0) translateZ(0);
-  }
-</style>
-
-<script>
-  var animation = weex.requireModule('animation')
-
-  module.exports = {
-    props: {
-      step: { default: 0 },
-      count: { default: 0 },
-      index: { default: 1 },
-      duration: { default: 0 },
-      interval: { default: 0 },
-      outofview: { default: false }
-    },
-    created: function () {
-      if (this.interval > 0 && this.step > 0 && this.duration > 0) {
-        this.run()
-      }
-    },
-    methods: {
-      run: function () {
-        if (this.outofview) {
-          setTimeout(this.run.bind(this), this.interval)
-        } else {
-          setTimeout(function () {
-            this.animation(this.run.bind(this))
-          }.bind(this), this.interval)
-        }
-      },
-      animation: function (cb) {
-        var offset = -this.step * this.index;
-        animation.transition(this.$refs.anim, {
-          styles: {
-            transform: 'translateY(' + offset + 'px) translateZ(0)'
-          },
-          timingFunction: 'ease',
-          duration: this.duration
-        }, function () {
-          this.index = (this.index + 1) % (this.count);
-          this.$emit('change', {
-            index: this.index,
-            count: this.count
-          });
-          cb && cb();
-        }.bind(this));
-      },
-      appeared: function() {
-        this.outofview = false
-      },
-      disappeared: function() {
-        this.outofview = true
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/include/navbar.vue b/examples/vue/include/navbar.vue
deleted file mode 100644
index 69bbe0b..0000000
--- a/examples/vue/include/navbar.vue
+++ /dev/null
@@ -1,121 +0,0 @@
-<template>
-  <div
-    :dataRole="dataRole"
-    class="container"
-    :style="{ height: height, backgroundColor: backgroundColor }">
-    <text
-      v-if="!rightItemSrc"
-      naviItemPosition="right"
-      :style="{ color: rightItemColor }"
-      class="right-text"
-      v-on:click="onclickrightitem">{{rightItemTitle}}</text>
-    <image
-      v-if="rightItemSrc"
-      naviItemPosition="right"
-      :src="rightItemSrc"
-      class="right-image"
-      v-on:click="onclickrightitem"></image>
-    <text
-      v-if="!leftItemSrc"
-      naviItemPosition="left"
-      :style="{ color: leftItemColor }"
-      class="left-text"
-      v-on:click="onclickleftitem">{{leftItemTitle}}</text>
-    <image
-      v-if="leftItemSrc"
-      naviItemPosition="left"
-      :src="leftItemSrc"
-      class="left-image"
-      v-on:click="onclickleftitem"></image>
-    <text
-      naviItemPosition="center"
-      :style="{ color: titleColor }"
-      class="center-text">{{title}}</text>
-  </div>
-</template>
-
-<style scoped>
-  .container {
-    flex-direction: row; 
-    position: fixed; 
-    top: 0; 
-    left: 0; 
-    right: 0; 
-    width: 750;
-  }
-  .right-text {
-    position: absolute; 
-    bottom: 28; 
-    right: 32; 
-    text-align: right;
-    font-size: 32; 
-    font-family: 'Open Sans', sans-serif;
-  }
-  .left-text {
-    position: absolute; 
-    bottom: 28; 
-    left :32; 
-    text-align :left;  
-    font-size: 32; 
-    font-family: 'Open Sans', sans-serif;
-  }
-  .center-text {
-    position: absolute; 
-    bottom: 25; 
-    left: 172; 
-    right: 172;
-    text-align: center; 
-    font-size: 36; 
-    font-weight: bold;
-  }
-  .left-image {
-    position: absolute; 
-    bottom: 20; 
-    left: 28; 
-    width: 50; 
-    height: 50;
-  }
-  .right-image {
-    position: absolute; 
-    bottom: 20; 
-    right: 28; 
-    width: 50; 
-    height: 50;
-  }
-</style>
-
-<script>
-  module.exports = {
-    props: {
-      dataRole: { default: 'navbar' },
-      //导航条背景色
-      backgroundColor: { default: 'black' },
-      //导航条高度
-      height: { default: 88 },
-      //导航条标题 
-      title: { default: '' },
-      //导航条标题颜色
-      titleColor: { default: 'black' },
-      //右侧按钮图片
-      rightItemSrc: { default: '' },
-      //右侧按钮标题
-      rightItemTitle: { default: '' },
-      //右侧按钮标题颜色
-      rightItemColor: { default: 'black' },
-      //左侧按钮图片
-      leftItemSrc: { default: '' },
-      //左侧按钮标题
-      leftItemTitle: { default: '' },
-      //左侧按钮颜色
-      leftItemColor: { default: 'black' }
-    },
-    methods: {
-      onclickrightitem: function (e) {
-        this.$emit('naviBarRightItemClick');
-      },
-      onclickleftitem: function (e) {
-        this.$emit('naviBarLeftItemClick');
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/include/navpage.vue b/examples/vue/include/navpage.vue
deleted file mode 100644
index c9ea887..0000000
--- a/examples/vue/include/navpage.vue
+++ /dev/null
@@ -1,62 +0,0 @@
-<template>
-  <div class="wrapper">
-    <navbar
-      :dataRole="dataRole"
-      :height="height"
-      :backgroundColor="backgroundColor"
-      :title="title"
-      :titleColor="titleColor"
-      :leftItemSrc="leftItemSrc"
-      :leftItemTitle="leftItemTitle"
-      :leftItemColor="leftItemColor"
-      :rightItemSrc="rightItemSrc"
-      :rightItemTitle="rightItemTitle"
-      :rightItemColor="rightItemColor"
-      @naviBarRightItemClick="naviBarRightItemClick"
-      @naviBarLeftItemClick="naviBarLeftItemClick"
-      ></navbar>
-    <div class="wrapper" :style="{ marginTop: height }">
-      <slot></slot>
-    </div>
-  </div>
-</template>
-
-<style scoped>
-  .wrapper {
-    position: absolute; 
-    top: 0; 
-    left: 0; 
-    right: 0; 
-    bottom: 0; 
-    width: 750;
-  }
-</style>
-
-<script>
-  module.exports = {
-    components: {
-      navbar: require('./navbar.vue')
-    },
-    props: {
-      dataRole: { default: 'navbar' },
-      backgroundColor: { default: 'black' },
-      height: { default: 88 },
-      title: { default: "" },
-      titleColor: { default: 'black' },
-      rightItemSrc: { default: '' },
-      rightItemTitle: { default: '' },
-      rightItemColor: { default: 'black' },
-      leftItemSrc: { default: '' },
-      leftItemTitle: { default: '' },
-      leftItemColor: { default: 'black' }
-    },
-    methods: {
-      naviBarRightItemClick: function (e) {
-        this.$emit('naviBarRightItemClick', e)
-      },
-      naviBarLeftItemClick: function (e) {
-        this.$emit('naviBarLeftItemClick', e)
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/include/panel.vue b/examples/vue/include/panel.vue
deleted file mode 100644
index b0c151f..0000000
--- a/examples/vue/include/panel.vue
+++ /dev/null
@@ -1,141 +0,0 @@
-<!-- Inspired by bootstrap http://getbootstrap.com/ -->
-<template>
-  <div
-    :class="['panel', 'panel-' + type]"
-    :style="{ borderWidth: border }">
-    <text
-      :class="['panel-header', 'panel-header-' + type]"
-      :style="{
-        paddingTop: paddingHead,
-        paddingBottom: paddingHead,
-        paddingLeft: paddingHead*1.5,
-        paddingRight: paddingHead*1.5
-      }">{{title}}</text>
-    <div
-      :class="['panel-body', 'panel-body-' + type]"
-      :style="{
-        paddingTop: paddingBody,
-        paddingBottom: paddingBody,
-        paddingLeft: paddingBody*1.5,
-        paddingRight: paddingBody*1.5
-      }">
-      <slot></slot>
-    </div>
-  </div>
-</template>
-
-<script>
-  module.exports = {
-    props: {
-      type: { default: 'default' },
-      title: { default: '' },
-      paddingBody: { default: 20 },
-      paddingHead: { default: 20 },
-      dataClass: { default: '' }, // FIXME transfer class
-      border:{ default: 0 }
-    }
-  }
-</script>
-
-<style scoped>
-  .panel {
-    margin-bottom: 20px;
-    background-color: #fff;
-    /*border: 1px solid transparent;*/
-    /*border-radius: 10px;*/
-    /*-webkit-box-shadow: 0 1px 1px rgba(0,0,0,.05);*/
-    /*box-shadow: 0 1px 1px rgba(0,0,0,.05);*/
-    border-color: #dddddd;
-    border-width: 1px;
-  }
-
-  .panel-default {
-  }
-
-  .panel-primary {
-    border-color: rgb(40, 96, 144);
-  }
-
-  .panel-success {
-    border-color: rgb(76, 174, 76);
-
-  }
-
-  .panel-info {
-    border-color: rgb(70, 184, 218);
-
-  }
-
-  .panel-warning {
-    border-color: rgb(238, 162, 54);
-
-  }
-
-  .panel-danger {
-    border-color: rgb(212, 63, 58);
-
-  }
-
-  .panel-header {
-    background-color: #f5f5f5;
-    font-size: 40px;
-    /*padding-left: 12px;*/
-    /*padding-right: 12px;*/
-    /*padding-top: 20px;*/
-    /*padding-bottom: 20px;*/
-    color: #333;
-  }
-
-  .panel-header-default {
-  }
-
-  .panel-header-primary {
-    background-color: rgb(40, 96, 144);
-    color: #ffffff;
-  }
-
-  .panel-header-success {
-    background-color: rgb(92, 184, 92);
-    color: #ffffff;
-  }
-
-  .panel-header-info {
-    background-color: rgb(91, 192, 222);
-    color: #ffffff;
-  }
-
-  .panel-header-warning {
-    background-color: rgb(240, 173, 78);
-    color: #ffffff;
-  }
-
-  .panel-header-danger {
-    background-color: rgb(217, 83, 79);
-    color: #ffffff;
-  }
-
-  .panel-body {
-    padding-left: 12px;
-    padding-right: 12px;
-    padding-top: 20px;
-    padding-bottom: 20px;
-  }
-
-  .panel-body-default {
-  }
-
-  .panel-body-primary {
-  }
-
-  .panel-body-success {
-  }
-
-  .panel-body-info {
-  }
-
-  .panel-body-warning {
-  }
-
-  .panel-body-danger {
-  }
-</style>
diff --git a/examples/vue/include/slider-item.vue b/examples/vue/include/slider-item.vue
deleted file mode 100644
index 94b6828..0000000
--- a/examples/vue/include/slider-item.vue
+++ /dev/null
@@ -1,19 +0,0 @@
-<template>
-  <image class="slider-item" :src="image"></image>
-</template>
-
-<script>
-  module.exports = {
-    props: {
-      image: { default: '' },
-      link: { default: '' },
-    }
-  };
-</script>
-
-<style scoped>
-  .slider-item {
-    width: 348px;
-    height: 400px;
-  }
-</style>
diff --git a/examples/vue/include/slider-page.vue b/examples/vue/include/slider-page.vue
deleted file mode 100644
index 7df0289..0000000
--- a/examples/vue/include/slider-page.vue
+++ /dev/null
@@ -1,26 +0,0 @@
-<template>
-  <div class="slider-page">
-    <slider-item v-for="(v , i) in items" :image="v.image" :key="i" :link="v.link"></slider-item>
-  </div>
-</template>
-
-<style scoped>
-  .slider-page {
-    flex-direction: row;
-    justify-content: space-between;
-
-    width: 714px;
-    height: 420px;
-  }
-</style>
-
-<script>
-  module.exports = {
-    props: {
-      items: { default: [] }
-    },
-    components: {
-      sliderItem: require('./slider-item.vue')
-    }
-  }
-</script>
diff --git a/examples/vue/include/tabbar.vue b/examples/vue/include/tabbar.vue
deleted file mode 100644
index b5087dd..0000000
--- a/examples/vue/include/tabbar.vue
+++ /dev/null
@@ -1,94 +0,0 @@
-<template>
-  <div class="wrapper">
-    <embed
-      v-for="(item , i) in tabItems"
-      :src="item.src"
-      :key="i"
-      type="weex"
-      :style="{ visibility: item.visibility }"
-      class="content"
-      ></embed>
-    <div class="tabbar" append="tree">
-      <tabitem
-        v-for="item in tabItems"
-        :key="item.index"
-        :index="item.index"
-        :icon="item.icon"
-        :title="item.title"
-        :titleColor="item.titleColor"
-        @tabItemOnClick="tabItemOnClick"
-        ></tabItem>
-    </div>
-  </div>
-</template>
-
-<style scoped>
-  .wrapper {
-    width: 750;
-    position: absolute;
-    top: 0;
-    left: 0;
-    right: 0;
-    bottom: 0;
-  }
-  .content {
-    position: absolute;
-    top: 0;
-    left: 0;
-    right: 0;
-    bottom: 0;
-    margin-top: 0;
-    margin-bottom: 88;
-  }
-  .tabbar {
-    flex-direction: row;
-    position: fixed;
-    bottom: 0;
-    left: 0;
-    right: 0;
-    height: 88;
-  }
-</style>
-
-<script>
-  module.exports = {
-    props: {
-      tabItems: { default: [] },
-      selectedColor: { default: '#ff0000' },
-      unselectedColor: { default: '#000000' }
-    },
-    data: function () {
-      return {
-        selectedIndex: 0
-      }
-    },
-    components: {
-      tabitem: require('./tabitem.vue')
-    },
-    created: function () {
-      this.select(this.selectedIndex);
-    },
-    methods: {
-      tabItemOnClick: function (e) {
-        this.selectedIndex = e.index;
-        this.select(e.index);
-        this.$emit('tabBarOnClick', e);
-      },
-      select: function(index) {
-        for(var i = 0; i < this.tabItems.length; i++) {
-          var tabItem = this.tabItems[i];
-          if(i == index){
-            tabItem.icon = tabItem.selectedImage;
-            tabItem.titleColor = this.selectedColor;
-            tabItem.visibility = 'visible';
-          }
-          else {
-            tabItem.icon = tabItem.image;
-            tabItem.titleColor = this.unselectedColor;
-            tabItem.visibility = 'hidden';
-          }
-        }
-      },
-    }
-  }
-</script>
diff --git a/examples/vue/include/tabitem.vue b/examples/vue/include/tabitem.vue
deleted file mode 100644
index 801ca0b..0000000
--- a/examples/vue/include/tabitem.vue
+++ /dev/null
@@ -1,63 +0,0 @@
-<template>
-  <div
-    :style="{ backgroundColor: backgroundColor }"
-    class="container"
-    @click="onclickitem">
-    <image
-      src="http://gtms03.alicdn.com/tps/i3/TB1mdsiMpXXXXXpXXXXNw4JIXXX-640-4.png"
-      class="top-line"></image>
-    <image
-      :src="icon"
-      class="tab-icon"></image>
-    <text
-      :style="{ color: titleColor }"
-      class="tab-text">{{title}}</text>
-  </div>  
-</template>
-
-<style scoped>
-  .container {
-    flex: 1; 
-    flex-direction: column; 
-    align-items:center; 
-    justify-content:center; 
-    height: 88;
-  }
-  .top-line {
-    position: absolute; 
-    top: 0; 
-    left: 0; 
-    right: 0; 
-    height: 2;
-  }
-  .tab-icon {
-    margin-top: 5; 
-    width: 40; 
-    height: 40
-  }
-  .tab-text {
-    margin-top: 5; 
-    text-align: center;  
-    font-size: 20;
-  }
-</style>
-
-<script>
-  module.exports = {
-    props: {
-      index: { default: 0 },
-      title: { default: '' },
-      titleColor: { default: '#000000' },
-      icon: { default: '' },
-      backgroundColor: { default: '#ffffff' }
-    },
-    methods: {
-      onclickitem: function (e) {
-        var params = {
-          index: this.index
-        };
-        this.$emit('tabItemOnClick', params);
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/include/tip.vue b/examples/vue/include/tip.vue
deleted file mode 100644
index 9e47bf3..0000000
--- a/examples/vue/include/tip.vue
+++ /dev/null
@@ -1,65 +0,0 @@
-<!-- Inspired by bootstrap http://getbootstrap.com/ -->
-<template>
-  <div :class="['tip', 'tip-' + type]">
-    <text :class="['tip-txt', 'tip-txt-' + type]">{{value}}</text>
-  </div>
-</template>
-
-<script>
-  module.exports = {
-    props: {
-      type: { default: 'success' },
-      value: { default: '' }
-    }
-  }
-</script>
-
-<style scoped>
-  .tip {
-    padding-left: 36px;
-    padding-right: 36px;
-    padding-top: 36px;
-    padding-bottom: 36px;
-    border-radius: 10px;
-  }
-
-  .tip-txt{
-    font-size: 28px;
-  }
-
-  .tip-success {
-    background-color: #dff0d8;
-    border-color: #d6e9c6;
-  }
-
-  .tip-txt-success {
-    color: #3c763d;
-  }
-
-  .tip-info {
-    background-color: #d9edf7;
-    border-color: #bce8f1;
-  }
-
-  .tip-txt-info {
-    color: #31708f;
-  }
-
-  .tip-warning {
-    background-color: #fcf8e3;
-    border-color: #faebcc;
-  }
-
-  .tip-txt-warning {
-    color: #8a6d3b;
-  }
-
-  .tip-danger {
-    background-color: #f2dede;
-    border-color: #ebccd1;
-  }
-
-  .tip-txt-danger {
-    color: #a94442;
-  }
-</style>
diff --git a/examples/vue/include/wxc-list-item.vue b/examples/vue/include/wxc-list-item.vue
deleted file mode 100644
index fd988b4..0000000
--- a/examples/vue/include/wxc-list-item.vue
+++ /dev/null
@@ -1,47 +0,0 @@
-<template>
-  <div
-    class="item" :style="{'background-color': bgColor}"
-    v-on:click="click"
-    v-on:touchstart="touchstart" v-on:touchend="touchend">
-    <text>Hello</text>
-    <slot></slot>
-  </div>
-</template>
-
-<script>
-  module.exports = {
-    data: function () {
-      return {
-        bgColor: '#ffffff'
-      }
-    },
-    methods: {
-      click: function () {
-        this.$emit('click')
-      },
-      touchstart: function() {
-        // FIXME android touch
-        // TODO adaptive opposite bgColor
-        // this.bgColor = '#e6e6e6';
-      },
-      touchend: function() {
-        // FIXME android touchend not triggered
-        // this.bgColor = '#ffffff';
-      }
-    }
-  }
-</script>
-
-<style scoped>
-  .item {
-    padding-top: 25px;
-    padding-bottom: 25px;
-    padding-left: 35px;
-    padding-right: 35px;
-    height: 160px;
-    justify-content: center;
-    /*margin-bottom: 1px; FUTURE */
-    border-bottom-width: 1px;
-    border-color: #dddddd;
-  }
-</style>
diff --git a/examples/vue/index.vue b/examples/vue/index.vue
deleted file mode 100644
index 49bea15..0000000
--- a/examples/vue/index.vue
+++ /dev/null
@@ -1,71 +0,0 @@
-<template>
-  <example-list :items="items" dir="examples"></example-list>
-</template>
-
-<script>
-  module.exports = {
-    data: function () {
-      var root = typeof window === 'object' ? 'vue-web/vue' : 'vue'
-
-      return {
-        items: [           
-          // common
-          {name: root + '/hello', title: 'Hello World'},
-          {name: root + '/style/index', title: 'Common Style'},
-          {name: root + '/animation', title: 'Animation'},
-          {name: root + '/transition', title: 'Transition'},
-
-          // component
-          {name: root + '/components/text', title: 'Text'},
-          {name: root + '/iconfont', title: 'iconfont'},
-          {name: root + '/components/image', title: 'Image'},
-          {name: root + '/components/input', title: 'Input'},
-          {name: root + '/components/scroller', title: 'Scroller'},
-          {name: root + '/components/list', title: 'List'},
-          {name: root + '/components/waterfall', title: 'Waterfall'},
-          {name: root + '/components/slider', title: 'Slider'},
-          {name: root + '/components/a', title: 'A'},
-          {name: root + '/components/video', title: 'Video'},
-          {name: root + '/components/countdown', title: 'Countdown'},
-          {name: root + '/components/marquee', title: 'Marquee'},
-          {name: root + '/components/web', title: 'Web'},
-          {name: root + '/components/navigator', title: 'Navigator'},
-          {name: root + '/components/tabbar', title: 'Tabbar'},
-
-          // module
-          {name: root + '/modules/instance-api', title: 'Instance API'},
-          {name: root + '/modules/modal', title: 'Modal'},
-          {name: root + '/modules/webSocket', title: 'WebSocket'},
-          {name: root + '/modules/stream', title: 'Stream'},
-          {name: root + '/modules/storage',title:'Storage'},
-          {name: root + '/modules/picker',title:'picker'},
-          // {name: 'module/clipboard', title: 'Clipboard'}, // 0.8 , developing
-
-          // showcase
-          {name: root + '/showcase/boxshadow', title: 'boxshadow'},
-          {name: root + '/showcase/progress', title: 'Progress Bar'},
-          {name: root + '/showcase/itemlist', title: 'List (Advanced)'},
-          {name: root + '/showcase/calculator', title: 'Calculator'},
-          {name: root + '/showcase/tap-penetrate', title: 'TapPenetrate'},
-          {name: root + '/showcase/a-node-click', title: 'ANodeClick'},
-          // {name: root + '/showcase/minesweeper', title: 'Minesweeper'},
-          // {name: root + '/showcase/ui', title: 'UI Gallery'},
-          // {name: root + '/showcase/dropdown/dropdown-demo', title: 'Dropdown'}
-
-          // market
-          {name: root + '/market/gcanvas', title: 'Gcanvas'}
-        ]
-      }
-    },
-    components: {
-      exampleList: require('./include/example-list.vue')
-    },
-    created: function() {
-      let root = typeof window === 'object' ? 'vue-web/vue' : 'vue'
-      let platform = this.$getConfig().env.platform.toLowerCase()
-      if (platform === 'ios') {
-        this.items.push({name: root + '/showcase/compositing', title: 'Compositing'})
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/market/gcanvas.vue b/examples/vue/market/gcanvas.vue
deleted file mode 100644
index 235375e..0000000
--- a/examples/vue/market/gcanvas.vue
+++ /dev/null
@@ -1,40 +0,0 @@
-<template>
-  <div ref="test">
-    <component :is="tagName" width="750" height="750" ref="canvas_holder" style="width:750px;height:750px;"></component>
-  </div>
-</template>
-<script>
-
-  var GCanvas=require('weex-gcanvas');
-  var Image=require('weex-gcanvas/gcanvasimage');
-
-  module.exports = {
-    data() {
-      return {
-        tagName: weex.config.env.platform === 'Web' ? 'canvas' : 'gcanvas'
-      }
-    },
-    mounted: function () {
-      var ref = this.$refs.canvas_holder;
-      var gcanvas = GCanvas.start(ref)
-      var ctx = gcanvas.getContext('2d');
-
-      ctx.fillStyle = 'red';
-      ctx.fillRect(0, 0, 100, 100);
-
-      ctx.fillStyle = 'black';
-      ctx.fillRect(100, 100, 100, 100);
-      ctx.fillRect(25, 210, 700, 5);
-
-      ctx.arc(450, 200, 100, 0, Math.PI * 2, true);
-      ctx.fill();
-
-      var img = new Image();
-      img.onload = function(){
-        ctx.drawImage(img, 100, 200, 210, 330);
-        // ctx.drawImage(img, 0,0,105,165, 100, 200, 210, 330);
-      };
-      img.src = 'https://img.alicdn.com/tps/TB1TFNdKVXXXXbeaXXXXXXXXXXX-210-330.png';
-    }
-  };
-</script>
diff --git a/examples/vue/modules/clipboard.vue b/examples/vue/modules/clipboard.vue
deleted file mode 100644
index eddd380..0000000
--- a/examples/vue/modules/clipboard.vue
+++ /dev/null
@@ -1,60 +0,0 @@
-<template>
-  <scroller>
-    <panel title="Clipboard" type="primary">
-      <panel title="Copy to clipboard5">
-        <text style="line-height: 40px; font-size: 28px">{{textToCopy}}</text>
-        <button type="info" size="middle" value="Copy" @click.native="doCopy"></button>
-      </panel>
-
-      <panel title="Paste from clipboard">
-        <text style="line-height: 40px; font-size: 28px">{{textFromPaste}}</text>
-        <button type="info" size="middle" value="Paste" @click.native="doPaste"></button>
-      </panel>
-
-      <panel title="Result">
-        <tip style="margin-bottom: 20px;" :value="tips"></tip>
-      </panel>
-
-    </panel>
-  </scroller>
-</template>
-
-<script>
-  var modal = weex.requireModule('modal')
-  var clipboard = weex.requireModule('clipboard')
-  module.exports = {
-    data: function () {
-      return {
-        textToCopy : '',
-        textFromPaste: '',
-        tips : ''
-      }
-    },
-    components: {
-      panel: require('../include/panel.vue'),
-      tip: require('../include/tip.vue'),
-      button: require('../include/button.vue')
-    },
-    mounted: function() {
-      this.tips = "1. Just click COPY button. It will auto generate a string with random text, and copy to system clipboard. \n 2. do copy in another app, then come back and click PASTE button."
-    },
-    methods: {
-      doCopy: function() {
-        modal.toast({'message': 'doCopy!', duration: 0.5})
-        textToCopy = "autoGenerateTextToCopy" + Math.random()
-        clipboard.setString(textToCopy)
-        this.textToCopy = textToCopy
-        this.tips = "copy done. Now system clipboard has string of '" + textToCopy + "', try PASTE button, or paste in another app."
-      },
-      doPaste: function() {
-        var me = this
-        modal.toast({'message': 'doPaste!', duration: 0.5})
-        clipboard.getString(function(ret) {
-          console.log("paste result is " + JSON.stringify(ret))
-          me.textFromPaste = ret.data
-          me.tips = "Paste done. Only support native(Android/iOS) NOW. according to security reason, paste in html5 is not supported."
-        })
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/modules/instance-api.vue b/examples/vue/modules/instance-api.vue
deleted file mode 100644
index d5dbf51..0000000
--- a/examples/vue/modules/instance-api.vue
+++ /dev/null
@@ -1,25 +0,0 @@
-<template>
-  <scroller>
-    <panel title="$getConfig()" type="primary">
-      <text>{{config}}</text>
-    </panel>
-  </scroller>
-</template>
-
-<script>
-  module.exports = {
-    data: function () {
-      return {
-        config: ''
-      }
-    },
-    components: {
-      panel: require('../include/panel.vue')
-    },
-    created: function() {
-      var config = this.$getConfig();
-      console.log('config', JSON.stringify(config));
-      this.config = JSON.stringify(config, null, 2);
-    }
-  }
-</script>
diff --git a/examples/vue/modules/modal.vue b/examples/vue/modules/modal.vue
deleted file mode 100644
index 393662a..0000000
--- a/examples/vue/modules/modal.vue
+++ /dev/null
@@ -1,73 +0,0 @@
-<template>
-  <scroller>
-    <panel title="Toast" type="primary">
-      <button type="primary" @click.native="toast" value="Toast"></button>
-    </panel>
-
-    <panel title="Dialog" type="primary">
-      <button type="success" @click.native="alert" value="Alert" style="margin-bottom: 20px;"></button>
-      <button type="primary" @click.native="confirm" value="Confirm" style="margin-bottom: 20px;"></button>
-      <button type="warning" @click.native="prompt" value="Prompt"></button>
-    </panel>
-  </scroller>
-</template>
-
-<script>
-  var modal = weex.requireModule('modal')
-  module.exports = {
-    data: function () {
-      return {}
-    },
-    components: {
-      panel: require('../include/panel.vue'),
-      button: require('../include/button.vue')
-    },
-    methods: {
-      toast: function(msg, duration) {
-        if (!msg || typeof msg !== 'string') {
-          msg = 'I am Toast show!'
-        }
-        duration = duration || 2
-        modal.toast({
-          'message': msg,
-          'duration': duration
-        })
-      },
-      alert: function(msg, okTitle, cancelTitle) {
-        if (!msg || typeof msg !== 'string') {
-          msg = "I am Alert!"
-        }
-         modal.alert({
-          'message': msg,
-          'okTitle': okTitle,
-          'cancelTitle': cancelTitle
-        }, function() {
-          modal.toast({ message: "Click Alert OK Bnt!!" })
-        })
-      },
-      confirm: function(msg, okTitle, cancelTitle) {
-        if (!msg || typeof msg !== 'string') {
-          msg = "I am Confirm!"
-        }
-        okTitle = okTitle || "OK"
-        cancelTitle = cancelTitle || "Cancel"
-        modal.confirm({
-          'message': msg,
-          'okTitle': okTitle,
-          'cancelTitle': cancelTitle
-        }, function(result) {
-          modal.toast({ message: "Click Confirm  " + JSON.stringify(result) })
-        })
-      },
-      prompt: function() {
-        modal.prompt( {
-          'message': 'I am Prompt!',
-          'okTitle': 'ok',
-          'cancelTitle': 'cancel'
-        }, function(result) {
-          modal.toast({ message: "Click Prompt  " + JSON.stringify(result) })
-        })
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/modules/picker.vue b/examples/vue/modules/picker.vue
deleted file mode 100644
index a15ab92..0000000
--- a/examples/vue/modules/picker.vue
+++ /dev/null
@@ -1,64 +0,0 @@
-<template>
-  <div class="conatiner">
-    <div style="background-color: #286090">
-      <text class="title" style="height: 80px ;padding: 20px;color: white">picker</text>
-    </div>
-	<div @click="normalpick" style="margin: 20px;padding:20px;background-color:#1ba1e2;color:#fff;"><text style="color:#fff">normalpick{{normalpickData}}</text></div>
-	<div @click="pickDate" style="margin: 20px;padding:20px;background-color:#1ba1e2;color:#fff;"><text style="color:#fff">pickDate{{pickDateData}}</text></div>
-	<div @click="pickTime" style="margin: 20px;padding:20px;background-color:#1ba1e2;color:#fff;"><text style="color:#fff">pickTime{{pickTimeData}}</text></div>
-  </div>
-</template>
-
-<style>
-  .container {
-	flex: 1;
-  }
-</style>
-
-<script>
-  const picker = weex.requireModule('picker');
-  module.exports = {
-    data: {
-      normalpickData:'',
-      pickDateData:'',
-         pickTimeData:''
-    },
-    methods: {
-      normalpick: function() {
-        var self = this;
-    	picker.pick({
-    	  height: '300px',
-    	  items: [1, 2, 3, 4],
-    	}, function(ret) {
-    	  var result = ret.result;
-    	  if (result == 'success') {
-    		self.normalpickData = ret.data;
-    	  }
-    	})
-      },
-      pickDate: function(e) {
-    	var self = this;
-    	picker.pickDate({
-    	  'value': '2016-12-20',
-    	  'max': '2016-12-30',
-    	  'min': '2014-12-30',
-    	}, function(ret) {
-    	  var result = ret.result;
-    	  if (result == 'success') {
-    		self.pickDateData = ret.data;
-    	  }
-    	});
-      },
-      pickTime:function(){
-    	var self = this;
-    	picker.pickTime({
-    	}, function(ret) {
-    	  var result = ret.result;
-    	  if (result == 'success') {
-    		self.pickTimeData = ret.data;
-    	  }
-    	});
-      }
-    }
-  }
-</script>
\ No newline at end of file
diff --git a/examples/vue/modules/storage.vue b/examples/vue/modules/storage.vue
deleted file mode 100644
index 380b511..0000000
--- a/examples/vue/modules/storage.vue
+++ /dev/null
@@ -1,82 +0,0 @@
-<template>
-  <scroller>
-    <panel title="storage API" type="primary">
-      <panel title="setItem">
-        <text>{{setItemResult}}</text>
-      </panel>
-      <panel title="getItem">
-        <text>{{getItemResult}}</text>
-      </panel>
-      <panel title="length">
-        <text>{{lengthResult}}</text>
-      </panel>
-      <panel title="getAllKeys">
-        <text>{{getAllKeysResult}}</text>
-      </panel>
-      <panel title="removeItem">
-        <text>{{removeItemResult}}</text>
-      </panel>
-    </panel>
-  </scroller>
-</template>
-
-
-<script>
-  var storage = weex.requireModule('storage')
-  module.exports = {
-    data: function () {
-      return {
-        setItemResult:'loading',
-        getItemResult:'loading',
-        removeItemResult:'loading',
-        lengthResult:'loading',
-        getAllKeysResult:'loading'
-      }
-    },
-    components: {
-      panel: require('../include/panel.vue')
-    },
-    created: function() {
-      var me = this
-
-      //setItem
-      storage.setItem('foo','foo-value',function(e){
-        console.log('set [foo<->foo-value]:'+JSON.stringify(e))
-        me.setItemResult = 'foo:'+JSON.stringify(e)+'\n'
-      })
-      storage.setItem('bar','bar-value',function(e){
-        console.log('set [bar<->bar-value]:'+JSON.stringify(e))
-        me.setItemResult = me.setItemResult + 'bar:'+JSON.stringify(e)
-      })
-
-      //getItem
-      storage.getItem('foo',function(e){
-        console.log('get foo result:'+JSON.stringify(e))
-        me.getItemResult = 'get foo,value is '+e.data+'\n'
-      })
-      storage.getItem('bar',function(e){
-        console.log('get bar result:'+JSON.stringify(e))
-        me.getItemResult += 'get bar,value is '+e.data
-      })
-
-      //length
-      storage.length(function(e){
-        console.log('length:'+JSON.stringify(e))
-        me.lengthResult = 'current length is ' + e.data
-      })
-
-      //getAllKeys
-      storage.getAllKeys(function(e){
-        console.log('getAllKeys:'+JSON.stringify(e))
-        me.getAllKeysResult = '' + e.data
-        //me.getAllKeysResult +=' '+ typeof e.data
-      })
-
-      //removeItem
-      storage.removeItem('foo',function(e){
-        console.log('remove foo:'+JSON.stringify(e))
-        me.removeItemResult = 'remove item foo '+e.result
-      })
-    }
-  }
-</script>
diff --git a/examples/vue/modules/stream.vue b/examples/vue/modules/stream.vue
deleted file mode 100644
index 0578ce7..0000000
--- a/examples/vue/modules/stream.vue
+++ /dev/null
@@ -1,170 +0,0 @@
-<template>
-  <scroller>
-    <panel title="stream.fetch" type="primary">
-      <panel title="method = GET">
-        <text>{{getResult}}</text>
-      </panel>
-      <panel title="method = GET / type = jsonp">
-        <text>{{getJsonpResult}}</text>
-      </panel>
-      <panel title="method = POST">
-        <text>{{postResult}}</text>
-      </panel>
-      <panel title="method = PUT">
-        <text>{{putResult}}</text>
-      </panel>
-      <panel title="method = DELETE">
-        <text>{{deleteResult}}</text>
-      </panel>
-      <panel title="method = HEAD">
-        <text>{{headResult}}</text>
-      </panel>
-      <panel title="method = PATCH">
-        <text>{{patchResult}}</text>
-      </panel>
-    </panel>
-  </scroller>
-</template>
-
-<script>
-  var stream = weex.requireModule('stream');
-  module.exports = {
-    data: function () {
-      return {
-        getJsonpResult: 'loading...',
-        getResult: 'loading...',
-        postResult: 'loading...',
-        putResult: 'loading...',
-        deleteResult: 'loading...',
-        headResult: 'loading...',
-        patchResult: 'loading...'
-      }
-    },
-    components: {
-      panel: require('../include/panel.vue')
-    },
-    created: function() {
-      var me = this;
-      var GET_URL_JSONP = 'http://jsfiddle.net/echo/jsonp/?callback=anything&result=content_in_response';
-      var GET_URL = 'http://httpbin.org/get';
-      var POST_URL = 'http://httpbin.org/post';
-      var PUT_URL = 'http://httpbin.org/put';
-      var DELETE_URL = 'http://httpbin.org/delete';
-      var HEAD_URL = 'http://httpbin.org/status/418';
-      var PATCH_URL = 'http://httpbin.org/patch';
-
-      stream.fetch({
-        method: 'GET',
-        url: GET_URL_JSONP,
-        type:'jsonp'
-      }, function(ret) {
-        if(!ret.ok){
-          me.getJsonpResult = "request failed";
-        }else{
-          console.log('get:'+ret);
-          me.getJsonpResult =  JSON.stringify(ret.data);
-        }
-      },function(response){
-        console.log('get jsonp in progress:'+response.length);
-        me.getJsonpResult = "bytes received:"+response.length;
-      });
-
-      stream.fetch({
-        method: 'GET',
-        url: GET_URL,
-        type:'json'
-      }, function(ret) {
-        if(!ret.ok){
-          me.getResult = "request failed";
-        }else{
-          console.log('get:'+ret);
-          me.getResult = JSON.stringify(ret.data);
-        }
-      },function(response){
-        console.log('get in progress:'+response.length);
-        me.getResult = "bytes received:"+response.length;
-      });
-
-      stream.fetch({
-        method: 'POST',
-        url: POST_URL,
-        type:'json'
-      }, function(ret) {
-        if(!ret.ok){
-          me.postResult = "request failed";
-        }else{
-          console.log('get:'+JSON.stringify(ret));
-          me.postResult = JSON.stringify(ret.data);
-        }
-      },function(response){
-        console.log('get in progress:'+response.length);
-        me.postResult = "bytes received:"+response.length;
-      });
-
-      stream.fetch({
-        method: 'PUT',
-        url: PUT_URL,
-        type:'json'
-      }, function(ret) {
-        if(!ret.ok){
-          me.putResult = "request failed";
-        }else{
-          console.log('get:'+JSON.stringify(ret));
-          me.putResult = JSON.stringify(ret.data);
-        }
-      },function(response){
-        console.log('get in progress:'+response.length);
-        me.putResult = "bytes received:"+response.length;
-      });
-
-      stream.fetch({
-        method: 'DELETE',
-        url: DELETE_URL,
-        type:'json'
-      }, function(ret) {
-
-        if(!ret.ok){
-          me.deleteResult = "request failed";
-        }else{
-          console.log('get:'+JSON.stringify(ret));
-          me.deleteResult = JSON.stringify(ret.data);
-        }
-      },function(response){
-        console.log('get in progress:'+response.length);
-        me.deleteResult = "bytes received:"+response.length;
-      });
-
-      stream.fetch({
-        method: 'HEAD',
-        url: HEAD_URL,
-        type:'json'
-      }, function(ret) {
-        if(ret.statusText !== 'I\'m a teapot'){
-          me.headResult = "request failed";
-        }else{
-          console.log('get:'+JSON.stringify(ret));
-          me.headResult = ret.statusText;
-        }
-      },function(response){
-        console.log('get in progress:'+response.length);
-        me.headResult = "bytes received:"+response.length;
-      });
-
-      stream.fetch({
-        method: 'PATCH',
-        url: PATCH_URL,
-        type:'json'
-      }, function(ret) {
-        if(!ret.ok){
-          me.patchResult = "request failed";
-        }else{
-          console.log('get:'+JSON.stringify(ret));
-          me.patchResult = JSON.stringify(ret.data);
-        }
-      },function(response){
-        console.log('get in progress:'+response.length);
-        me.patchResult = "bytes received:"+response.length;
-      });
-    }
-  };
-</script>
diff --git a/examples/vue/modules/websocket.vue b/examples/vue/modules/websocket.vue
deleted file mode 100644
index 2620677..0000000
--- a/examples/vue/modules/websocket.vue
+++ /dev/null
@@ -1,136 +0,0 @@
-<template>
-  <scroller>
-    <div>
-      <div style="background-color: #286090">
-        <text class="title" style="height: 80px ;padding: 20px;color: white">websocket</text>
-      </div>
-      <input type="text" placeholder="please input message to send" class="input" autofocus="false" value="" @input="oninput" ref="input" />
-      <div style="flex-direction: row; justify-content: center;">
-        <text class="button" @click="connect">connect</text>
-        <text class="button" @click="send">send</text>
-        <text class="button" @click="sendArrayBuffer">sendArrayBuffer</text>
-        <text class="button" @click="close">close</text>
-      </div>
-      <div style="background-color: lightgray">
-        <text class="title" style="height: 80px ;padding: 20px;color: black">method = close</text>
-      </div>
-      <text style="color: black;height: 80px">{{closeinfo}}</text>
-      <div style="background-color: lightgray">
-        <text class="title" style="height: 80px ;padding: 20px;color: black">method = send</text>
-      </div>
-      <text style="color: black;height: 80px">{{sendinfo}}</text>
-      <div style="background-color: lightgray">
-        <text class="title" style="height: 80px ;padding: 20px;color: black">method = onopen</text>
-      </div>
-      <text style="color: black;height: 80px">{{onopeninfo}}</text>
-      <div style="background-color: lightgray">
-        <text class="title" style="height: 80px ;padding: 20px;color: black">method = onmessage</text>
-      </div>
-      <text style="color: black;height: 400px">{{onmessage}}</text>
-      <div style="background-color: lightgray">
-        <text class="title" style="height: 80px ;padding: 20px;color: black">method = onclose</text>
-      </div>
-      <text style="color: black;height: 80px">{{oncloseinfo}}</text>
-      <div style="background-color: lightgray">
-        <text class="title" style="height: 80px ;padding: 20px;color: black">method = onerror</text>
-      </div>
-      <text style="color: black;height: 80px">{{onerrorinfo}}</text>
-    </div>
-  </scroller>
-</template>
-
-<style scoped>
-  .input {
-    font-size: 40px;
-    height: 80px;
-    width: 600px;
-  }
-  
-  .button {
-    font-size: 36px;
-    width: 150px;
-    color: #41B883;
-    text-align: center;
-    padding-top: 25px;
-    padding-bottom: 25px;
-    border-width: 2px;
-    border-style: solid;
-    margin-right: 20px;
-    border-color: rgb(162, 217, 192);
-    background-color: rgba(162, 217, 192, 0.2);
-  }
-</style>
-
-<script>
-  var websocket = weex.requireModule('webSocket')
-  export default {
-    data() {
-      return {
-        connectinfo: '',
-        sendinfo: '',
-        onopeninfo: '',
-        onmessage: '',
-        oncloseinfo: '',
-        onerrorinfo: '',
-        closeinfo: '',
-        txtInput: '',
-        navBarHeight: 88,
-        title: 'Navigator',
-        dir: 'examples',
-        baseURL: ''
-      }
-    },
-    methods: {
-
-      connect: function() {
-        websocket.WebSocket('ws://echo.websocket.org', '');
-        var self = this;
-        self.onopeninfo = 'connecting...'
-        websocket.onopen = function(e) {
-          self.onopeninfo = 'websocket open';
-        }
-        websocket.onmessage = function(e) {
-          console.log(typeof(e.data));
-          if(typeof(e.data) === 'string'){
-            self.onmessage = e.data;
-          }else
-          {
-            var str = 'receive array buffer show with string:' +  String.fromCharCode.apply(null, new Float32Array(e.data));
-            self.onmessage = str;
-          }
-        }
-        websocket.onerror = function(e) {
-          self.onerrorinfo = e.data;
-        }
-        websocket.onclose = function(e) {
-          self.onopeninfo = '';
-          self.oncloseinfo = e.code;
-        }
-      },
-      send: function(e) {
-        var input = this.$refs.input;
-        input.blur();
-        websocket.send(this.txtInput);
-        this.sendinfo = this.txtInput;
-      },
-      sendArrayBuffer: function(e) {
-        var input = this.$refs.input;
-        input.blur();
-        var buffer = new ArrayBuffer(16)
-        var view = new Float32Array(buffer)
-        view.set([4,89,36.9,0.765])
-        console.log(buffer);
-        var str = 'send array buffer show with string:' +  String.fromCharCode.apply(null, new Float32Array(buffer));
-        this.sendinfo = str;
-        websocket.send(buffer);
-      },
-      oninput: function(event) {
-        this.txtInput = event.value;
-      },
-      close: function(e) {
-        this.closeinfo = 'close connect';
-        websocket.close();
-      },
-    },
-  }
-</script>
\ No newline at end of file
diff --git a/examples/vue/showcase/a-node-click.vue b/examples/vue/showcase/a-node-click.vue
deleted file mode 100644
index 26d5282..0000000
--- a/examples/vue/showcase/a-node-click.vue
+++ /dev/null
@@ -1,74 +0,0 @@
-<template>
-  <list class="list">
-    <cell class="cell" @click="clickCell">
-      <xlink style="width: 400px;height: 400px;background-color: yellow;" target="_blank" :href = "url">
-        <div class="ct"  @click="click">
-          <text>CLICK ME</text>
-        </div>
-      </xlink>
-    </cell>
-  </list>
-</template>
-
-<style scoped>
-.list {
-  height: 2000px;
-}
-.cell {
-  height: 400px;
-  background-color: blue;
-}
-.txt {
-  font-size: 64px;
-  height: 84px;
-  line-height: 84px;
-  padding: 10px;
-}
-.ct {
-  width: 200px;
-  height: 200px;
-  background-color: #fff;
-}
-</style>
-
-<script>
-export default {
-  data () {
-    return {
-      // url: '//m.taobao.com'
-      url: '#'
-    }
-  },
-  components: {
-    xlink: {
-      props: {
-        href: String
-      },
-      render (createElement) {
-        return createElement('a', {
-          ref: 'link',
-          attrs: {
-            'component-name': 'link',
-            'href': this.href
-          }
-        }, this.$slots.default)
-      }
-    }
-  },
-  methods: {
-    click (evt) {
-      evt.preventDefault()
-      // var d = Date.now()
-      // while (true) {
-      //   var now = Date.now()
-      //   if (now - d > 2000) { break }
-      // }
-      // throw new Error('test')
-      console.log('click on inner')
-    },
-    clickCell (evt) {
-      console.log('click on cell')
-    }
-  }
-}
-</script>
\ No newline at end of file
diff --git a/examples/vue/showcase/boxshadow.vue b/examples/vue/showcase/boxshadow.vue
deleted file mode 100644
index d656b23..0000000
--- a/examples/vue/showcase/boxshadow.vue
+++ /dev/null
@@ -1,39 +0,0 @@
-
-<template>
-    <div class="wrapper">
-        <div style="width:400px; height:60px;background-color: #FFE4C4; box-shadow:20px  10px rgb(255, 69, 0);">
-            <text class="title" style="text-align: center">Hello {{target}}</text>
-        </div>
-        <div style="margin-top: 80px;width:400px; height:60px;background-color: #FFE4C4; box-shadow: 20px  10px 5px rgba(255, 69, 0, 0.8);">
-            <text class="title" style="text-align: center">Hello {{target}}</text>
-        </div>
-        <div style="margin-top: 80px;width:400px; height:60px;background-color: #FFE4C4; box-shadow:inset 20px  10px 5px rgba(255, 69, 0, 0.8);">
-            <text class="title" style="text-align: center">Hello {{target}}</text>
-        </div>
-        <div style="margin-top: 80px;width:400px; height:60px;background-color: #FFE4C4; box-shadow:inset 20px  10px 5px rgb(255, 69, 0);">
-            <text class="title" style="text-align: center">Hello {{target}}</text>
-        </div>
-        <div style="margin-top: 80px;width:400px; height:60px;background-color: #FFE4C4; box-shadow:20px  10px 5px black;">
-            <text class="title" style="text-align: center">Hello {{target}}</text>
-        </div>
-        <div style="margin-top: 80px;width:400px; height:60px;background-color: #FFE4C4; box-shadow:20px  10px 5px #008B00;">
-            <text class="title" style="text-align: center">Hello {{target}}</text>
-        </div>
-    </div>
-</template>
-
-<style scoped>
-    .wrapper {align-items: center; margin-top: 120px;}
-    .title {font-size: 48px;}
-</style>
-
-<script>
-    module.exports = {
-        data: function () {
-            return {
-                logoUrl: 'https://alibaba.github.io/weex/img/weex_logo_blue@3x.png',
-                target: 'World'
-            };
-        }
-    };
-</script>
diff --git a/examples/vue/showcase/calculator.vue b/examples/vue/showcase/calculator.vue
deleted file mode 100644
index d945077..0000000
--- a/examples/vue/showcase/calculator.vue
+++ /dev/null
@@ -1,104 +0,0 @@
-<template>
-  <div style="padding: 5px;">
-    <text class="result">{{result}}</text>
-    <div class="row">
-      <text class="btn" @click="input">1</text>
-      <text class="btn" @click="input">2</text>
-      <text class="btn" @click="input">3</text>
-      <text class="btn btn-operator" @click="input">+</text>
-    </div>
-    <div class="row">
-      <text class="btn" @click="input">4</text>
-      <text class="btn" @click="input">5</text>
-      <text class="btn" @click="input">6</text>
-      <text class="btn btn-operator" @click="input">-</text>
-    </div>
-    <div class="row">
-      <text class="btn" @click="input">7</text>
-      <text class="btn" @click="input">8</text>
-      <text class="btn" @click="input">9</text>
-      <text class="btn btn-operator" @click="input">*</text>
-    </div>
-    <div class="row">
-      <text class="btn" @click="input">0</text>
-      <text class="btn" @click="input">.</text>
-      <text class="btn" @click="clear">AC</text>
-      <text class="btn btn-operator" @click="calculate">=</text>
-    </div>
-  </div>
-</template>
-
-<style scoped>
-  .row {
-    flex-direction: row;
-  }
-
-  .result {
-    text-align: right;
-    background-color: #666;
-    font-size: 40px;
-    color: white;
-  }
-
-  .btn {
-    flex: 1;
-    text-align: center;
-    background-color: #eee;
-    font-size: 36px;
-  }
-
-  .btn, .result {
-    height: 100px;
-    padding: 30px;
-    margin: 5px;
-  }
-
-  .btn-operator {
-    background-color: #669;
-    font-size: 40px;
-    color: white;
-  }
-</style>
-
-<script>
-  var OP = ['+', '-', '*', '/'];
-  var modal = weex.requireModule('modal')
-  module.exports = {
-    data: function () {
-      return {
-        result: '',
-        inputs: []
-      }
-    },
-    methods: {
-      input: function(e) {
-        modal.toast({ message: 'input: ' + e.target.attr.value, duration: 1 })
-        var value = e.target.attr['value'];
-        var inputs = this.inputs;
-        var lastOne = inputs.length ? inputs[inputs.length - 1] : '';
-        if (OP.indexOf(lastOne) > -1 && OP.indexOf(value) > -1) {
-          return;
-        }
-        inputs.push(value);
-        var buf = [], char;
-        for (var i = 0; i < inputs.length; i++) {
-          char = inputs[i];
-          if (OP.indexOf(char) > -1) {
-            char = ' ' + char + ' ';
-          }
-          buf.push(char);
-        }
-        this.result = buf.join('');
-      },
-      calculate: function() {
-        var result = eval(this.result);
-        this.inputs = [result];
-        this.result = result;
-      },
-      clear: function() {
-        this.inputs = [];
-        this.result = '';
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/showcase/compositing.vue b/examples/vue/showcase/compositing.vue
deleted file mode 100644
index 58e238f..0000000
--- a/examples/vue/showcase/compositing.vue
+++ /dev/null
@@ -1,89 +0,0 @@
-
-<template>
-  <div class="wrapper" @click="update" >
-    <div class="item" compositing=true>
-      <div class="itemWrapper">
-        <div class="nameWrapper">
-          <text class="itemName">Thomas Carlyle</text>
-        </div>
-        <image class="itemPhoto" src="https://gw.alicdn.com/tps/TB1Jl1CPFXXXXcJXXXXXXXXXXXX-370-370.jpg"></image>
-        <div class="descWrapper">
-          <text class="itemDesc">Genius only means hard-working all one\'s life</text>
-        </div>
-      </div>
-    </div>
-
-    <div class="item" compositing=false>
-      <div class="itemWrapper">
-        <div class="nameWrapper">
-          <text class="itemName">Thomas Carlyle</text>
-        </div>
-        <image class="itemPhoto" src="https://gw.alicdn.com/tps/TB1Jl1CPFXXXXcJXXXXXXXXXXXX-370-370.jpg"></image>
-        <div class="descWrapper">
-          <text class="itemDesc">Genius only means hard-working all one\'s life</text>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<style>
-  .wrapper {
-    align-items: center; 
-    opacity: 0.8;
-  }
-  .itemWrapper {
-    flex:1;
-    border-top-right-radius: 80;
-    border-bottom-right-radius: 80;
-    border-top-width: 10;
-    border-top-color: red;
-    border-style: dashed;
-    align-items: center;
-    background-color: white;
-  }
-  .nameWrapper {
-    background-color:rgba(255,0,0,0.5);
-    border-radius: 30;
-    overflow: visible;
-    border-color: black;
-    border-width: 10;
-  }
-  .item {
-    margin-top: 120px; 
-    background-color: #CCCCCC;
-    align-items: center;
-  }
-  .itemName {
-    font-size:28;
-    color:#333333;
-    line-height:42;
-    text-align:left;
-    margin-top: 24;
-  }
-  .itemPhoto {
-    margin-top: 18;
-    width: 220;
-    height: 220;
-    margin-bottom: 18;
-    border-radius: 30;
-    overflow: hidden;
-    background-color: blue;
-  }
-  .itemDesc {
-    font-size:24;
-    margin:12;
-    color:#999999;
-    line-height:36;
-    text-align:left;
-  }
-</style>
-
-<script>
-  module.exports = {
-    data: {
-    },
-    methods: {
-    }
-  }
-</script>
diff --git a/examples/vue/showcase/gesture.vue b/examples/vue/showcase/gesture.vue
deleted file mode 100644
index 75759f3..0000000
--- a/examples/vue/showcase/gesture.vue
+++ /dev/null
@@ -1,57 +0,0 @@
-<template>
-  <div>
-    <div class="ct"
-      @longpress="handlePress"
-      @swipe="handleSwipe"
-      @panstart="handlePanStart"
-      @panmove="handlePanMove"
-      @panend="handlePanEnd"
-      :style="{ top: top, left: left }">
-        <text>{{text}}</text>
-    </div>
-  </div>
-</template>
-
-<style scoped>
-.ct {
-  position: absolute;
-  width: 750px;
-  height: 1000px;
-  background-color: #f7f7f7;
-}
-</style>
-
-<script>
-  module.exports = {
-    data: function () {
-      return {
-        text: 'no press.',
-        top: '0px',
-        left: '0px',
-        flag: false,
-      }
-    },
-    methods: {
-      handlePress: function(e) {
-        this.text = '->longpress(' + e.touch.pageX + ',' + e.touch.pageY + ')id:'+ e.touch.identifier
-      },
-      handleSwipe: function(e) {
-        this.text += '->swipe(' + e.touch.pageX + ',' + e.touch.pageY + ')id:'+ e.touch.identifier
-      },
-      handlePanStart: function(e) {
-        this.flag = false
-        this.text = '->panstart(' + e.touch.pageX + ',' + e.touch.pageY + ')id:'+ e.touch.identifier
-      },
-      handlePanMove: function(e) {
-        if (this.flag) {
-          return
-        }
-        this.flag = true
-        this.text += '->panmove(' + e.touch.pageX + ',' + e.touch.pageY + ')id:'+ e.touch.identifier
-      },
-      handlePanEnd: function(e) {
-        this.text += '->panend(' + e.touch.pageX + ',' + e.touch.pageY + ')id:'+ e.touch.identifier
-      }
-    }
-  }
-</script>
\ No newline at end of file
diff --git a/examples/vue/showcase/include/banner.vue b/examples/vue/showcase/include/banner.vue
deleted file mode 100644
index 1d814cc..0000000
--- a/examples/vue/showcase/include/banner.vue
+++ /dev/null
@@ -1,23 +0,0 @@
-<template>
-  <image :style="{ width: width, height: height }" :src="src" :image-quality="quality"
-    @click="clickHandler"></image>
-</template>
-<script>
-  var modal = weex.requireModule('modal')
-  module.exports = {
-    props: ['width', 'height', 'src', 'href'],
-    data: function () {
-      return {
-        quality: 'normal'
-      }
-    },
-    methods: {
-      clickHandler: function () {
-        modal.toast({
-          message: 'click',
-          duration: 1
-        });
-      }
-    }
-  };
-</script>
diff --git a/examples/vue/showcase/include/banners.vue b/examples/vue/showcase/include/banners.vue
deleted file mode 100644
index 911c54c..0000000
--- a/examples/vue/showcase/include/banners.vue
+++ /dev/null
@@ -1,22 +0,0 @@
-<template>
-  <div>
-    <div v-if="direction==='row'" style="flex-direction:row">
-      <div v-for="(item,i) in ds" :key="i" :style="{ width: width, height: height, marginLeft: (i % ds.length ? space : 0) }">
-        <banner :width="width" :height="height" :src="item.img" :href="item.url"></banner>
-      </div>
-    </div>
-    <div v-if="direction==='column'">
-      <div v-for="(item,i) in ds" :key="i" :style="{ width: width, height: height, marginTop: (i % ds.length ? space : 0) }">
-        <banner :width="width" :height="height" :src="item.img" :href="item.url"></banner>
-      </div>
-    </div>
-  </div>
-</template>
-<script>
-  module.exports = {
-    components: {
-      banner: require('./banner.vue')
-    },
-    props: ['ds', 'width', 'height', 'space', 'direction']
-  };
-</script>
diff --git a/examples/vue/showcase/include/brand.vue b/examples/vue/showcase/include/brand.vue
deleted file mode 100644
index f884e48..0000000
--- a/examples/vue/showcase/include/brand.vue
+++ /dev/null
@@ -1,63 +0,0 @@
-<template>
-  <div class="container">
-    <image v-if="ds.floorTitle" class="title" :src="ds.floorTitle"></image>
-    <div style="margin-left:4;margin-right:4">
-      <banners direction="column" :ds="bannerItems" :width="NUMBER_742" :height="NUMBER_230" :space="NUMBER_4"></banners>
-    </div>
-  </div>
-</template>
-<style scoped>
-  .title {
-    width: 750;
-    height: 100;
-  }
-
-  .container {
-    margin-bottom: 4;
-    background-color:#C0BABC;
-  }
-</style>
-<script>
-  module.exports = {
-    components: {
-      banners: require('./banners.vue')
-    },
-    props: {
-      ds: {
-        default: function () {
-          return {
-            bannerItems: []
-          }
-        }
-      }
-    },
-    data: function () {
-      return {
-        NUMBER_742: 742,
-        NUMBER_230: 230,
-        NUMBER_4: 4
-      }
-    },
-    computed: {
-      bannerItems: function () {
-        return this.ds.bannerItems.slice(0,8);
-      }
-    },
-    created: function () {
-      var bannerItems = this.ds.bannerItems
-      bannerItems.sort(function(){
-        return Math.random()-0.5;
-      });
-      for(var i=0;i<bannerItems.length;i++){
-        var item =  bannerItems[i];
-        if(i%2===0){
-          item.img = item.leftImg;
-          item.url = item.rightUrl;
-        }else{
-          item.img = item.rightImg;
-          item.url = item.rightUrl;
-        }
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/showcase/include/category.vue b/examples/vue/showcase/include/category.vue
deleted file mode 100644
index 4f16772..0000000
--- a/examples/vue/showcase/include/category.vue
+++ /dev/null
@@ -1,513 +0,0 @@
-<template>
-  <div>
-    <image v-if="ds.floorTitle" class="title" :src="ds.floorTitle"></image>
-    <div class="item-container">
-      <div v-for="(item,i) in items" :key="i" :style="{ width: 750, paddingBottom: 14, backgroundColor: item.colour }">
-        <div>
-          <banner :width="NUMBER_750" :height="NUMBER_237"
-            :src="i % 2 === 0 ? item.leftBannerImg : item.rightBannerImg"
-            :href="item.bannerUrl"></banner>
-        </div>
-        <div class="shop-list">
-          <div v-for="(i, shop) in item.shopList" :key="i" class="shop-img-container">
-            <banner :width="NUMBER_186" :height="NUMBER_208" :src="shop.picUrl" :href="shop.shopUrl"></banner>
-          </div>
-        </div>
-      </div>
-    </div>
-    <div class="sub-item-container" :style="{ height: Math.round(subItems.length / 3) * (241 + 3) }">
-      <div v-for="(item,i) in subItems" :key="i" class="sub-item" :style="{top: getSubItemTop(i), left: getSubItemLeft(i) }">
-        <image class="sub-item-bg" :src="subItemBg"></image>
-        <div class="sub-item-img">
-          <banner :width="NUMBER_248" :height="NUMBER_155"
-            :src="item.industryImg"
-            :href="item.industryUrl"></banner>
-        </div>
-        <div class="sub-item-title">
-          <text class="industry-title" :href="item.industryUrl">{{item.industryTitle}}</text>
-          <text class="industry-benefit" :href="item.industryUrl">{{item.industryBenefit}}</text>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<style scoped>
-  .title {
-    width: 750;
-    height: 100;
-  }
-
-  .shop-list {
-    flex-direction: row;
-  }
-
-  .shop-img-container {
-    margin-right: 2;
-  }
-
-  .sub-item {
-    position: absolute;
-    width: 248;
-    height: 241;
-    align-items: center;
-    background-color:#ffffff;
-  }
-
-  .sub-item-bg {
-    width: 248;
-    height: 86;
-  }
-
-  .sub-item-title {
-    position: absolute;
-    left: 0;
-    top: 0;
-    width: 248;
-    text-align: center;
-  }
-
-  .industry-title {
-    font-size: 28;
-    color: #484848;
-    text-align: center;
-    margin-top: 10;
-    height:34;
-  }
-
-  .industry-benefit {
-    font-size: 24;
-    color: #999999;
-    text-align: center;
-  }
-</style>
-
-<script>
-  var demoContent = {
-    "main": [{
-      "shopList": [{
-        "id": "619123122",
-        "picUrl": "//img.alicdn.com/tps/i1/TB1Cl5MLVXXXXXTaXXXSutbFXXX.jpg",
-        "finalScore": "0.884765209440857",
-        "shopUrl": "http://liangpinpuzi.tmall.com/campaign-3735-7.htm",
-        "entityType": "SHOP",
-        "brandId": "7724367"
-      }, {
-        "id": "880734502",
-        "picUrl": "//img.alicdn.com/tps/i1/TB1HN2XLVXXXXbkXFXXSutbFXXX.jpg",
-        "finalScore": "0.8822246866512714",
-        "shopUrl": "http://sanzhisongshu.tmall.com/campaign-3735-7.htm",
-        "entityType": "SHOP",
-        "brandId": "147280915"
-      }, {
-        "id": "392147177",
-        "picUrl": "//img.alicdn.com/tps/i1/TB1yq6dLVXXXXbXXpXXSutbFXXX.jpg",
-        "finalScore": "0.8805854724243631",
-        "shopUrl": "http://zhouheiya.tmall.com/campaign-3735-6.htm",
-        "entityType": "SHOP",
-        "brandId": "111496"
-      }, {
-        "id": "2081058060",
-        "picUrl": "//img.alicdn.com/tps/i1/TB1w4jxLVXXXXaxXXXXtKXbFXXX.gif",
-        "finalScore": "0.8640439551049249",
-        "shopUrl": "http://rongxintang.tmall.com/campaign-3735-6.htm",
-        "entityType": "SHOP",
-        "brandId": "8709890"
-      }],
-      "finalScore": "4.657333333333334",
-      "industryUrl": null,
-      "entityType": "OTHER",
-      "colour": "#fff5a3",
-      "industryTitle": null,
-      "bannerUrl": "//pages.tmall.com/wow/act/15617/newfood?abbucket=_AB-M1011_B14&acm=03654.1003.1.735362&aldid=KXPpnvEH&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.OTHER_12_735362&pos=1",
-      "leftBannerImg": "http://img.alicdn.com/tps/i1/TB1LHh4MXXXXXbsXpXXeWjm2pXX-750-240.jpg",
-      "_pos_": "1",
-      "industryBenefit": null,
-      "industryId": "12",
-      "industryImg": null,
-      "rightBannerImg": "//img.alicdn.com/tps/i4/TB1wshUMXXXXXXaXVXXeWjm2pXX-750-240.jpg"
-    }, {
-      "shopList": [{
-        "id": "520557274",
-        "picUrl": "//img.alicdn.com/tps/i1/TB1aMjXLVXXXXbUaXXXSutbFXXX.jpg",
-        "finalScore": "0.8986382989845325",
-        "shopUrl": "http://newbalance.tmall.com/campaign-3735-20.htm",
-        "entityType": "SHOP",
-        "brandId": "20584"
-      }, {
-        "id": "746866993",
-        "picUrl": "//img.alicdn.com/tps/i1/TB1pXG9LVXXXXaLXFXXSutbFXXX.jpg",
-        "finalScore": "0.8917855242977327",
-        "shopUrl": "http://vans.tmall.com/campaign-3735-19.htm",
-        "entityType": "SHOP",
-        "brandId": "29529"
-      }, {
-        "id": "1612713147",
-        "picUrl": "//img.alicdn.com/tps/i1/TB1jHfXLVXXXXXPXFXXSutbFXXX.jpg",
-        "finalScore": "0.8895943606442631",
-        "shopUrl": "http://dcshoecousa.tmall.com/campaign-3735-8.htm",
-        "entityType": "SHOP",
-        "brandId": "3851662"
-      }, {
-        "id": "2379251418",
-        "picUrl": "//img.alicdn.com/tps/i1/TB1sbLlLVXXXXbeXXXXSutbFXXX.jpg",
-        "finalScore": "0.8881539668874383",
-        "shopUrl": "http://baijinydhw.tmall.com/campaign-3735-2.htm",
-        "entityType": "SHOP",
-        "brandId": "20579"
-      }],
-      "finalScore": "4.545333333333334",
-      "industryUrl": null,
-      "entityType": "OTHER",
-      "colour": "#cbdbfe",
-      "industryTitle": null,
-      "bannerUrl": "//pages.tmall.com/wow/act/15617/ydhw?abbucket=_AB-M1011_B14&acm=03654.1003.1.735362&aldid=KXPpnvEH&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.OTHER_8_735362&pos=2",
-      "leftBannerImg": "http://img.alicdn.com/tps/i3/TB1h4kzLVXXXXawXpXXeWjm2pXX-750-240.jpg",
-      "_pos_": "2",
-      "industryBenefit": null,
-      "industryId": "8",
-      "industryImg": null,
-      "rightBannerImg": "//img.alicdn.com/tps/i4/TB19VMjLVXXXXaeaXXXeWjm2pXX-750-240.jpg"
-    }, {
-      "shopList": [{
-        "id": "811383091",
-        "picUrl": "//img.alicdn.com/tps/i1/TB1q49ZLVXXXXaJXVXXSutbFXXX.jpg",
-        "finalScore": "0.8723682716749482",
-        "shopUrl": "http://tongrentangbj.tmall.com/campaign-3735-9.htm",
-        "entityType": "SHOP",
-        "brandId": "44652"
-      }, {
-        "id": "838914626",
-        "picUrl": "//img.alicdn.com/tps/i1/TB1GQYbLVXXXXaXXVXXSutbFXXX.jpg",
-        "finalScore": "0.5027131908086584",
-        "shopUrl": "http://jouo.tmall.com/campaign-3735-3.htm",
-        "entityType": "SHOP",
-        "brandId": "14170081"
-      }, {
-        "id": "1077716829",
-        "picUrl": "//img.alicdn.com/tps/i1/TB1rdW2LVXXXXagapXXSutbFXXX.jpg",
-        "finalScore": "0.5015387557024262",
-        "shopUrl": "http://wetcode.tmall.com/campaign-3735-14.htm",
-        "entityType": "SHOP",
-        "brandId": "3675642"
-      }, {
-        "id": "1664976033",
-        "picUrl": "//img.alicdn.com/tps/i1/TB1Q.rpLVXXXXXiXpXXSutbFXXX.jpg",
-        "finalScore": "0.5014897109669442",
-        "shopUrl": "http://hanhoohzp.tmall.com/campaign-3735-17.htm",
-        "entityType": "SHOP",
-        "brandId": "78888695"
-      }],
-      "finalScore": "4.526666666666666",
-      "industryUrl": null,
-      "entityType": "OTHER",
-      "colour": "#ffd1b6",
-      "industryTitle": null,
-      "bannerUrl": "//pages.tmall.com/wow/act/15617/getbeauty?abbucket=_AB-M1011_B14&acm=03654.1003.1.735362&aldid=KXPpnvEH&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.OTHER_2_735362&pos=3",
-      "leftBannerImg": "http://img.alicdn.com/tps/i4/TB1Djt9MXXXXXanXXXXeWjm2pXX-750-240.jpg",
-      "_pos_": "3",
-      "industryBenefit": null,
-      "industryId": "2",
-      "industryImg": null,
-      "rightBannerImg": "//img.alicdn.com/tps/i3/TB1_gVQMXXXXXX9XVXXeWjm2pXX-750-240.jpg"
-    }, {
-      "shopList": [{
-        "id": "2153169655",
-        "picUrl": "//img.alicdn.com/tps/i1/TB1nlK7LVXXXXaRXFXXSutbFXXX.jpg",
-        "finalScore": "0.8820210808835905",
-        "shopUrl": "http://ctkicks.tmall.com/campaign-3735-15.htm",
-        "entityType": "SHOP",
-        "brandId": "20584"
-      }, {
-        "id": "2784101115",
-        "picUrl": "//img.alicdn.com/tps/i1/TB1RrS.LVXXXXcrXpXXSutbFXXX.jpg",
-        "finalScore": "0.5930383227012586",
-        "shopUrl": "http://tomtailor.tmall.com/campaign-3735-0.htm",
-        "entityType": "SHOP",
-        "brandId": "213474060"
-      }, {
-        "id": "2183813726",
-        "picUrl": "//img.alicdn.com/tps/i1/TB1kmS_LVXXXXaBaXXXSutbFXXX.jpg",
-        "finalScore": "0.5882558957771681",
-        "shopUrl": "http://huaiyuan.tmall.com/campaign-3735-5.htm",
-        "entityType": "SHOP",
-        "brandId": "29465"
-      }, {
-        "id": "1785908005",
-        "picUrl": "//img.alicdn.com/tps/i1/TB1dB6zLVXXXXcJXXXXSutbFXXX.jpg",
-        "finalScore": "0.5694211862124341",
-        "shopUrl": "http://axonus.tmall.com/campaign-3735-1.htm",
-        "entityType": "SHOP",
-        "brandId": "115035841"
-      }],
-      "finalScore": "4.413955555555555",
-      "industryUrl": null,
-      "entityType": "OTHER",
-      "colour": "#b9eaf2",
-      "industryTitle": null,
-      "bannerUrl": "//pages.tmall.com/wow/act/15617/guojixfs?abbucket=_AB-M1011_B14&acm=03654.1003.1.735362&aldid=KXPpnvEH&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.OTHER_1_735362&pos=4",
-      "leftBannerImg": "http://img.alicdn.com/tps/i3/TB1_T7ALVXXXXXOXXXXeWjm2pXX-750-240.jpg",
-      "_pos_": "4",
-      "industryBenefit": null,
-      "industryId": "1",
-      "industryImg": null,
-      "rightBannerImg": "//img.alicdn.com/tps/i2/TB1s7koLVXXXXafXFXXeWjm2pXX-750-240.jpg"
-    }, {
-      "shopList": [{
-        "id": "2453054335",
-        "picUrl": "//img.alicdn.com/tps/i1/TB1RX_vLVXXXXchXpXXSutbFXXX.jpg",
-        "finalScore": "0.8463447899590267",
-        "shopUrl": "http://nanshizixing.tmall.com/campaign-3735-2.htm",
-        "entityType": "SHOP",
-        "brandId": "844502560"
-      }, {
-        "id": "1041773234",
-        "picUrl": "//img.alicdn.com/tps/i1/TB1Q7jpLVXXXXX8XpXXSutbFXXX.jpg",
-        "finalScore": "0.560952734503075",
-        "shopUrl": "http://dapu.tmall.com/campaign-3735-8.htm",
-        "entityType": "SHOP",
-        "brandId": "14493763"
-      }, {
-        "id": "300031438",
-        "picUrl": "//img.alicdn.com/tps/i1/TB13VC4LVXXXXarXVXXSutbFXXX.jpg",
-        "finalScore": "0.5450674634839442",
-        "shopUrl": "http://kangerxin.tmall.com/campaign-3735-10.htm",
-        "entityType": "SHOP",
-        "brandId": "3781905"
-      }, {
-        "id": "92042735",
-        "picUrl": "//img.alicdn.com/tps/i1/TB1PxYcLVXXXXasaXXXSutbFXXX.jpg",
-        "finalScore": "0.5448023228053981",
-        "shopUrl": "http://shuixing.tmall.com/campaign-3735-10.htm",
-        "entityType": "SHOP",
-        "brandId": "3685660"
-      }],
-      "finalScore": "4.13",
-      "industryUrl": null,
-      "entityType": "OTHER",
-      "colour": "#bbffe5",
-      "industryTitle": null,
-      "bannerUrl": "//pages.tmall.com/wow/act/15617/jfjs?abbucket=_AB-M1011_B14&acm=03654.1003.1.735362&aldid=KXPpnvEH&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.OTHER_4_735362&pos=5",
-      "leftBannerImg": "http://img.alicdn.com/tps/i3/TB1jeoCLVXXXXcoXXXXeWjm2pXX-750-240.jpg",
-      "_pos_": "5",
-      "industryBenefit": null,
-      "industryId": "4",
-      "industryImg": null,
-      "rightBannerImg": "//img.alicdn.com/tps/i4/TB1C5.fLVXXXXb3aXXXeWjm2pXX-750-240.jpg"
-    }, {
-      "shopList": [{
-        "id": "822428555",
-        "picUrl": "//img.alicdn.com/tps/i1/TB1g46aLVXXXXcUXVXXSutbFXXX.jpg",
-        "finalScore": "0.9183458776971917",
-        "shopUrl": "http://playboyyd.tmall.com/campaign-3735-11.htm",
-        "entityType": "SHOP",
-        "brandId": "29510"
-      }, {
-        "id": "196993935",
-        "picUrl": "//img.alicdn.com/tps/i1/TB1pHG8LVXXXXbraXXXSutbFXXX.jpg",
-        "finalScore": "0.9105525246667775",
-        "shopUrl": "https://uniqlo.tmall.com/campaign-3735-56.htm",
-        "entityType": "SHOP",
-        "brandId": "29527"
-      }, {
-        "id": "505753958",
-        "picUrl": "//img.alicdn.com/tps/i1/TB1WKYyLVXXXXXHXXXXSutbFXXX.jpg",
-        "finalScore": "0.90750966370726",
-        "shopUrl": "http://bonas.tmall.com/campaign-3735-11.htm",
-        "entityType": "SHOP",
-        "brandId": "3486580"
-      }, {
-        "id": "2113823580",
-        "picUrl": "//img.alicdn.com/tps/i1/TB1itHkLVXXXXX9XFXXSutbFXXX.jpg",
-        "finalScore": "0.5900977955635289",
-        "shopUrl": "http://kafanya.tmall.com/campaign-3735-7.htm",
-        "entityType": "SHOP",
-        "brandId": "110684218"
-      }],
-      "finalScore": "4.088",
-      "industryUrl": null,
-      "entityType": "OTHER",
-      "colour": "#ffc7c9",
-      "industryTitle": null,
-      "bannerUrl": "//pages.tmall.com/wow/act/15617/neiyi328?abbucket=_AB-M1011_B14&acm=03654.1003.1.735362&aldid=KXPpnvEH&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.OTHER_9_735362&pos=6",
-      "leftBannerImg": "http://img.alicdn.com/tps/i1/TB1tl3tLVXXXXbbXFXXeWjm2pXX-750-240.jpg",
-      "_pos_": "6",
-      "industryBenefit": null,
-      "industryId": "9",
-      "industryImg": null,
-      "rightBannerImg": "//img.alicdn.com/tps/i2/TB1AkIyLVXXXXbjXpXXeWjm2pXX-750-240.jpg"
-    }],
-    "sub": [{
-      "shopList": null,
-      "finalScore": "4.033333333333333",
-      "industryUrl": "//pages.tmall.com/wow/act/15617/zbps?abbucket=_AB-M1011_B14&acm=03654.1003.1.735362&aldid=KXPpnvEH&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.OTHER_3_735362&pos=7",
-      "entityType": "OTHER",
-      "colour": "#bbffe5",
-      "industryTitle": "珠宝配饰",
-      "bannerUrl": null,
-      "leftBannerImg": null,
-      "_pos_": "7",
-      "industryBenefit": "大牌1折秒杀",
-      "industryId": "3",
-      "industryImg": "//img.alicdn.com/tps/i1/TB1s5y.LVXXXXb.aXXXrdvGIFXX-248-155.jpg",
-      "rightBannerImg": null
-    }, {
-      "shopList": null,
-      "finalScore": "3.8773333333333335",
-      "industryUrl": "//pages.tmall.com/wow/act/15617/dqc?abbucket=_AB-M1011_B14&acm=03654.1003.1.735362&aldid=KXPpnvEH&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.OTHER_15_735362&pos=8",
-      "entityType": "OTHER",
-      "colour": "#b4ebff",
-      "industryTitle": "数码",
-      "bannerUrl": null,
-      "leftBannerImg": null,
-      "_pos_": "8",
-      "industryBenefit": "疯抢大牌新品",
-      "industryId": "15",
-      "industryImg": "//img.alicdn.com/tps/i4/TB1_xG.LVXXXXbWaXXXrdvGIFXX-248-155.jpg",
-      "rightBannerImg": null
-    }, {
-      "shopList": null,
-      "finalScore": "3.8359999999999994",
-      "industryUrl": "//pages.tmall.com/wow/act/15617/man?abbucket=_AB-M1011_B14&acm=03654.1003.1.735362&aldid=KXPpnvEH&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.OTHER_6_735362&pos=9",
-      "entityType": "OTHER",
-      "colour": "#cbe9a9",
-      "industryTitle": "男装",
-      "bannerUrl": null,
-      "leftBannerImg": null,
-      "_pos_": "9",
-      "industryBenefit": "新品低至9.9元",
-      "industryId": "6",
-      "industryImg": "//img.alicdn.com/tps/i1/TB1mO2qLVXXXXXiXFXXrdvGIFXX-248-155.jpg",
-      "rightBannerImg": null
-    }, {
-      "shopList": null,
-      "finalScore": "3.243333333333333",
-      "industryUrl": "//pages.tmall.com/wow/act/15617/xihu?abbucket=_AB-M1011_B14&acm=03654.1003.1.735362&aldid=KXPpnvEH&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.OTHER_13_735362&pos=10",
-      "entityType": "OTHER",
-      "colour": "#cdffa4",
-      "industryTitle": "洗护",
-      "bannerUrl": null,
-      "leftBannerImg": null,
-      "_pos_": "10",
-      "industryBenefit": "爆款1分钱抢",
-      "industryId": "13",
-      "industryImg": "//img.alicdn.com/tps/i3/TB1Ft_CLVXXXXX2XXXXrdvGIFXX-248-155.jpg",
-      "rightBannerImg": null
-    }, {
-      "shopList": null,
-      "finalScore": "3.1553333333333335",
-      "industryUrl": "//pages.tmall.com/wow/act/15617/myxfs?abbucket=_AB-M1011_B14&acm=03654.1003.1.735362&aldid=KXPpnvEH&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.OTHER_5_735362&pos=11",
-      "entityType": "OTHER",
-      "colour": "#f8e1ff",
-      "industryTitle": "母婴童装",
-      "bannerUrl": null,
-      "leftBannerImg": null,
-      "_pos_": "11",
-      "industryBenefit": "跨店满299减40",
-      "industryId": "5",
-      "industryImg": "//img.alicdn.com/tps/i4/TB1c.HvLVXXXXXPXpXXrdvGIFXX-248-155.jpg",
-      "rightBannerImg": null
-    }, {
-      "shopList": null,
-      "finalScore": "2.6739999999999995",
-      "industryUrl": "//pages.tmall.com/wow/act/15617/nvzhuang?abbucket=_AB-M1011_B14&acm=03654.1003.1.735362&aldid=KXPpnvEH&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.OTHER_7_735362&pos=12",
-      "entityType": "OTHER",
-      "colour": "#d5cbe8",
-      "industryTitle": "女装",
-      "bannerUrl": null,
-      "leftBannerImg": null,
-      "_pos_": "12",
-      "industryBenefit": "折后用券抢新",
-      "industryId": "7",
-      "industryImg": "//img.alicdn.com/tps/i3/TB1JdfsLVXXXXbRXpXXrdvGIFXX-248-155.jpg",
-      "rightBannerImg": null
-    }, {
-      "shopList": null,
-      "finalScore": "0.0",
-      "industryUrl": "//pages.tmall.com/wow/act/15617/mobilephone?abbucket=_AB-M1011_B14&acm=03654.1003.1.735362&aldid=KXPpnvEH&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.OTHER_14_735362&pos=13",
-      "entityType": "OTHER",
-      "colour": "#c5ffdf",
-      "industryTitle": "手机",
-      "bannerUrl": null,
-      "leftBannerImg": null,
-      "_pos_": "13",
-      "industryBenefit": "1元抢优惠券",
-      "industryId": "14",
-      "industryImg": "//img.alicdn.com/tps/i4/TB1M3zhLVXXXXX4XVXXrdvGIFXX-248-155.jpg",
-      "rightBannerImg": null
-    }, {
-      "shopList": null,
-      "finalScore": "0.0",
-      "industryUrl": "//pages.tmall.com/wow/act/15617/xiangbaohuanxin?abbucket=_AB-M1011_B14&acm=03654.1003.1.735362&aldid=KXPpnvEH&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.OTHER_11_735362&pos=14",
-      "entityType": "OTHER",
-      "colour": "#ffccdc",
-      "industryTitle": "箱包",
-      "bannerUrl": null,
-      "leftBannerImg": null,
-      "_pos_": "14",
-      "industryBenefit": "极致焕新尖货",
-      "industryId": "11",
-      "industryImg": "//img.alicdn.com/tps/i3/TB1gE6kLVXXXXcrXFXXrdvGIFXX-248-155.jpg",
-      "rightBannerImg": null
-    }, {
-      "shopList": null,
-      "finalScore": "0.0",
-      "industryUrl": "//pages.tmall.com/wow/act/15617/newnv?abbucket=_AB-M1011_B14&acm=03654.1003.1.735362&aldid=KXPpnvEH&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.OTHER_10_735362&pos=15",
-      "entityType": "OTHER",
-      "colour": "#fff8ee",
-      "industryTitle": "鞋履",
-      "bannerUrl": null,
-      "leftBannerImg": null,
-      "_pos_": "15",
-      "industryBenefit": "潮品精选鞋履",
-      "industryId": "10",
-      "industryImg": "//img.alicdn.com/tps/i3/TB1.qzpLVXXXXX.XFXXrdvGIFXX-248-155.jpg",
-      "rightBannerImg": null
-    }],
-    "isFormal": "false",
-    "exposureParam": "//ac.mmstat.com/1.gif?apply=vote&abbucket=_AB-M1011_B14&com=02&acm=03654.1003.1.735362&cod=03654&cache=U5revsTn&aldid=KXPpnvEH&logtype=4&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.735362&ip=",
-    "id": "03654"
-  }
-
-  module.exports = {
-    components: {
-      banner: require('./banner.vue')
-    },
-    props: {
-      ds: {
-        default: function () {
-          return {}
-        }
-      }
-    },
-    data: function () {
-      return {
-        NUMBER_248: 248,
-        NUMBER_155: 155,
-        NUMBER_373: 373,
-        NUMBER_237: 237,
-        NUMBER_186: 186,
-        NUMBER_208: 208,
-        NUMBER_750: 750,
-        subItemBg: '//gw.alicdn.com/tps/TB1QzUfLVXXXXaOXVXXXXXXXXXX-248-86.jpg',
-        items: [],
-        subItems: []
-      }
-    },
-    created: function () {
-      this.initData(demoContent)
-    },
-    methods: {
-      getSubItemTop: function (i) {
-        return (i - i % 3) / 3 * (241 + 3);
-      },
-      getSubItemLeft: function (i) {
-        return i % 3 * (248 + 3);
-      },
-      initData: function (content) {
-        this.items = content.main;
-        this.subItems = content.sub;
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/showcase/include/coupon.vue b/examples/vue/showcase/include/coupon.vue
deleted file mode 100644
index 268f36c..0000000
--- a/examples/vue/showcase/include/coupon.vue
+++ /dev/null
@@ -1,85 +0,0 @@
-<template>
-  <div>
-    <image v-if="ds.floorTitle" class="title" :src="ds.floorTitle"></image>
-    <div class="wrapper">
-      <image class="img" :src="currentStatus"></image>
-      <div class="my-coupon" @click="handleClick"></div>
-      <div class="guides" @click="handleClick"></div>
-      <div class="lottery" @click="handleClick"></div>
-    </div>
-  </div>
-</template>
-
-<style scoped>
-  .title{
-    width:750;
-    height:100;
-  }
-  .wrapper {
-    color: #FF4550;
-    width: 750;
-    height: 230;
-  }
-
-  .my-coupon {
-    width: 180;
-    height: 39;
-    position: absolute;
-    top: 15;
-    right: 149;
-  }
-
-  .guides {
-    height: 39;
-    width: 110;
-    position: absolute;
-    top: 15;
-    right: 32;
-  }
-
-  .lottery {
-    width: 348;
-    height: 76;
-    position: absolute;
-    top: 132;
-    right: 70;
-  }
-
-  .info {
-    font-size: 18;
-    position: absolute;
-    top: 84;
-    right: 70;
-  }
-
-  .img {
-    width: 750;
-    height: 230;
-  }
-</style>
-
-<script>
-  var modal = weex.requireModule('modal')
-  module.exports = {
-    props: {
-      ds: {
-        default: function () {
-          return {}
-        }
-      }
-    },
-    data: function () {
-      return {
-        currentStatus: '//img.alicdn.com/tps/i4/TB1cYBKMXXXXXayaXXXkxHk2pXX-750-228.jpg_q75.jpg'
-      }
-    },
-    methods: {
-      handleClick: function (e) {
-        modal.toast({
-            message: 'click',
-            duration: 1
-        });
-      }
-    }
-  };
-</script>
diff --git a/examples/vue/showcase/include/goods.vue b/examples/vue/showcase/include/goods.vue
deleted file mode 100644
index 861d5ae..0000000
--- a/examples/vue/showcase/include/goods.vue
+++ /dev/null
@@ -1,69 +0,0 @@
-<template>
-  <div v-if="!ds.isHide">
-    <image v-if="ds.floorTitle" class="title" :src="ds.floorTitle"></image>
-    <slider class="slider" show-indicators="true" auto-play="true" interval="3000">
-      <div class="pannel" v-for="(item,i) in ds.bannerItems" :key="i" >
-        <div>
-          <banner style="margin-bottom:4" :width="NUMBER_251" :height="NUMBER_292" :src="item.img1" :href="item.url1"></banner>
-          <banner :width="NUMBER_251" :height="NUMBER_292" :src="item.img2" :href="item.url2"></banner>
-        </div>
-        <div  class="middle-col">
-          <banner :width="NUMBER_240" :height="NUMBER_588" :src="item.img3" :href="item.url3"></banner>
-        </div>
-        <div>
-          <banner style="margin-bottom:4" :width="NUMBER_251" :height="NUMBER_292" :src="item.img4" :href="item.url4"></banner>
-          <banner :width="NUMBER_251" :height="NUMBER_292" :src="item.img5" :href="item.url5"></banner>
-        </div>
-      </div>
-      <indicator
-        style="position:absolute;width:714;height:200;left:10;bottom:-80;itemSize:20;itemColor:#999999;itemSelectedColor:#000000;"></indicator>
-    </slider>
-  </div>
-</template>
-
-<style scoped>
-  .title {
-    width: 750;
-    height: 100;
-  }
-
-  .slider {
-    height: 652;
-  }
-
-  .pannel {
-    width: 750;
-    height: 592;
-    flex-direction: row;
-  }
-
-  .middle-col {
-    margin-left:4;
-    margin-right:4;
-    width: 240;
-    height: 588;
-  }
-</style>
-
-<script>
-  module.exports = {
-    components: {
-      banner: require('./banner.vue')
-    },
-    props: {
-      ds: {
-        default: function () {
-          return {}
-        }
-      }
-    },
-    data: function () {
-      return {
-        NUMBER_251: 251,
-        NUMBER_240: 240,
-        NUMBER_292: 292,
-        NUMBER_588: 588
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/showcase/include/headlines.vue b/examples/vue/showcase/include/headlines.vue
deleted file mode 100644
index d76b1fd..0000000
--- a/examples/vue/showcase/include/headlines.vue
+++ /dev/null
@@ -1,94 +0,0 @@
-<template>
-  <div class="container">
-    <image class="banner" :src="ds.topBanner"></image>
-    <div class="rule-container">
-      <link style="font-size:22px;color:#ffffff;text-align:center;"
-        text="帮助" :href="ds.ruleLink"></link>
-    </div>
-    <div class="announce">
-      <image class="announce-hd" :src="ds.announceHdBanner"></image>
-      <banners style="margin-left:6;margin-right:6;"
-        :ds="ds.bannerItems" direction="row" :width="NUMBER_233"
-        :height="NUMBER_172" :space="NUMBER_3">
-      </banners>
-    </div>
-  </div>
-</template>
-
-<style scoped>
-  .banner {
-    width: 750;
-    height: 782;
-  }
-
-  .share-container {
-    position: absolute;
-    right: 100;
-    top: 15;
-    z-index: 100;
-    font-size: 20;
-    color: #ffffff;
-    background-color: #000000;
-    border-radius: 17;
-    width: 110;
-    height: 35;
-    justify-content: center;
-    align-items: center;
-  }
-
-  .rule-container {
-    position: absolute;
-    right: 22;
-    top: 15;
-    z-index: 100;
-    font-size: 20;
-    color: #ffffff;
-    background-color: #000000;
-    border-radius: 17;
-    width: 70;
-    height: 35;
-    justify-content: center;
-  }
-
-  .announce {
-    background-color: #f5f3f4;
-    width: 716;
-    height: 286;
-    position: absolute;
-    bottom: 17;
-    left: 17;
-    border-radius: 5;
-  }
-
-  .announce-hd {
-    width: 700;
-    height: 90;
-    margin-top: 8;
-    margin-bottom: 8;
-    margin-left: 5;
-    margin-right: 5;
-  }
-</style>
-
-<script>
-  module.exports = {
-    components: {
-      link: require('./link.vue'),
-      banners: require('./banners.vue')
-    },
-    props: {
-      ds: {
-        default: function () {
-          return {}
-        }
-      }
-    },
-    data: function () {
-      return {
-        NUMBER_233: 233,
-        NUMBER_172: 172,
-        NUMBER_3: 3
-      }
-    }
-  };
-</script>
diff --git a/examples/vue/showcase/include/link.vue b/examples/vue/showcase/include/link.vue
deleted file mode 100644
index e6923a2..0000000
--- a/examples/vue/showcase/include/link.vue
+++ /dev/null
@@ -1,17 +0,0 @@
-<template>
-  <text @click="clickHandler">{{text}}</text>
-</template>
-<script>
-  var modal = weex.requireModule('modal')
-  module.exports = {
-    props: ['text', 'href'],
-    methods: {
-      clickHandler: function () {
-        modal.toast({
-          message: 'click',
-          duration: 1
-        });
-      }
-    }
-  };
-</script>
diff --git a/examples/vue/showcase/include/match.vue b/examples/vue/showcase/include/match.vue
deleted file mode 100644
index ab851fe..0000000
--- a/examples/vue/showcase/include/match.vue
+++ /dev/null
@@ -1,50 +0,0 @@
-<template>
-  <div>
-    <image v-if="ds.floorTitle" class="title" :src="ds.floorTitle"></image>
-    <div class="tm-banner" v-if="ds.isShowTmSpecBanner && ds.tmSpecBanner">
-      <banner :width="NUMBER_750" :height="NUMBER_200" :src="ds.tmSpecBanner.img" :href="ds.tmSpecBanner.url"></banner>
-    </div>
-    <div v-for="(item,i) in ds.bannerItems" :key="i" :style="{ flexDirection: 'row', marginBottom: NUMBER_4 }">
-      <div :style="{ marginRight: NUMBER_4 }">
-        <banner :width="NUMBER_373" :height="NUMBER_240" :src="item.leftImg" :href="item.leftUrl"></banner>
-      </div>
-      <div>
-        <banner :width="NUMBER_373" :height="NUMBER_240" :src="item.rightImg" :href="item.rightUrl"></banner>
-      </div>
-    </div>
-  </div>
-</template>
-
-<style scoped>
-  .title {
-    width: 750;
-    height: 100;
-  }
-  .tm-banner{
-    bottom:4;
-  }
-</style>
-
-<script>
-  module.exports = {
-    components: {
-      banner: require('./banner.vue')
-    },
-    props: {
-      ds: {
-        default: function () {
-          return {}
-        }
-      }
-    },
-    data: function () {
-      return {
-        NUMBER_750: 750,
-        NUMBER_373: 373,
-        NUMBER_240: 240,
-        NUMBER_200: 200,
-        NUMBER_4: 4
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/showcase/include/resource.vue b/examples/vue/showcase/include/resource.vue
deleted file mode 100644
index 7c935c6..0000000
--- a/examples/vue/showcase/include/resource.vue
+++ /dev/null
@@ -1,43 +0,0 @@
-<template>
-  <div v-if="!ds.isHide">
-    <div class="big-banner-container">
-      <banner :width="NUMBER_750" :height="NUMBER_200" :src="ds.bigBannerImg" :href="ds.bigBannerUrl"></banner>
-    </div>
-    <banners direction="row" :ds="ds.smallBannerItems" :width="NUMBER_373" :height="NUMBER_224" :space="NUMBER_4"></banners>
-  </div>
-</template>
-
-<style scoped>
-  .title {
-    width: 750;
-    height: 100;
-  }
-  .big-banner-container{
-    margin-bottom:4;
-  }
-</style>
-
-<script>
-  module.exports = {
-    components: {
-      banners: require('./banners.vue'),
-      banner: require('./banner.vue')
-    },
-    props: {
-      ds: {
-        default: function () {
-          return {}
-        }
-      }
-    },
-    data: function () {
-      return {
-        NUMBER_750: 750,
-        NUMBER_200: 200,
-        NUMBER_373: 373,
-        NUMBER_224: 224,
-        NUMBER_4: 4
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/showcase/include/scene.vue b/examples/vue/showcase/include/scene.vue
deleted file mode 100644
index 7c7db25..0000000
--- a/examples/vue/showcase/include/scene.vue
+++ /dev/null
@@ -1,283 +0,0 @@
-<template>
-  <div>
-    <image v-if="ds.floorTitle" class="title" :src="ds.floorTitle"></image>
-    <div class="small-item-container" :style="{ height: Math.round(smallItems.length/2)*234 }">
-      <div v-for="(item,i) in smallItems" :key="i" class="small-item" :style="{ top: getItemTop(i), left: getItemLeft(i) }">
-        <div>
-          <image class="small-item-bg" :src="smallItemBg"></image>
-        </div>
-        <div class="small-item-img">
-          <banner :width="NUMBER_186" :height="NUMBER_206" :src="item.itemImg" :href="item.sceneUrl"></banner>
-        </div>
-        <div class="small-benifit-img">
-          <banner :width="NUMBER_170" :height="NUMBER_100" :src="item.benefitImg" :href="item.sceneUrl"></banner>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<style scoped>
-  .title {
-    width: 750;
-    height: 100;
-  }
-
-  .item {
-    width: 750;
-    height: 340;
-    margin-bottom: 4;
-  }
-
-  .item-img {
-    position: absolute;
-    left: 110;
-    top: 20;
-  }
-
-  .right-item-img {
-    position: absolute;
-    right: 110;
-    top: 20;
-  }
-
-  .benifit-img {
-    position: absolute;
-    right: 5;
-    top: 160;
-  }
-
-  .right-benifit-img {
-    position: absolute;
-    left: 40;
-    top: 160;
-  }
-
-  .small-item-container {
-    width: 750;
-  }
-
-  .small-item {
-    position: absolute;
-    width: 373;
-    height: 230;
-    flex-direction: row;
-  }
-
-  .small-item-bg {
-    width: 373;
-    height: 230;
-  }
-
-  .small-item-img {
-    position: absolute;
-    left: 12;
-    top: 12;
-  }
-
-  .small-benifit-img {
-    position: absolute;
-    right: 0;
-    top: 65;
-  }
-</style>
-
-<script>
-  var demoContent = [{
-    "id": "1111",
-    "sceneUrl": "https://pages.tmall.com/wow/act/15617/scene?acm=03653.1003.1.740603&aldid=VyrSqx06&wh_id=1392&scm=1003.1.03653.SUB_1111_740603&pos=1",
-    "_s_": "d",
-    "itemImg": "https://img.alicdn.com/tps/TB1c7t.MXXXXXchXXXXXXXXXXXX-182-206.jpg",
-    "sceneCat": "50012010,50012027,50012032,50007003,50008881,50008883,1623,162116,50010850,123216004",
-    "finalScore": "10000.0",
-    "_pos_": "1",
-    "entityType": "SUB",
-    "benefitImg": "//img.alicdn.com/tps/TB1Zgl2MXXXXXaYXFXXXXXXXXXX-170-100.png"
-  }, {
-    "id": "1396",
-    "sceneUrl": "https://pages.tmall.com/wow/act/15617/scene?acm=03653.1003.1.740603&aldid=VyrSqx06&wh_id=1396&scm=1003.1.03653.SUB_1396_740603&pos=2",
-    "_s_": "d",
-    "itemImg": "//img.alicdn.com/tps/i2/TB1O1VfMXXXXXX0aXXXKofZZpXX-182-206.jpg",
-    "sceneCat": "50010368,50011892,50011894,50013794,50010792,50010790,50010790,121434025,121396024,50010793,50010789,50010793,121386035,121392037,121458034,121392036,121482027,121392015,121368014,121418013,121392016,50011982,122690003,302910,50012010,122654005,50012019,50012825,50012027,50012042,50011744,50012906,50012907,50008881,50008883,50008882?,50012784?,50022889,50022728,50013228,50013896,50014775,50019578,50014822,50026394,50019694,50019279,50019272,50014079,50014078,50014076,50014077,50017238,121464011,121468014,50019130,50019127,50019126,50019128,50019125,50015984,50014803,50014802,50015980,50014788,50014787,50019526,50014791,50019520,50013932,50014677,50015978,50014786,50014785,50522001,50014493,50023100,121418021,121388027,121424021,121418020,121368020,50012036,50012044,50012043,50010368, 50011892, 50019274,50012044,50012048,50012043,50013228,50013238,50011726,50019279,50015984,50014803,50014802,50019526,50014791,50019520,50013932,50014677,50019526,50013314,50023341,50016752,50016749,50016747,50016744,50016741,50016740,50016739,50016738,50016737,50016769,50016763,50016750,50007003,302910,50012010,50012032,50012033,50011745,50011746,50011894,121458034,121756003,121426033,50011982,50011979,121390006,124730001,50001748,50011130,124730001,50001748,50011130,50011129,50010160,50011161,50011159,50010159,50010158,50011127,3035,50010167,50000557,50011123,50010402,50000436,50011153,50010850,50000671,162201,50022566,50007068,50026651,50000852,162104,162116,162205,1623,123216004,162404,162401,50011412,50011411,162402,50008903,50011413,162403,50000697,1629,50011277,121412004,50008897,50008901,50008899,50013194,50008904,50008905,50008898,162103,50008900,50013196,121434004,50005065,162702,162701,162703,1636,1512,123534001,14,50008090,50012341,50132002,50012342,50012343,50012345,50012346,50013189,50010527,121394006,50013618,50010537,50012424,121452038,121484044,50010540,50010548,50024769,121450007,50013697,50010218,50005960,50005962,50012820,50012406,50023620,50023605,50008829,50024064,50023440,50008687,124392001,50023771,50006804,50012410,124482010,121398023,50023789,50011975",
-    "finalScore": "10000.0",
-    "_pos_": "2",
-    "entityType": "SUB",
-    "benefitImg": "//img.alicdn.com/tps/i1/TB1cp4sMXXXXXbLXFXX3bpXTXXX-170-100.png"
-  }, {
-    "id": "1616",
-    "sceneUrl": "https://pages.tmall.com/wow/act/15617/scene?acm=03653.1003.1.740603&aldid=VyrSqx06&wh_id=1616&scm=1003.1.03653.SUB_1616_740603&pos=3",
-    "_s_": "d",
-    "itemImg": "//img.alicdn.com/tps/i4/TB1dlEALVXXXXbxXpXXKofZZpXX-182-206.jpg",
-    "sceneCat": "50009032,50007003,302910,1512,124688012,124986002,124942005,50023722,50010368,50011892,50011894",
-    "finalScore": "10000.0",
-    "_pos_": "3",
-    "entityType": "SUB",
-    "benefitImg": "//img.alicdn.com/tps/i3/TB1fxonLVXXXXXUaXXX3bpXTXXX-170-100.png"
-  }, {
-    "id": "16424",
-    "sceneUrl": "https://brand.tmall.com/mobilestreet/subject.htm?id=16424&acm=03653.1003.1.740603&aldid=VyrSqx06&spm=0.0.0.0.Wv8ion&scm=1003.1.03653.SUB_16424_740603&pos=4",
-    "_s_": "d",
-    "itemImg": "//img.alicdn.com/tps/i4/TB1.i2_LVXXXXbrXpXXKofZZpXX-182-206.jpg",
-    "sceneCat": "50012043,50012036,50010850,50000671,1622,50000852,162104,50000697,162205,162116,50012027,50012032,50012028,50012033,50012042,50008882,50012772,50006846,50008881,50000436,50011123,3035,50010167,50000557,50010158,50010159,50010402,50010160,50011980,50011993,121390006,50011978,50011977,50011979,121454013,50011745",
-    "finalScore": "6.729749999999999",
-    "_pos_": "4",
-    "entityType": "SUB",
-    "benefitImg": "//img.alicdn.com/tps/i2/TB1bhH5LVXXXXapXFXX3bpXTXXX-170-100.png"
-  }, {
-    "id": "16425",
-    "sceneUrl": "https://brand.tmall.com/mobilestreet/subject.htm?id=16360&acm=03653.1003.1.740603&aldid=VyrSqx06&spm=0.0.0.0.MttFEC&scm=1003.1.03653.SUB_16425_740603&pos=5",
-    "_s_": "d",
-    "itemImg": "//img.alicdn.com/tps/i3/TB15ywbLVXXXXcdXXXXKofZZpXX-182-206.jpg",
-    "sceneCat": "50012043,50012036,50010850,50000671,1622,50000852,162104,50000697,162205,162116,50012027,50012032,50012028,50012033,50012042,50008882,50012772,50006846,50008881,50000436,50011123,3035,50010167,50000557,50010158,50010159,50010402,50010160,50011980,50011993,121390006,50011978,50011977,50011979,121454013,50011745",
-    "finalScore": "6.729749999999999",
-    "_pos_": "5",
-    "entityType": "SUB",
-    "benefitImg": "//img.alicdn.com/tps/i1/TB1JBLYLVXXXXXlXVXX3bpXTXXX-170-100.png"
-  }, {
-    "id": "1625",
-    "sceneUrl": "https://pages.tmall.com/wow/fushi/act/gf-chaoliu?acm=03653.1003.1.740603&aldid=VyrSqx06&scm=1003.1.03653.SUB_1625_740603&pos=6",
-    "_s_": "d",
-    "itemImg": "//img.alicdn.com/bao/uploaded/i2/TB1Gd21KVXXXXXZXVXXXXXXXXXX_!!0-item_pic.jpg",
-    "sceneCat": "50012043,50012036,50010850,50000671,1622,50000852,162104,50000697,162205,162116,50012027,50012032,50012028,50012033,50012042,50008882,50012772,50006846,50008881,50000436,50011123,3035,50010167,50000557,50010158,50010159,50010402,50010160,50011980,50011993,121390006,50011978,50011977,50011979,121454013,50011982,50011991,50012906,50011744,50011745,50011743,50012907,50011746,50010815,121460005,50013794,122438001,121398006,121386023,50010808",
-    "finalScore": "6.729749999999999",
-    "_pos_": "6",
-    "entityType": "SUB",
-    "benefitImg": "//img.alicdn.com/tps/i3/TB1qxXzMXXXXXcjXFXX3bpXTXXX-170-100.png"
-  }, {
-    "id": "1392",
-    "sceneUrl": "https://pages.tmall.com/wow/act/15617/scene?acm=03653.1003.1.740603&aldid=VyrSqx06&wh_id=1392&scm=1003.1.03653.SUB_1392_740603&pos=7",
-    "_s_": "d",
-    "itemImg": "https://img.alicdn.com/tps/TB1c7t.MXXXXXchXXXXXXXXXXXX-182-206.jpg",
-    "sceneCat": "50006842,50006840,50008881,50008883,50008882,50008884,50012774,50012775,50012776,50012781,5000888,50012766,50012771,50012772,50010404,50010368, 50011892, 50011894,124688012,124730001,50001748,50011130,124730001,50001748,50011130,50011129,50010160,50011161,50011159,50010159,50010158,50011127,3035,50010167,50000557,50011123,50010402,50000436,50011153,50011740,50008882,50008886,50008885,50012777,50012778,50011977,50011978,50011979,50011980,50011982,50011990,50011999,50012000,50011993,50011996,50011997,121366011,121484009,121368010,121390006,121398029,121404030,121404031,121408040,121410035,121412033,121414041,121418013,121454013,121410013,121422013,121484013,50010789,50010790,50010792,50010793,50010794,50010796,50010797,50010798,50010801,50010803,50010805,50010807,50010808,50010815,121410007,121426007,121452004,121460005,50012341,50132002,50012342,50012343,50012345,50012346,50013189,50010527,121394006,50013618,50010537,50012424,121452038,121484044,50010540,50010548,50024769,121366037,121458036,121392038,121420035,121364028,121468026,121472031,121476036,121470042,121418032,121410036,121472032,121420032,121470040,121384032,121460028,121448028,121400030,121424024,121482025,121418031,121402028,121388035,121460029,121400028,121400029,121418030,121476034,121478031,121448029,121480030,121366035,121424025,121426030,121484030,121412031,121384033,121424023,121402027,121408039,121420033,121452028,121466040,121416029,121482028,121420034,121396046,121422052,121370037,121424031,21364043,121472040,121412045,121424032,125054002,125074007,125074008,125104003,125080003,125024006,125080004",
-    "finalScore": "4.4951428571428576",
-    "_pos_": "7",
-    "entityType": "SUB",
-    "benefitImg": "//img.alicdn.com/tps/TB1Zgl2MXXXXXaYXFXXXXXXXXXX-170-100.png"
-  }, {
-    "id": "1395",
-    "sceneUrl": "https://pages.tmall.com/wow/act/15617/scene?acm=03653.1003.1.740603&aldid=VyrSqx06&wh_id=1395&scm=1003.1.03653.SUB_1395_740603&pos=8",
-    "_s_": "d",
-    "itemImg": "//img.alicdn.com/tps/i2/TB1p4NcMXXXXXbGaXXXKofZZpXX-182-206.jpg",
-    "sceneCat": "50008881,50008883,50008882,50008884,50012774,50012775,50012776,50012781,50008886,50012766,50012771,50012772,50010850,50000671,162201,50022566,50007068,50026651,50000852,162104,162116,162205,1623,123216004,162404,162401,50011412,50011411,16240,50012773,50006846,50010394,50008888,50008890,50008889,50012784,50012785,50012786,50012787,50008885,50012777,50012778,124730001,50001748,50011130,124730001,50001748,50011130,50011129,50010160,50011161,50011159,50010159,50010158,50011127,3035,50010167,50000557,50011123,50010402,50000436,50011153,50011740,50006843,50006842,124942005,50010368,50011892,50011894,50023751,121366037,121458036,121392038,121420035,121364028,121468026,121400029,121418030,121478031,121480030,121366035,121424025,121426030,121484030,121412031,125054002,125074007,125074008,125104003,125080003,125024006,125080004,121400030,121424024,121482025,121418031,121402028,121388035",
-    "finalScore": "4.465166666666667",
-    "_pos_": "8",
-    "entityType": "SUB",
-    "benefitImg": "//img.alicdn.com/tps/i1/TB1ySNtMXXXXXamXFXX3bpXTXXX-170-100.png"
-  }, {
-    "id": "1394",
-    "sceneUrl": "https://pages.tmall.com/wow/act/15617/scene?acm=03653.1003.1.740603&aldid=VyrSqx06&wh_id=1394&scm=1003.1.03653.SUB_1394_740603&pos=9",
-    "_s_": "d",
-    "itemImg": "//img.alicdn.com/tps/i4/TB1Ns8eMXXXXXb1aXXXKofZZpXX-182-206.jpg",
-    "sceneCat": "50010850,50000671,162201,50022566,50007068,50026651,50000852,162104,162116,162205,1623,123216004,162404,162401,50011412,50011411,162402,50008903,50011413,162403,50000697,1629,50011277,121412004,50008897,50008901,50008899,50013194,50008904,50008905,50008898,162103,50008900,50013196,121434004,50005065,162702,162701,162703,1636,124730001,50001748,50011130,124730001,50001748,50011130,50011129,50010160,50011161,50011159,50010159,50010158,50011127,3035,50010167,50000557,50011123,50010402,50000436,50011153,50011740,50006843,50006842,124986002,50010368, 50011892,50011894,121480030,121366035,121424025,121426030,121484030,121412031",
-    "finalScore": "4.309925925925926",
-    "_pos_": "9",
-    "entityType": "SUB",
-    "benefitImg": "//img.alicdn.com/tps/i3/TB1ZEXfMXXXXXapaXXX3bpXTXXX-170-100.png"
-  }, {
-    "id": "1610",
-    "sceneUrl": "https://pages.tmall.com/wow/act/15617/scene?acm=03653.1003.1.740603&aldid=VyrSqx06&wh_id=1610&scm=1003.1.03653.SUB_1610_740603&pos=10",
-    "_s_": "d",
-    "itemImg": "//img.alicdn.com/tps/i3/TB1ONckLVXXXXbJaXXXKofZZpXX-182-206.jpg",
-    "sceneCat": "121484044,121452038,50012342,50012027,50012032,50006843,50010850,50000671,162104,1623,50011277,162116,123216004,50008898,121366037,121458036,121392038,121420035,121364028,121468026,121472031,121476036,121470042,121418032,121410036,121472032,121420032,121470040,121384032,121460028,121448028,121400030,121424024,121482025,121418031,121402028,121388035,121460029,121400028,121400029,121418030,121476034,121478031,121448029,121480030,121366035,121424025,121426030,121484030,121412031,121384033,121424023,121402027,121408039,121420033,121452028,121466040,121416029,121482028,121420034,121396046,121422052,121370037,121424031,21364043,121472040,121412045,121424032,125054002,125074007,125074008,125104003,125080003,125024006,125080004",
-    "finalScore": "4.293333333333334",
-    "_pos_": "10",
-    "entityType": "SUB",
-    "benefitImg": "//img.alicdn.com/tps/i2/TB1RzwFLVXXXXXsXpXX3bpXTXXX-170-100.png"
-  }, {
-    "id": "1619",
-    "sceneUrl": "https://pages.tmall.com/wow/act/15617/scene?acm=03653.1003.1.740603&aldid=VyrSqx06&wh_id=1619&scm=1003.1.03653.SUB_1619_740603&pos=11",
-    "_s_": "d",
-    "itemImg": "//img.alicdn.com/tps/i3/TB1eagyLVXXXXaiXFXXKofZZpXX-182-206.jpg",
-    "sceneCat": "124730001,50001748,50011130,124730001,50001748,50011130,50011129,50010160,50011161,50011159,50010159,50010158,50011127,3035,50010167,50000557,50011123,50010402,50000436,50011153,122654005,50011740,50009032,124688012,213202,121396029,121476023,121410029,213203,50023326,213205,50022686,50023293,50466023,50024999,50016885,50011894",
-    "finalScore": "4.23",
-    "_pos_": "11",
-    "entityType": "SUB",
-    "benefitImg": "//img.alicdn.com/tps/i4/TB1j0AxLVXXXXaRXFXX3bpXTXXX-170-100.png"
-  }, {
-    "id": "1613",
-    "sceneUrl": "https://pages.tmall.com/wow/act/15617/scene?acm=03653.1003.1.740603&aldid=VyrSqx06&wh_id=1613&scm=1003.1.03653.SUB_1613_740603&pos=12",
-    "_s_": "d",
-    "itemImg": "//img.alicdn.com/tps/i2/TB1WssFLVXXXXXUXpXXKofZZpXX-182-206.jpg",
-    "sceneCat": "50023108,50022893,50022892,50022890,50013228,50019520,50017120,50019560,50017129,50017128,50017127,50017126,50017125,50017124,50017123,50017122,50017121,50020039,50020038,50017119,50019559,50017110,50017108,50017107,50017097,50017096,50017095,50017094,50017093,50017092,50012036,50012041",
-    "finalScore": "4.2186666666666675",
-    "_pos_": "12",
-    "entityType": "SUB",
-    "benefitImg": "//img.alicdn.com/tps/i1/TB1Rg.qLVXXXXbqXVXX3bpXTXXX-170-100.png"
-  }, {
-    "id": "1614",
-    "sceneUrl": "https://pages.tmall.com/wow/act/15617/scene?acm=03653.1003.1.740603&aldid=VyrSqx06&wh_id=1614&scm=1003.1.03653.SUB_1614_740603&pos=13",
-    "_s_": "d",
-    "itemImg": "//img.alicdn.com/tps/i1/TB1KzUxLVXXXXajXFXXKofZZpXX-182-206.jpg",
-    "sceneCat": "50013238,50011726,50022893,50022892,50022890,50013228,50017129,50020038,50017119,50019559,50017102,50017110,50017097,50019707,50019555,50016677,50018317,50016675,50016673,50016672,50016671,50016670,50016732,50016669,50016668,50016667,50016666,50016665,50016683,50016682,50016608,50016607,50016637,50016638,50012036,50012043",
-    "finalScore": "4.216",
-    "_pos_": "13",
-    "entityType": "SUB",
-    "benefitImg": "//img.alicdn.com/tps/i2/TB1WyouLVXXXXXcXVXX3bpXTXXX-170-100.png"
-  }, {
-    "id": "1397",
-    "sceneUrl": "https://pages.tmall.com/wow/act/15617/scene?acm=03653.1003.1.740603&aldid=VyrSqx06&wh_id=1397&scm=1003.1.03653.SUB_1397_740603&pos=14",
-    "_s_": "d",
-    "itemImg": "//img.alicdn.com/tps/i4/TB1dCxvMXXXXXc1XpXXKofZZpXX-182-206.jpg",
-    "sceneCat": "122846004,50020776,50024799,50024801,50024921,50002794,50020778,50002792,50002791,50002793,50003942,50005500,50005497,50001692,50005495,50005496,50005503,50005498,50005499,50005501,50005502,50003455,50003457,122904003,50023091,50020770,50008863,50005507,121414011,50020768,50022701,50008862,121420012,50020766,50020764,121398012,121380011,50020751,50020676,50024945,50020720,50002790,50020730,50001866,50020678,121476008,121458013,50002795,121364011,50005505,121422014,50024943,50000583,50000582,50000584,213002,50005033,50000563,50008607,50006988,50008608,50024601,50024602,50012051,50001871,122854005,121458010,121452006,121416008,50008779,50002777,121394007,121386009,50010825,50013810,121434010,50001865,50008565,50008246,50017192,121404045,121368009,121462014,50019372,50008248,121418011,50008249,50017193,50008252,50008251,50000512,121364047,122846004,50020776,50024799,50024801,50024921,50002794,50020778,50002792,50002791,50002793,50003942,50005500,50005497,50001692,50005495,50005496,50005503,50005498,50005499,50005501,50005502,50003455,50003457,122904003,50023091,50020770,50008863,50005507,121414011,50020768,50022701,50008862,121420012,50020766,50020764,121398012,121380011,50020751,50020676,50024945,50020720,50002790,50020730,50001866,50020678,121476008,121458013,50002795,121364011,50005505,121422014,50024943,50000583,50000582,50000584,213002,50005033,50000563,50008607,50006988,50008608,50024601,50024602,50012051,50020835,50021907,121472021,50021902,50005919,50002045,122724003,122652007,121408025,122688004,50021924,50021923,50000561,50011738,122676005,121396026,121388028,50003338,50021915,50011415,50011416,50003454,50021928,50021930,50021929,50021931,50024939,121384024,121472020,50020902,50020903,50020904,50020905,50021888,50021889,50021890,50023266,122960005,50012001,50011999,50012004,50012000,50012006,121394024,121412033,121394025,121450036,121472007,121480009,121388013,121466009,121484012,121366014,121434014,121422012,121476006,121396013,50011997,121434013,122646001,121458012,121468012,121368013,50011979,121366015,121406016,121456012,121366011,121414010,121460006,121368014,121388016,121396013,121400010,121470011,121474011,121478009,124760009,124768010,124822006,121482009,122430002,121454014,121392016,50001871,122854005,121458010,121452006,121416008,50008779,50002777,121394007,121386009,50010825,50013810,121434010,50001865,50008565,50008246,50017192,121404045,121368009,121462014,50019372,50008248,121418011,50008249,50017193,50008252,50008251,50000512,121364047,122846004,50020776,50024799,50024801,50024921,50002794,50020778,50002792,50002791,50002793,50003942,50005500,50005497,50001692,50005495,50005496,50005503,50005498,50005499,50005501,50005502,50003455,50003457,122904003,50023091,50020770,50008863,50005507,121414011,50020768,50022701,50008862,121420012,50020766,50020764,121398012,121380011,50020751,50020676,50024945,50020720,50002790,50020730,50001866,50020678,121476008,121458013,50002795,121364011,50005505,121422014,50024943,50000583,50000582,50000584,213002,50005033,50000563,50008607,50006988,50008608,50024601,50024602,50012051",
-    "finalScore": "3.4206666666666665",
-    "_pos_": "14",
-    "entityType": "SUB",
-    "benefitImg": "//img.alicdn.com/tps/i3/TB1ZARnMXXXXXaGXVXX3bpXTXXX-170-100.png"
-  }, {
-    "id": "1608",
-    "sceneUrl": "https://pages.tmall.com/wow/act/15617/scene?acm=03653.1003.1.740603&aldid=VyrSqx06&wh_id=1608&scm=1003.1.03653.SUB_1608_740603&pos=15",
-    "_s_": "d",
-    "itemImg": "//img.alicdn.com/tps/i3/TB1xA3jLVXXXXXqapXXKofZZpXX-182-206.jpg",
-    "sceneCat": "50012010,50012027,50012032,50007003,50008881,50008883,1623,162116,50010850,123216004",
-    "finalScore": "0.0",
-    "_pos_": "15",
-    "entityType": "SUB",
-    "benefitImg": "//img.alicdn.com/tps/i2/TB1WvoALVXXXXcdXpXX3bpXTXXX-170-100.png"
-  }]
-
-  module.exports = {
-    components: {
-      banner: require('./banner.vue')
-    },
-    props: {
-      ds: {
-        default: function () {
-          return {}
-        }
-      }
-    },
-    data: function () {
-      return {
-        NUMBER_186: 186,
-        NUMBER_206: 206,
-        NUMBER_373: 373,
-        NUMBER_230: 230,
-        NUMBER_170: 170,
-        NUMBER_100: 100,
-        NUMBER_750: 750,
-        NUMBER_300: 300,
-        NUMBER_340: 340,
-        smallItemBg: 'https://gw.alicdn.com/tps/TB1oBIeLVXXXXatXpXXXXXXXXXX-373-230.jpg',
-        items: [],
-        smallItems: [],
-        sceneBgs: [
-          'https://gw.alicdn.com/tps/TB1xBT8LVXXXXbYXVXXXXXXXXXX-750-340.jpg',
-          'https://gw.alicdn.com/tps/TB1RoEkLVXXXXaMXpXXXXXXXXXX-750-340.jpg',
-          'https://gw.alicdn.com/tps/TB1DiEpLVXXXXa7XXXXXXXXXXXX-750-340.jpg'
-        ]
-      }
-    },
-    created: function () {
-      this.items = demoContent.slice(0, 3);
-      this.smallItems = demoContent.slice(3);
-    },
-    methods: {
-      getItemTop: function (i) {
-        return (i - i % 2) / 2 * (230 + 4);
-      },
-      getItemLeft: function (i) {
-        return i % 2 * (373 + 4);
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/showcase/include/util.js b/examples/vue/showcase/include/util.js
deleted file mode 100644
index c56d0a8..0000000
--- a/examples/vue/showcase/include/util.js
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-function randomInt (min, max) {
-    return Math.round(Math.random() * (max - min)) + min;
-},
-function randomItemFromArr (arr) {
-    if (!arr) return;
-    return arr[randomInt(0, arr.length - 1)];
-},
-function httpurl (url) {
-    var params = {};
-
-    Object.defineProperty(this, 'params', {
-        set: function (v) {
-            if (typeof v === 'object') {
-                for (var p in params) {
-                    delete params[p];
-                }
-                for (var p in v) {
-                    params[p] = v[p];
-                }
-            }
-        },
-        get: function () {
-            return params;
-        },
-        enumerable: true
-    });
-
-    Object.defineProperty(this, 'search', {
-        set: function (v) {
-            if (typeof v === 'string') {
-                if (v.indexOf('?') === 0) {
-                    v = v.substr(1);
-                }
-                var search = v.split('&');
-                for (var p in params) {
-                    delete params[p];
-                }
-                for (var i = 0; i < search.length; i++) {
-                    var pair = search[i].split('=');
-                    if (pair[0]) {
-                        try {
-                            params[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || '');
-                        } catch (e) {
-                            params[pair[0]] = pair[1] || '';
-                        }
-                    }
-                }
-            }
-        },
-        get: function () {
-            var search = [];
-            for (var p in params) {
-                if (params[p]) {
-                    try {
-                        search.push(encodeURIComponent(p) + '=' + encodeURIComponent(params[p]));
-                    } catch (e) {
-                        search.push(p + '=' + params[p]);
-                    }
-                } else {
-                    try {
-                        search.push(encodeURIComponent(p));
-                    } catch (e) {
-                        search.push(p);
-                    }
-                }
-            }
-            if (search.length) {
-                return '?' + search.join('&');
-            } else {
-                return '';
-            }
-        },
-        enumerable: true
-    });
-
-    var hash;
-    Object.defineProperty(this, 'hash', {
-        set: function (v) {
-            if (typeof v === 'string') {
-                if (v && v.indexOf('#') < 0) {
-                    v = '#' + v;
-                }
-                hash = v || '';
-            }
-        },
-        get: function () {
-            return hash;
-        },
-        enumerable: true
-    });
-
-    this.set = function (v) {
-        var matchArr;
-        if ((matchArr = v.match(new RegExp('^([a-z0-9-]+\:)?' +    //protocol
-                        '[/]{2}' +                            //slash x 2
-                        '(?:([^@/:\?]+)(?::([^@/:]+))?@)?' +  //username:password@
-                        '([^:/?#]+)' +                        //hostname
-                        '(?:[:]([0-9]+))?' +                  //port
-                        '([/][^?#;]*)?' +                     //pathname
-                        '(?:[?]([^?#]*))?' +                  //search
-                        '(#[^#]*)?$'                          //hash
-                        , 'i')))) {
-            this.protocol = matchArr[1] || '';
-            this.username = matchArr[2] || '';
-            this.password = matchArr[3] || '';
-            this.hostname = this.host = matchArr[4];
-            this.port = matchArr[5] || '';
-            this.pathname = matchArr[6] || '/';
-            this.search = matchArr[7] || '';
-            this.hash = matchArr[8] || '';
-            this.origin = this.protocol + '//' + this.hostname;
-        } else {
-            throw new Error('Wrong uri scheme.');
-        }
-    };
-
-    this.toString = function () {
-        var string = this.protocol + '//';
-        if (this.username) {
-            string += this.username;
-            if (this.password) {
-                string += ':' + this.password;
-            }
-            string += '@';
-        }
-        string += this.host;
-        if (this.port && this.port !== '80') {
-            string += ':' + this.port;
-        }
-        if (this.pathname) {
-            string += this.pathname;
-        }
-        if (this.search) {
-            string += this.search;
-        }
-        if (this.hash) {
-            string += this.hash;
-        }
-        return string;
-    };
-
-    this.set(url.toString());
-}
-
-module.exports = {
-  randomInt: randomInt,
-  randomItemFromArr: randomItemFromArr,
-  httpurl: httpurl
-}
diff --git a/examples/vue/showcase/itemlist.vue b/examples/vue/showcase/itemlist.vue
deleted file mode 100644
index 02fb33a..0000000
--- a/examples/vue/showcase/itemlist.vue
+++ /dev/null
@@ -1,548 +0,0 @@
-<template>
-  <list class="list" @loadmore="loadmore" loadmoreoffset=2000>
-    <cell class="cell" v-for="item in shopList" :scope="item.scopeValue" @click="oncellclick(item.id)">
-      <div class="shopDiv">
-        <div class="shopHeader" style="flex-direction:row;">
-          <div style="flex:2;flex-direction:row;">
-            <div>
-              <image class="test" :src="item.PersonPhoto"></image>
-            </div>
-            <div style="flex-direction:column;margin-left:5px;">
-              <div style="margin-top:5px;">
-                <text style="font-size:20px;">{{item.PersonName}}</text>
-              </div>
-              <div style="margin-top:5px;">
-                <text style="font-size:20;color:#cccccc;">{{item.PersonVisitTime}}</text>
-              </div>
-            </div>
-          </div>
-          <div style="flex:5;flex-direction:row;">
-            <div style="flex-direction:row;margin-left:10px;margin-top:10px;">
-              <div>
-                <image style="width:20px;height:20px;"
-                  src="https://img.alicdn.com/tps/i4/TB1zkDeIFXXXXXrXVXX07tlTXXX-200-200.png_88x88xz.jpg"></image>
-              </div>
-              <div>
-                <text style="font-size:20px;">Hope</text>
-              </div>
-            </div>
-            <div style="position:absolute;left:90px;top:10px;flex-direction:row;">
-              <div>
-                <image style="width:20px;height:20px;"
-                  src="https://img.alicdn.com/tps/i2/TB1hRb1IXXXXXX3XVXXXQaP.pXX-87-87.jpeg"></image>
-              </div>
-              <div>
-                <text style="font-size:20px;">Mem</text>
-              </div>
-            </div>
-            <div style="position:absolute;left:170px;top:10px;flex-direction:row;">
-              <div>
-                <image style="width:20px;height:20px;"
-                  src="https://img.alicdn.com/tps/i3/TB1DGkJJFXXXXaZXFXX07tlTXXX-200-200.png"></image>
-              </div>
-              <div>
-                <text style="font-size:20px;">auth</text>
-              </div>
-            </div>
-            <div style="position:absolute;left:250px;top:10px;flex-direction:row;">
-              <div>
-                <image style="width:20px;height:20px;"
-                  src="https://img.alicdn.com/tps/i1/TB1nFvPIXXXXXbUXXXXUAkPJpXX-87-87.png"></image>
-              </div>
-              <div>
-                <text style="font-size:20px;">Friend</text>
-              </div>
-            </div>
-            <div style="position:absolute;left:330px;top:10px;flex-direction:row;">
-              <div>
-                <image style="width:20px;height:20px;"
-                  src="https://img.alicdn.com/tps/i2/TB1CpD7IXXXXXbSXXXXUAkPJpXX-87-87.png"></image>
-              </div>
-              <div>
-                <text style="font-size:20px;">issue</text>
-              </div>
-            </div>
-            <div style="position:absolute;left:410px;top:10px;flex-direction:row;">
-              <div>
-                <image style="width:20px;height:20px;"
-                  src="https://gtms02.alicdn.com/tps/i2/TB11ZZfIVXXXXbMXFXXEDhGGXXX-32-32.png"></image>
-              </div>
-              <div>
-                <text style="font-size:20px;">super</text>
-              </div>
-            </div>
-          </div>
-        </div>
-        <div class="shopBody" style="flex-direction:column;">
-          <div class="descDiv" style="margin-top:10px;margin-left:10px;">
-            <text class="shopDesc" style="font-size:25px;">{{item.shopDesc}}</text>
-          </div>
-          <div style="flex-direction:row;">
-            <div class="imgDiv" style="flex:1;height:300px;flex-direction:column;margin:10px;" v-for="img in item.shopImgList">
-              <div>
-                <image class="shopImg" :style="{ width: img.shopImgWidth, height: img.shopImgHeight }" :src="img.shopImg"></image>
-              </div>
-              <div style="flex:1;margin-top:10px;flex-direction:row;">
-                <div style="flex:1;justify-content:center;flex-direction:row;">
-                  <div>
-                    <image style="width:20px;height:20px;"
-                           src="https://img.alicdn.com/tps/i1/TB1nFvPIXXXXXbUXXXXUAkPJpXX-87-87.png"></image>
-                  </div>
-                  <div style="margin-left:5px;">
-                    <text style="font-size:20px;text-align:center;">Up</text>
-                  </div>
-                </div>
-                <div style="flex:1;justify-content:center;flex-direction:row;">
-                  <div>
-                    <image style="width:20px;height:20px;"
-                           src="https://img.alicdn.com/tps/i2/TB1CpD7IXXXXXbSXXXXUAkPJpXX-87-87.png"></image>
-                  </div>
-                  <div style="margin-left:5px;">
-                    <text style="font-size:20px;text-align:center;">down</text>
-                  </div>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-        <div class="shopFooter" style="flex-direction:row;margin-top:10px;margin-left:10px;justify-content:flex-end;">
-          <div style="margin-right:5px;">
-            <image class="shopLikeImg smallImg" :src="item.shopLikeImg"></image>
-          </div>
-          <div style="margin-right:15px;">
-            <text class="shopLikeText" style="font-size:20px;">{{item.shopLikeText}}</text>
-          </div>
-          <div style="margin-right:5px;">
-            <image class="shopCommentImg smallImg" :src="item.shopCommentImg"></image>
-          </div>
-          <div style="margin-right:15px;">
-            <text class="shopCommentText" style="font-size:20px;">{{item.shopCommentText}}</text>
-          </div>
-          <div style="margin-right:5px;">
-            <image class="shopLookImg smallImg" :src="item.shopLookImg"></image>
-          </div>
-          <div style="margin-right:15px;">
-            <text class="shopLookText" style="font-size:20px;">{{item.shopLookText}}</text>
-          </div>
-          <div style="margin-right:5px;">
-            <image class="shareImg smallImg" :src="item.shareImg"></image>
-          </div>
-          <div style="margin-right:20px;">
-            <text class="shareText" style="font-size:20px;">{{item.shareText}}</text>
-          </div>
-        </div>
-      </div>
-    </cell>
-  </list>
-</template>
-
-<style scoped>
-  .flexRow {
-    flex-direction: row;
-  }
-
-  .flexColumn {
-    flex-direction: column;
-  }
-
-  .text {
-  }
-
-  .div {
-  }
-
-  .fixed {
-    position: fixed;
-    bottom: 50px;
-    left: 50px;
-    width: 300px;
-    height: 50px;
-    align-items: center;
-    justify-content: center
-  }
-
-  .shopImg {
-    width: 220px;
-    height: 220px;
-  }
-
-  .list {
-    flex-direction: column;
-    overflow: hidden;
-    width: 750px;
-    height: 1200px;
-    background-color: #dddddd;
-  }
-
-  .cell {
-    background-color: #dddddd;
-    flex-direction: column;
-    width: 750px;
-  }
-
-  .test {
-    width:60px;
-    height:60px;
-  }
-
-  .shopDiv {
-    flex-direction: column;
-    background-color: #ffffff;
-    margin: 5px;
-    padding: 10px;
-    border-width: 1px;
-    border-color: #cccccc;
-    overflow: visible;
-  }
-
-  .shopRowList {
-    flex-direction: column;
-    border-width: 1px;
-    border-color: #cccccc;
-    overflow: visible;
-    margin: 5px;
-    padding: 10px;
-    background-color: #ffffff;
-  }
-
-  .shopHeader {
-    flex-direction: row;
-    width: 720px;
-  }
-
-  .shopFooter {
-    flex-direction: row;
-    width: 720px;
-  }
-
-  .smallImg {
-    width: 20px;
-    height: 20px;
-  }
-</style>
-
-<script>
-  var modal = weex.requireModule('modal')
-  module.exports = {
-    data: function () {
-      return {
-        shopList: [
-          {
-            id: 1,
-            scopeValue: 1,
-            PersonPhoto: 'https://gw.alicdn.com/tps/i3/TB1yeWeIFXXXXX5XFXXuAZJYXXX-210-210.png_60x60.jpg',
-            PersonName: 'Mendeleyev',
-            PersonVisitTime: 'today',
-            shopDesc: 'Genius only means hard-working all one\'s life',
-            shopImgList: [{
-              shopImgWidth: '220px',
-              shopImgHeight: '220px',
-              shopImg: 'https://gd2.alicdn.com/bao/uploaded/i2/TB1rtOnHpXXXXXLaXXXXXXXXXXX_!!0-item_pic.jpg_220x220.jpg'
-            }, {
-              shopImgWidth: '220px',
-              shopImgHeight: '220px',
-              shopImg: 'https://gd4.alicdn.com/bao/uploaded/i4/TB15KrfFVXXXXXJXXXXXXXXXXXX_!!0-item_pic.jpg_220x220.jpg'
-            }, {
-              shopImgWidth: '220px',
-              shopImgHeight: '220px',
-              shopImg: 'https://gd2.alicdn.com/bao/uploaded/i2/TB1t5YBGVXXXXXcaXXXXXXXXXXX_!!0-item_pic.jpg_220x220.jpg'
-            }],
-            shopLikeImg: 'https://img.alicdn.com/tps/i1/TB1jTxXIVXXXXb8XXXX07tlTXXX-200-200.png_88x88xz.jpg',
-            shopLikeText: '6',
-            shopCommentImg: 'https://img.alicdn.com/tps/i1/TB1kTKyIVXXXXacXFXX07tlTXXX-200-200.png_88x88xz.jpg',
-            shopCommentText: '97',
-            shopLookImg: 'https://img.alicdn.com/imgextra/i4/397746073/TB2IseKeFXXXXcVXXXXXXXXXXXX-397746073.png_88x88xz.jpg',
-            shopLookText: '1003',
-            shareImg: 'https://cbu01.alicdn.com/cms/upload/2015/930/224/2422039_702806130.png_88x88xz.jpg',
-            shareText: "10",
-
-          },
-          {
-            id: 2,
-            scopeValue: 2,
-            PersonPhoto: 'https://gw.alicdn.com/tps/i3/TB1yeWeIFXXXXX5XFXXuAZJYXXX-210-210.png_60x60.jpg',
-            PersonName: 'Napoleon',
-            PersonVisitTime: 'yesterday',
-            shopDesc: 'The man who has made up his mind to win will never say "impossible "',
-            shopImgList: [{
-              shopImgWidth: '220px',
-              shopImgHeight: '220px',
-              shopImg: 'https://gd1.alicdn.com/imgextra/i1/2655929383/TB2.qITjpXXXXcIXXXXXXXXXXXX_!!2655929383.jpg_220x220.jpg'
-            }, {
-              shopImgWidth: '220px',
-              shopImgHeight: '220px',
-              shopImg: 'https://gd3.alicdn.com/imgextra/i3/2655929383/TB2eWwZjpXXXXbHXXXXXXXXXXXX_!!2655929383.jpg_220x220.jpg'
-            }, {
-              shopImgWidth: '220px',
-              shopImgHeight: '220px',
-              shopImg: 'https://gd2.alicdn.com/imgextra/i2/2655929383/TB2tgQWjpXXXXbZXXXXXXXXXXXX_!!2655929383.jpg_220x220.jpg'
-            }],
-            shopLikeImg: 'https://img.alicdn.com/tps/i1/TB1jTxXIVXXXXb8XXXX07tlTXXX-200-200.png_88x88xz.jpg',
-            shopLikeText: '6',
-            shopCommentImg: 'https://img.alicdn.com/tps/i1/TB1kTKyIVXXXXacXFXX07tlTXXX-200-200.png_88x88xz.jpg',
-            shopCommentText: '97',
-            shopLookImg: 'https://img.alicdn.com/imgextra/i4/397746073/TB2IseKeFXXXXcVXXXXXXXXXXXX-397746073.png_88x88xz.jpg',
-            shopLookText: '1003',
-            shareImg: 'https://cbu01.alicdn.com/cms/upload/2015/930/224/2422039_702806130.png_88x88xz.jpg',
-            shareText: "10",
-
-          },
-          {
-            id: 3,
-            scopeValue: 3,
-            PersonPhoto: 'https://gw.alicdn.com/tps/i3/TB1yeWeIFXXXXX5XFXXuAZJYXXX-210-210.png_60x60.jpg',
-            PersonName: 'Balzac',
-            PersonVisitTime: 'yesterday',
-            shopDesc: 'There is no such thing as a great talent without great will - power',
-            shopImgList: [{
-              shopImgWidth: '220px',
-              shopImgHeight: '220px',
-              shopImg: 'https://gd1.alicdn.com/imgextra/i1/TB1AFz9LXXXXXbrXVXXXXXXXXXX_!!0-item_pic.jpg_220x220.jpg'
-            }, {
-              shopImgWidth: '220px',
-              shopImgHeight: '220px',
-              shopImg: 'https://gd2.alicdn.com/imgextra/i2/2557954751/TB2is2njXXXXXatXpXXXXXXXXXX_!!2557954751.jpg_220x220.jpg'
-            }, {
-              shopImgWidth: '220px',
-              shopImgHeight: '220px',
-              shopImg: 'https://gd2.alicdn.com/imgextra/i2/2557954751/TB2PNYGjXXXXXbXXXXXXXXXXXXX_!!2557954751.jpg_220x220.jpg'
-            }],
-            shopLikeImg: 'https://img.alicdn.com/tps/i1/TB1jTxXIVXXXXb8XXXX07tlTXXX-200-200.png_88x88xz.jpg',
-            shopLikeText: '6',
-            shopCommentImg: 'https://img.alicdn.com/tps/i1/TB1kTKyIVXXXXacXFXX07tlTXXX-200-200.png_88x88xz.jpg',
-            shopCommentText: '97',
-            shopLookImg: 'https://img.alicdn.com/imgextra/i4/397746073/TB2IseKeFXXXXcVXXXXXXXXXXXX-397746073.png_88x88xz.jpg',
-            shopLookText: '1003',
-            shareImg: 'https://cbu01.alicdn.com/cms/upload/2015/930/224/2422039_702806130.png_88x88xz.jpg',
-            shareText: "10",
-
-          },
-          {
-            id: 4,
-            scopeValue: 4,
-            PersonPhoto: 'https://gw.alicdn.com/tps/i3/TB1yeWeIFXXXXX5XFXXuAZJYXXX-210-210.png_60x60.jpg',
-            PersonName: 'Thomas Carlyle',
-            PersonVisitTime: '3 day ago',
-            shopDesc: 'Cease to struggle and you cease to live',
-            shopImgList: [{
-              shopImgWidth: '220px',
-              shopImgHeight: '220px',
-              shopImg: 'https://gd4.alicdn.com/imgextra/i4/69426324/TB2zbwdfXXXXXa4XpXXXXXXXXXX_!!69426324.jpg_220x220.jpg'
-            }, {
-              shopImgWidth: '220px',
-              shopImgHeight: '220px',
-              shopImg: 'https://gd4.alicdn.com/imgextra/i4/69426324/TB2L7ZAfXXXXXXOXXXXXXXXXXXX_!!69426324.jpg_220x220.jpg'
-            }, {
-              shopImgWidth: '220px',
-              shopImgHeight: '220px',
-              shopImg: 'https://gd4.alicdn.com/imgextra/i4/69426324/TB2p9wufXXXXXbiXXXXXXXXXXXX_!!69426324.jpg_220x220.jpg'
-            }],
-            shopLikeImg: 'https://img.alicdn.com/tps/i1/TB1jTxXIVXXXXb8XXXX07tlTXXX-200-200.png_88x88xz.jpg',
-            shopLikeText: '6',
-            shopCommentImg: 'https://img.alicdn.com/tps/i1/TB1kTKyIVXXXXacXFXX07tlTXXX-200-200.png_88x88xz.jpg',
-            shopCommentText: '97',
-            shopLookImg: 'https://img.alicdn.com/imgextra/i4/397746073/TB2IseKeFXXXXcVXXXXXXXXXXXX-397746073.png_88x88xz.jpg',
-            shopLookText: '1003',
-            shareImg: 'https://cbu01.alicdn.com/cms/upload/2015/930/224/2422039_702806130.png_88x88xz.jpg',
-            shareText: "10",
-
-          },
-          {
-            id: 5,
-            scopeValue: 5,
-            PersonPhoto: 'https://gw.alicdn.com/tps/i3/TB1yeWeIFXXXXX5XFXXuAZJYXXX-210-210.png_60x60.jpg',
-            PersonName: 'Addison',
-            PersonVisitTime: 'yesterday',
-            shopDesc: 'A strong man will struggle with the storms of fate',
-            shopImgList: [{
-              shopImgWidth: '220px',
-              shopImgHeight: '220px',
-              shopImg: 'https://gd3.alicdn.com/bao/uploaded/i3/TB1MQ8_KVXXXXaLXVXXXXXXXXXX_!!0-item_pic.jpg_220x220.jpg'
-            }, {
-              shopImgWidth: '220px',
-              shopImgHeight: '220px',
-              shopImg: 'https://gd2.alicdn.com/imgextra/i2/53218032/TB2bGSqiXXXXXXyXpXXXXXXXXXX_!!53218032.jpg_220x220.jpg'
-            }, {
-              shopImgWidth: '220px',
-              shopImgHeight: '220px',
-              shopImg: 'https://gd2.alicdn.com/bao/uploaded/i2/TB1kP2zKFXXXXbIXXXXXXXXXXXX_!!0-item_pic.jpg_220x220.jpg'
-            }],
-            shopLikeImg: 'https://img.alicdn.com/tps/i1/TB1jTxXIVXXXXb8XXXX07tlTXXX-200-200.png_88x88xz.jpg',
-            shopLikeText: '6',
-            shopCommentImg: 'https://img.alicdn.com/tps/i1/TB1kTKyIVXXXXacXFXX07tlTXXX-200-200.png_88x88xz.jpg',
-            shopCommentText: '97',
-            shopLookImg: 'https://img.alicdn.com/imgextra/i4/397746073/TB2IseKeFXXXXcVXXXXXXXXXXXX-397746073.png_88x88xz.jpg',
-            shopLookText: '1003',
-            shareImg: 'https://cbu01.alicdn.com/cms/upload/2015/930/224/2422039_702806130.png_88x88xz.jpg',
-            shareText: "10",
-
-          },
-          {
-            id: 6,
-            scopeValue: 1,
-            PersonPhoto: 'https://gw.alicdn.com/tps/i3/TB1yeWeIFXXXXX5XFXXuAZJYXXX-210-210.png_60x60.jpg',
-            PersonName: 'Ruskin',
-            PersonVisitTime: 'yesterday',
-            shopDesc: 'Living without an aim is like sailing without a compass',
-            shopImgList: [{
-              shopImgWidth: '220px',
-              shopImgHeight: '220px',
-              shopImg: 'https://gd4.alicdn.com/bao/uploaded/i4/TB11yFnHXXXXXakaXXXXXXXXXXX_!!0-item_pic.jpg_220x220.jpg'
-            }, {
-              shopImgWidth: '220px',
-              shopImgHeight: '220px',
-              shopImg: 'https://gd4.alicdn.com/imgextra/i4/32720628/TB2CRJUcXXXXXXwXpXXXXXXXXXX_!!32720628.jpg_220x220.jpg'
-            }, {
-              shopImgWidth: '220px',
-              shopImgHeight: '220px',
-              shopImg: 'https://gd2.alicdn.com/bao/uploaded/i2/TB17LUzHXXXXXcEaXXXXXXXXXXX_!!0-item_pic.jpg_220x220.jpg'
-            }],
-            shopLikeImg: 'https://img.alicdn.com/tps/i1/TB1jTxXIVXXXXb8XXXX07tlTXXX-200-200.png_88x88xz.jpg',
-            shopLikeText: '6',
-            shopCommentImg: 'https://img.alicdn.com/tps/i1/TB1kTKyIVXXXXacXFXX07tlTXXX-200-200.png_88x88xz.jpg',
-            shopCommentText: '97',
-            shopLookImg: 'https://img.alicdn.com/imgextra/i4/397746073/TB2IseKeFXXXXcVXXXXXXXXXXXX-397746073.png_88x88xz.jpg',
-            shopLookText: '1003',
-            shareImg: 'https://cbu01.alicdn.com/cms/upload/2015/930/224/2422039_702806130.png_88x88xz.jpg',
-            shareText: "10",
-
-          },
-          {
-            id: 7,
-            scopeValue: 2,
-            PersonPhoto: 'https://gw.alicdn.com/tps/i3/TB1yeWeIFXXXXX5XFXXuAZJYXXX-210-210.png_60x60.jpg',
-            PersonName: 'Yiming',
-            PersonVisitTime: 'today',
-            shopDesc: 'Live a noble and honest life. Reviving past times in your old age will help you to enjoy your life again',
-            shopImgList: [{
-              shopImgWidth: '220px',
-              shopImgHeight: '220px',
-              shopImg: 'https://gd4.alicdn.com/bao/uploaded/i4/TB1hvNoJXXXXXaMaXXXXXXXXXXX_!!0-item_pic.jpg_220x220.jpg'
-            }, {
-              shopImgWidth: '220px',
-              shopImgHeight: '220px',
-              shopImg: 'https://gd4.alicdn.com/imgextra/i4/2058567235/TB2V8iygFXXXXaRXpXXXXXXXXXX_!!2058567235.jpg_220x220.jpg'
-            }, {
-              shopImgWidth: '220px',
-              shopImgHeight: '220px',
-              shopImg: 'https://gd2.alicdn.com/imgextra/i2/2058567235/TB2im1QgFXXXXX8XXXXXXXXXXXX_!!2058567235.jpg_220x220.jpg'
-            }],
-            shopLikeImg: 'https://img.alicdn.com/tps/i1/TB1jTxXIVXXXXb8XXXX07tlTXXX-200-200.png_88x88xz.jpg',
-            shopLikeText: '6',
-            shopCommentImg: 'https://img.alicdn.com/tps/i1/TB1kTKyIVXXXXacXFXX07tlTXXX-200-200.png_88x88xz.jpg',
-            shopCommentText: '97',
-            shopLookImg: 'https://img.alicdn.com/imgextra/i4/397746073/TB2IseKeFXXXXcVXXXXXXXXXXXX-397746073.png_88x88xz.jpg',
-            shopLookText: '1003',
-            shareImg: 'https://cbu01.alicdn.com/cms/upload/2015/930/224/2422039_702806130.png_88x88xz.jpg',
-            shareText: "10",
-
-          },
-          {
-            id: 8,
-            scopeValue: 3,
-            PersonPhoto: 'https://gw.alicdn.com/tps/i3/TB1yeWeIFXXXXX5XFXXuAZJYXXX-210-210.png_60x60.jpg',
-            PersonName: 'Brown',
-            PersonVisitTime: 'yesterday',
-            shopDesc: 'Behind every successful man there\'s a lot u unsuccessful years',
-            shopImgList: [{
-              shopImgWidth: '220px',
-              shopImgHeight: '220px',
-              shopImg: 'https://gd1.alicdn.com/bao/uploaded/i1/TB18BZ2KFXXXXb8XFXXXXXXXXXX_!!0-item_pic.jpg_220x220.jpg'
-            }, {
-              shopImgWidth: '220px',
-              shopImgHeight: '220px',
-              shopImg: 'https://gd1.alicdn.com/imgextra/i1/2775383848/TB2r012jVXXXXXHXpXXXXXXXXXX_!!2775383848.jpg_220x220.jpg'
-            }, {
-              shopImgWidth: '220px',
-              shopImgHeight: '220px',
-              shopImg: 'https://gd3.alicdn.com/imgextra/i3/2775383848/TB2iI9VjVXXXXaoXpXXXXXXXXXX_!!2775383848.jpg_220x220.jpg'
-            }],
-            shopLikeImg: 'https://img.alicdn.com/tps/i1/TB1jTxXIVXXXXb8XXXX07tlTXXX-200-200.png_88x88xz.jpg',
-            shopLikeText: '6',
-            shopCommentImg: 'https://img.alicdn.com/tps/i1/TB1kTKyIVXXXXacXFXX07tlTXXX-200-200.png_88x88xz.jpg',
-            shopCommentText: '97',
-            shopLookImg: 'https://img.alicdn.com/imgextra/i4/397746073/TB2IseKeFXXXXcVXXXXXXXXXXXX-397746073.png_88x88xz.jpg',
-            shopLookText: '1003',
-            shareImg: 'https://cbu01.alicdn.com/cms/upload/2015/930/224/2422039_702806130.png_88x88xz.jpg',
-            shareText: "10",
-
-          },
-          {
-            id: 9,
-            scopeValue: 4,
-            PersonPhoto: 'https://gw.alicdn.com/tps/i3/TB1yeWeIFXXXXX5XFXXuAZJYXXX-210-210.png_60x60.jpg',
-            PersonName: 'YIMING',
-            PersonVisitTime: 'today',
-            shopDesc: 'Enrich your life today,. yesterday is history.tomorrow is mystery',
-            shopImgList: [{
-              shopImgWidth: '220px',
-              shopImgHeight: '220px',
-              shopImg: 'https://gd1.alicdn.com/bao/uploaded/i1/TB1JB.rLpXXXXXLXXXXXXXXXXXX_!!0-item_pic.jpg_220x220.jpg'
-            }, {
-              shopImgWidth: '220px',
-              shopImgHeight: '220px',
-              shopImg: 'https://gd4.alicdn.com/imgextra/i4/2702739128/TB2JdvmjVXXXXXjXXXXXXXXXXXX_!!2702739128.jpg_220x220.jpg'
-            }, {
-              shopImgWidth: '220px',
-              shopImgHeight: '220px',
-              shopImg: 'https://gd2.alicdn.com/imgextra/i2/2702739128/TB2A.e6jVXXXXXGXpXXXXXXXXXX_!!2702739128.jpg_220x220.jpg'
-            }],
-            shopLikeImg: 'https://img.alicdn.com/tps/i1/TB1jTxXIVXXXXb8XXXX07tlTXXX-200-200.png_88x88xz.jpg',
-            shopLikeText: '6',
-            shopCommentImg: 'https://img.alicdn.com/tps/i1/TB1kTKyIVXXXXacXFXX07tlTXXX-200-200.png_88x88xz.jpg',
-            shopCommentText: '97',
-            shopLookImg: 'https://img.alicdn.com/imgextra/i4/397746073/TB2IseKeFXXXXcVXXXXXXXXXXXX-397746073.png_88x88xz.jpg',
-            shopLookText: '1003',
-            shareImg: 'https://cbu01.alicdn.com/cms/upload/2015/930/224/2422039_702806130.png_88x88xz.jpg',
-            shareText: "10",
-
-          },
-          {
-            id: 10,
-            scopeValue: 5,
-            PersonPhoto: 'https://gw.alicdn.com/tps/i3/TB1yeWeIFXXXXX5XFXXuAZJYXXX-210-210.png_60x60.jpg',
-            PersonName: 'YIMING',
-            PersonVisitTime: 'yesterday',
-            shopDesc: 'The secret of success is constancy to purpose',
-            shopImgList: [{
-              shopImgWidth: '220px',
-              shopImgHeight: '220px',
-              shopImg: 'https://gd3.alicdn.com/bao/uploaded/i3/TB17zXOGXXXXXbEXVXXXXXXXXXX_!!0-item_pic.jpg_220x220.jpg'
-            }, {
-              shopImgWidth: '220px',
-              shopImgHeight: '220px',
-              shopImg: 'https://gd1.alicdn.com/imgextra/i1/2265445951/TB22ACTbFXXXXXBXXXXXXXXXXXX_!!2265445951.jpg_220x220.jpg'
-            }, {
-              shopImgWidth: '220px',
-              shopImgHeight: '220px',
-              shopImg: 'https://gd3.alicdn.com/imgextra/i3/2265445951/TB2oXqUbFXXXXXIXXXXXXXXXXXX_!!2265445951.jpg_220x220.jpg'
-            }],
-            shopLikeImg: 'https://img.alicdn.com/tps/i1/TB1jTxXIVXXXXb8XXXX07tlTXXX-200-200.png_88x88xz.jpg',
-            shopLikeText: '6',
-            shopCommentImg: 'https://img.alicdn.com/tps/i1/TB1kTKyIVXXXXacXFXX07tlTXXX-200-200.png_88x88xz.jpg',
-            shopCommentText: '97',
-            shopLookImg: 'https://img.alicdn.com/imgextra/i4/397746073/TB2IseKeFXXXXcVXXXXXXXXXXXX-397746073.png_88x88xz.jpg',
-            shopLookText: '1003',
-            shareImg: 'https://cbu01.alicdn.com/cms/upload/2015/930/224/2422039_702806130.png_88x88xz.jpg',
-            shareText: "10",
-          }
-          ],
-      }
-    },
-    methods: {
-      loadmore: function(e) {
-        modal.toast({
-          'message': 'loadmore',
-          'duration': 2.0
-        });
-      },
-      oncellclick: function(id) {
-        modal.toast({
-          'message': 'row ' + id + ' clicked',
-          'duration': 2.0
-        });
-      }
-    }
-
-  }
-</script>
diff --git a/examples/vue/showcase/new-fashion.vue b/examples/vue/showcase/new-fashion.vue
deleted file mode 100644
index 03b83df..0000000
--- a/examples/vue/showcase/new-fashion.vue
+++ /dev/null
@@ -1,605 +0,0 @@
-<template>
-  <scroller class="content">
-    <refresh class="refresh" @refresh="handleRefresh" :display="displayRefresh"
-      style="flex-direction:row;">
-      <loading-indicator></loading-indicator>
-      <text style="margin-left:36px;color:#eee;">下拉刷新...</text>
-    </refresh>
-    <headlines v-if="show0" :ds="showData.header"></headlines>
-    <category v-if="show0" :ds="showData.category"></category>
-    <coupon v-if="show1" :ds="showData.coupon"></coupon>
-    <goods v-if="show1" :ds="showData.goods"></goods>
-    <resource v-if="show1" :ds="showData.resource"></resource>
-    <scene v-if="show1" :ds="showData.scene"></scene>
-    <match v-if="show2" :ds="showData.match"></match>
-    <brand v-if="show2" :ds="showData.brand"></brand>
-    <loading class="loading" @loading="handleLoading" :display="displayLoading">
-      <text style="color:#eee;">加载更多...</text>
-    </loading>
-  </scroller>
-</template>
-
-<style scoped>
-  .content {
-    color: #353535;
-    background-color: #666;
-    position: absolute;
-    top: 0;
-    left: 0;
-    right: 0;
-    bottom: 0;
-  }
-  .refresh {
-    align-items: center;
-    justify-content: center;
-  }
-  .loading {
-    align-items: center;
-    justify-content: center;
-  }
-</style>
-
-<script>
-  var modal = weex.requireModule('modal')
-  var timer = weex.requireModule('timer')
-
-  module.exports = {
-    components: {
-      headlines: require('./include/headlines.vue'),
-      category: require('./include/category.vue'),
-      coupon: require('./include/coupon.vue'),
-      goods: require('./include/goods.vue'),
-      resource: require('./include/resource.vue'),
-      scene: require('./include/scene.vue'),
-      match: require('./include/match.vue'),
-      brand: require('./include/brand.vue')
-    },
-    data: {
-      navBarHeight: 88,
-      cnt: 0,
-      show0: true,
-      show1: false,
-      show2: false,
-      displayRefresh: 'show',
-      displayLoading: 'show',
-      showData: {}
-    },
-    created: function () {
-      this.showData = {
-        "header": {
-          "topBanner": "https://gw.alicdn.com/tps/TB1J48kMXXXXXXtapXXXXXXXXXX-750-782.jpg",
-          "ruleLink": "https://chaoshi.m.tmall.com/",
-          "isShowShare": true,
-          "shareInfo": {
-            "shareTitle": "我是分享标题",
-            "shareIntro": " 我是分享内容测试",
-            "allLink": "https://www.tmall.com",
-            "mobileImage": "https://gw.alicdn.com/tps/TB1J48kMXXXXXXtapXXXXXXXXXX-750-782.jpg",
-            "pcImage": "https://img.alicdn.com/tps/i4/TB1Dyw1LVXXXXXEapXXSutbFXXX.jpg",
-            "shareScene": "我是测试业务",
-            "bizId": ""
-          },
-          "announceHdBanner": "https://gw.alicdn.com/tps/i4/TB1fzclLVXXXXaVaXXXwu0bFXXX.png",
-          "bannerItems": [{
-            "img": "https://img.alicdn.com/tps/TB1U8LHLVXXXXa3XpXXXXXXXXXX-233-172.jpg",
-            "url": "https://chaoshi.m.tmall.com/"
-          },
-          {
-            "img": "https://img.alicdn.com/tps/TB1U8LHLVXXXXa3XpXXXXXXXXXX-233-172.jpg",
-            "url": "https://chaoshi.m.tmall.com/"
-          },
-          {
-            "img": "https://img.alicdn.com/tps/TB1U8LHLVXXXXa3XpXXXXXXXXXX-233-172.jpg",
-            "url": "https://chaoshi.m.tmall.com/"
-          }]
-        },
-        "fashion": {
-          "isHide": false,
-          "floorTitle": "https://gw.alicdn.com/tps/TB1._64LVXXXXatXVXXXXXXXXXX-750-100.jpg",
-          "bigBannerImg": "https://gw.alicdn.com/tps/TB1tO.aLVXXXXcvXpXXXXXXXXXX-750-262.jpg",
-          "bigBannerUrl": "https://chaoshi.m.tmall.com/",
-          "smallBannerItems": [{
-            "img": "https://img.alicdn.com/tps/TB1Ff_0LVXXXXXNaXXXXXXXXXXX-375-262.jpg",
-            "url": "https://chaoshi.m.tmall.com/"
-          },
-          {
-            "img": "https://img.alicdn.com/tps/TB1Ff_0LVXXXXXNaXXXXXXXXXXX-375-262.jpg",
-            "url": "https://chaoshi.m.tmall.com/"
-          }],
-          "isHideStarBanner": false,
-          "firstStarBannerItems": [{
-            "img": "https://gw.alicdn.com/tps/TB1xlIVLVXXXXckXVXXXXXXXXXX-250-220.jpg",
-            "url": "https://chaoshi.m.tmall.com/"
-          },
-          {
-            "img": "https://gw.alicdn.com/tps/TB1xlIVLVXXXXckXVXXXXXXXXXX-250-220.jpg",
-            "url": "https://chaoshi.m.tmall.com/"
-          }],
-          "secondStarBannerItems": [{
-            "img": "https://gw.alicdn.com/tps/TB1xlIVLVXXXXckXVXXXXXXXXXX-250-220.jpg",
-            "url": "https://chaoshi.m.tmall.com/"
-          },
-          {
-            "img": "https://gw.alicdn.com/tps/TB1xlIVLVXXXXckXVXXXXXXXXXX-250-220.jpg",
-            "url": "https://chaoshi.m.tmall.com/"
-          }],
-          "thirdStarBannerItems": [{
-            "img": "https://gw.alicdn.com/tps/TB1xlIVLVXXXXckXVXXXXXXXXXX-250-220.jpg",
-            "url": "https://chaoshi.m.tmall.com/"
-          },
-          {
-            "img": "https://gw.alicdn.com/tps/TB1xlIVLVXXXXckXVXXXXXXXXXX-250-220.jpg",
-            "url": "https://chaoshi.m.tmall.com/"
-          }]
-        },
-        "goods": {
-          "isHide": false,
-          "floorTitle": "https://gw.alicdn.com/tps/TB1._64LVXXXXatXVXXXXXXXXXX-750-100.jpg",
-          "bannerItems": [{
-            "img1": "https://gw.alicdn.com/tps/TB1TUzGLVXXXXc1XFXXXXXXXXXX-250-296.jpg",
-            "url1": "https://chaoshi.m.tmall.com/",
-            "img2": "https://gw.alicdn.com/tps/TB1TUzGLVXXXXc1XFXXXXXXXXXX-250-296.jpg",
-            "url2": "https://chaoshi.m.tmall.com/",
-            "img3": "https://gw.alicdn.com/tps/TB12MPFLVXXXXXnXVXXXXXXXXXX-250-592.jpg",
-            "url3": "https://chaoshi.m.tmall.com/",
-            "img4": "https://gw.alicdn.com/tps/TB1TUzGLVXXXXc1XFXXXXXXXXXX-250-296.jpg",
-            "url4": "https://chaoshi.m.tmall.com/",
-            "img5": "https://gw.alicdn.com/tps/TB1TUzGLVXXXXc1XFXXXXXXXXXX-250-296.jpg",
-            "url5": "https://chaoshi.m.tmall.com/"
-          },
-          {
-            "img1": "https://gw.alicdn.com/tps/TB1TUzGLVXXXXc1XFXXXXXXXXXX-250-296.jpg",
-            "url1": "https://chaoshi.m.tmall.com/",
-            "img2": "https://gw.alicdn.com/tps/TB1TUzGLVXXXXc1XFXXXXXXXXXX-250-296.jpg",
-            "url2": "https://chaoshi.m.tmall.com/",
-            "img3": "https://gw.alicdn.com/tps/TB12MPFLVXXXXXnXVXXXXXXXXXX-250-592.jpg",
-            "url3": "https://chaoshi.m.tmall.com/",
-            "img4": "https://gw.alicdn.com/tps/TB1TUzGLVXXXXc1XFXXXXXXXXXX-250-296.jpg",
-            "url4": "https://chaoshi.m.tmall.com/",
-            "img5": "https://gw.alicdn.com/tps/TB1TUzGLVXXXXc1XFXXXXXXXXXX-250-296.jpg",
-            "url5": "https://chaoshi.m.tmall.com/"
-          }]
-        },
-        "coupon": {
-          "floorTitle": "https://gw.alicdn.com/tps/TB1._64LVXXXXatXVXXXXXXXXXX-750-100.jpg"
-        },
-        "scene": {
-          "floorTitle": "https://gw.alicdn.com/tps/TB1._64LVXXXXatXVXXXXXXXXXX-750-100.jpg",
-          "_backup": {
-            "id": "03653",
-            "data": [{
-              "id": "1395",
-              "sceneUrl": "https://pages.tmall.com/wow/act/15617/scene?acm=03653.1003.1.710531&aldid=TPMkJDIw&wh_id=1395&scm=1003.1.03653.MAIN_1395_710531&pos=1",
-              "_s_": "d",
-              "itemImg": "//img.alicdn.com/tps/i2/TB1n6bVLVXXXXcCXVXXTCU0QpXX-300-300.jpg",
-              "sceneCat": "50008881,50008883,50008882,50008884,50012774,50012775,50012776,50012781,50008886,50012766,50012771,50012772,50010850,50000671,162201,50022566,50007068,50026651,50000852,162104,162116,162205,1623,123216004,162404,162401,50011412,50011411,16240,50012773,50006846,50010394,50008888,50008890,50008889,50012784,50012785,50012786,50012787,50008885,50012777,50012778,124730001,50001748,50011130,124730001,50001748,50011130,50011129,50010160,50011161,50011159,50010159,50010158,50011127,3035,50010167,50000557,50011123,50010402,50000436,50011153,50011740,50006843,50006842,124942005,50010368,50011892,50011894,50023751,121366037,121458036,121392038,121420035,121364028,121468026,121400029,121418030,121478031,121480030,121366035,121424025,121426030,121484030,121412031,125054002,125074007,125074008,125104003,125080003,125024006,125080004,121400030,121424024,121482025,121418031,121402028,121388035",
-              "finalScore": "77.26011111111112",
-              "_pos_": 1,
-              "entityType": "MAIN",
-              "benefitImg": "//img.alicdn.com/tps/i3/TB1Onr9LVXXXXbiXpXXB8gAQpXX-300-100.png",
-            },
-            {
-              "id": "1394",
-              "sceneUrl": "https://pages.tmall.com/wow/act/15617/scene?acm=03653.1003.1.710531&aldid=TPMkJDIw&wh_id=1394&scm=1003.1.03653.MAIN_1394_710531&pos=2",
-              "_s_": "d",
-              "itemImg": "//img.alicdn.com/tps/i1/TB13mj1LVXXXXa.XFXXTCU0QpXX-300-300.jpg",
-              "sceneCat": "50010850,50000671,162201,50022566,50007068,50026651,50000852,162104,162116,162205,1623,123216004,162404,162401,50011412,50011411,162402,50008903,50011413,162403,50000697,1629,50011277,121412004,50008897,50008901,50008899,50013194,50008904,50008905,50008898,162103,50008900,50013196,121434004,50005065,162702,162701,162703,1636,124730001,50001748,50011130,124730001,50001748,50011130,50011129,50010160,50011161,50011159,50010159,50010158,50011127,3035,50010167,50000557,50011123,50010402,50000436,50011153,50011740,50006843,50006842,124986002,50010368, 50011892,50011894,121480030,121366035,121424025,121426030,121484030,121412031",
-              "finalScore": "77.06103999999999",
-              "_pos_": 2,
-              "entityType": "MAIN",
-              "benefitImg": "//img.alicdn.com/tps/i2/TB17kvVLVXXXXaTXVXXB8gAQpXX-300-100.png",
-            },
-            {
-              "id": "1396",
-              "sceneUrl": "https://pages.tmall.com/wow/act/15617/scene?acm=03653.1003.1.710531&aldid=TPMkJDIw&wh_id=1396&scm=1003.1.03653.MAIN_1396_710531&pos=3",
-              "_s_": "d",
-              "itemImg": "//img.alicdn.com/tps/i2/TB1ZOAXLVXXXXa0XXXXTCU0QpXX-300-300.jpg",
-              "sceneCat": "50010368,50011892,50011894,50013794,50010792,50010790,50010790,121434025,121396024,50010793,50010789,50010793,121386035,121392037,121458034,121392036,121482027,121392015,121368014,121418013,121392016,50011982,122690003,302910,50012010,122654005,50012019,50012825,50012027,50012042,50011744,50012906,50012907,50008881,50008883,50008882?,50012784?,50022889,50022728,50013228,50013896,50014775,50019578,50014822,50026394,50019694,50019279,50019272,50014079,50014078,50014076,50014077,50017238,121464011,121468014,50019130,50019127,50019126,50019128,50019125,50015984,50014803,50014802,50015980,50014788,50014787,50019526,50014791,50019520,50013932,50014677,50015978,50014786,50014785,50522001,50014493,50023100,121418021,121388027,121424021,121418020,121368020,50012036,50012044,50012043,50010368, 50011892, 50019274,50012044,50012048,50012043,50013228,50013238,50011726,50019279,50015984,50014803,50014802,50019526,50014791,50019520,50013932,50014677,50019526,50013314,50023341,50016752,50016749,50016747,50016744,50016741,50016740,50016739,50016738,50016737,50016769,50016763,50016750,50007003,302910,50012010,50012032,50012033,50011745,50011746,50011894,121458034,121756003,121426033,50011982,50011979,121390006,124730001,50001748,50011130,124730001,50001748,50011130,50011129,50010160,50011161,50011159,50010159,50010158,50011127,3035,50010167,50000557,50011123,50010402,50000436,50011153,50010850,50000671,162201,50022566,50007068,50026651,50000852,162104,162116,162205,1623,123216004,162404,162401,50011412,50011411,162402,50008903,50011413,162403,50000697,1629,50011277,121412004,50008897,50008901,50008899,50013194,50008904,50008905,50008898,162103,50008900,50013196,121434004,50005065,162702,162701,162703,1636,1512,123534001,14,50008090,50012341,50132002,50012342,50012343,50012345,50012346,50013189,50010527,121394006,50013618,50010537,50012424,121452038,121484044,50010540,50010548,50024769,121450007,50013697,50010218,50005960,50005962,50012820,50012406,50023620,50023605,50008829,50024064,50023440,50008687,124392001,50023771,50006804,50012410,124482010,121398023,50023789,50011975",
-              "finalScore": "76.76379487179486",
-              "_pos_": 3,
-              "entityType": "MAIN",
-              "benefitImg": "//img.alicdn.com/tps/i3/TB1Usn.LVXXXXaoXpXXB8gAQpXX-300-100.png",
-            },
-            {
-              "id": "1619",
-              "sceneUrl": "https://pages.tmall.com/wow/act/15617/scene?acm=03653.1003.1.710531&aldid=TPMkJDIw&wh_id=1619&scm=1003.1.03653.SUB_1619_710531&pos=4",
-              "_s_": "d",
-              "itemImg": "//img.alicdn.com/tps/i2/TB1MpoBLVXXXXbxXpXXKofZZpXX-182-206.jpg",
-              "sceneCat": "124730001,50001748,50011130,124730001,50001748,50011130,50011129,50010160,50011161,50011159,50010159,50010158,50011127,3035,50010167,50000557,50011123,50010402,50000436,50011153,122654005,50011740,50009032,124688012,213202,121396029,121476023,121410029,213203,50023326,213205,50022686,50023293,50466023,50024999,50016885,50011894",
-              "finalScore": "75.88480000000001",
-              "_pos_": 4,
-              "entityType": "SUB",
-              "benefitImg": "//img.alicdn.com/tps/i4/TB1j0AxLVXXXXaRXFXX3bpXTXXX-170-100.png",
-            },
-            {
-              "id": "1612",
-              "sceneUrl": "https://pages.tmall.com/wow/act/15617/scene?acm=03653.1003.1.710531&aldid=TPMkJDIw&wh_id=1612&scm=1003.1.03653.SUB_1612_710531&pos=5",
-              "_s_": "d",
-              "itemImg": "//img.alicdn.com/tps/i3/TB1NNwyLVXXXXaEXVXXKofZZpXX-182-206.jpg",
-              "sceneCat": "50010850,50000671,162104,162116,123216004",
-              "finalScore": "75.23733333333334",
-              "_pos_": 5,
-              "entityType": "SUB",
-              "benefitImg": "//img.alicdn.com/tps/i1/TB1PsoBLVXXXXbQXpXX3bpXTXXX-170-100.png",
-            },
-            {
-              "id": "1610",
-              "sceneUrl": "https://pages.tmall.com/wow/act/15617/scene?acm=03653.1003.1.710531&aldid=TPMkJDIw&wh_id=1610&scm=1003.1.03653.SUB_1610_710531&pos=6",
-              "_s_": "d",
-              "itemImg": "//img.alicdn.com/tps/i4/TB1EkczLVXXXXcVXpXXKofZZpXX-182-206.jpg",
-              "sceneCat": "121484044,121452038,50012342,50012027,50012032,50006843,50010850,50000671,162104,1623,50011277,162116,123216004,50008898,121366037,121458036,121392038,121420035,121364028,121468026,121472031,121476036,121470042,121418032,121410036,121472032,121420032,121470040,121384032,121460028,121448028,121400030,121424024,121482025,121418031,121402028,121388035,121460029,121400028,121400029,121418030,121476034,121478031,121448029,121480030,121366035,121424025,121426030,121484030,121412031,121384033,121424023,121402027,121408039,121420033,121452028,121466040,121416029,121482028,121420034,121396046,121422052,121370037,121424031,21364043,121472040,121412045,121424032,125054002,125074007,125074008,125104003,125080003,125024006,125080004",
-              "finalScore": "75.00533333333334",
-              "_pos_": 6,
-              "entityType": "SUB",
-              "benefitImg": "//img.alicdn.com/tps/i2/TB1RzwFLVXXXXXsXpXX3bpXTXXX-170-100.png",
-            },
-            {
-              "id": "1620",
-              "sceneUrl": "https://pages.tmall.com/wow/act/15617/scene?acm=03653.1003.1.710531&aldid=TPMkJDIw&wh_id=1620&scm=1003.1.03653.SUB_1620_710531&pos=7",
-              "_s_": "d",
-              "itemImg": "//img.alicdn.com/tps/i1/TB1IJsILVXXXXbGXXXXKofZZpXX-182-206.jpg",
-              "sceneCat": "50010789,50010790,50010792,50010793,50010794,50010796,50010797,50010798,50010801,50010803,50010805,50010807,50010808,50010813,50010814,50010815,50013794,121382014,121386023,121388007,121388008,121398004,121364007,121398006,121410007,121426007,121452004,50012010,50012027,50012032,124688012, 124986002, 124942005,50010850,50000671,162104,162201,50022566,162116,1623,50011277,50008897,162401,162402",
-              "finalScore": "74.72522222222223",
-              "_pos_": 7,
-              "entityType": "SUB",
-              "benefitImg": "//img.alicdn.com/tps/i1/TB16A.yLVXXXXX8XFXX3bpXTXXX-170-100.png",
-            },
-            {
-              "id": "1608",
-              "sceneUrl": "https://pages.tmall.com/wow/act/15617/scene?acm=03653.1003.1.710531&aldid=TPMkJDIw&wh_id=1608&scm=1003.1.03653.SUB_1608_710531&pos=8",
-              "_s_": "d",
-              "itemImg": "//img.alicdn.com/tps/i3/TB1xA3jLVXXXXXqapXXKofZZpXX-182-206.jpg",
-              "sceneCat": "50012010,50012027,50012032,50007003,50008881,50008883,1623,162116,50010850,123216004",
-              "finalScore": "74.626",
-              "_pos_": 8,
-              "entityType": "SUB",
-              "benefitImg": "//img.alicdn.com/tps/i2/TB1WvoALVXXXXcdXpXX3bpXTXXX-170-100.png",
-            },
-            {
-              "id": "1615",
-              "sceneUrl": "https://pages.tmall.com/wow/act/15617/scene?acm=03653.1003.1.710531&aldid=TPMkJDIw&wh_id=1615&scm=1003.1.03653.SUB_1615_710531&pos=9",
-              "_s_": "d",
-              "itemImg": "//img.alicdn.com/tps/i1/TB1PVctLVXXXXchXFXXKofZZpXX-182-206.jpg",
-              "sceneCat": "50011978,50011979,50011980,50011993,50011996,50011997,121390006,121408011,121474010,50010789,50010790,50010792,50010793,50010803,50013794,121398004,121410007,213205,121470030,50024980,121408030",
-              "finalScore": "74.02799999999999",
-              "_pos_": 9,
-              "entityType": "SUB",
-              "benefitImg": "//img.alicdn.com/tps/i4/TB1yKwBLVXXXXa4XpXX3bpXTXXX-170-100.png",
-            },
-            {
-              "id": "1618",
-              "sceneUrl": "https://pages.tmall.com/wow/act/15617/scene?acm=03653.1003.1.710531&aldid=TPMkJDIw&wh_id=1618&scm=1003.1.03653.SUB_1618_710531&pos=10",
-              "_s_": "d",
-              "itemImg": "//img.alicdn.com/tps/i1/TB1vn3sLVXXXXX5XVXXKofZZpXX-182-206.jpg",
-              "sceneCat": "50008886,50012766,50012771,50012772,50012773,50008090,111219,50012100,50012082,50012478,50012475,213202,50018977,121396029,121476023,50018994,121410029,213203,50023326,50003820,213205,50022686,50012481,50013976?,50001871,122854005,121458010,121452006,121416008,50008779,50002777,121394007,121386009,50010825,50013810,121434010,50001865,50008565,50008246,50017192,121404045,121368009,121462014,50019372,50008248,121418011,50008249,50017193,50008252,50008251,50000512,121364047",
-              "finalScore": "73.94212121212121",
-              "_pos_": 10,
-              "entityType": "SUB",
-              "benefitImg": "//img.alicdn.com/tps/i4/TB1kSkpLVXXXXbTXVXX3bpXTXXX-170-100.png",
-            },
-            {
-              "id": "1617",
-              "sceneUrl": "https://pages.tmall.com/wow/act/15617/scene?acm=03653.1003.1.710531&aldid=TPMkJDIw&wh_id=1617&scm=1003.1.03653.SUB_1617_710531&pos=11",
-              "_s_": "d",
-              "itemImg": "//img.alicdn.com/tps/i1/TB1ELwrLVXXXXaNXVXXKofZZpXX-182-206.jpg",
-              "sceneCat": "50013189,50010527,121394006,50013618,50010537,50012424,121452038,121484044,50010540,50010548,50024769,50012341,50132002,50012342,50012343,50012345,50012346,50012341,50132002,50012342,50012343,50012345,50012346",
-              "finalScore": "73.78883333333334",
-              "_pos_": 11,
-              "entityType": "SUB",
-              "benefitImg": "//img.alicdn.com/tps/i3/TB1CtsuLVXXXXcJXFXX3bpXTXXX-170-100.png",
-            }],
-            "exposureParam": "//ac.mmstat.com/1.gif?apply=vote&abbucket=_AB-M1001_B5&com=02&acm=03653.1003.1.710531&cod=03653&cache=jWl8FJsb&aldid=TPMkJDIw&logtype=4&abtest=_AB-LR1001-PR1001&scm=1003.1.03653.710531&ip=42.120.74.104",
-            "serverTime": 1458296110334
-          }
-        },
-        "resource": {
-          "isHide": false,
-          "bigBannerImg": "https://gw.alicdn.com/tps/TB1tO.aLVXXXXcvXpXXXXXXXXXX-750-262.jpg",
-          "bigBannerUrl": "https://chaoshi.m.tmall.com/",
-          "smallBannerItems": [{
-            "img": "https://img.alicdn.com/tps/TB1Ff_0LVXXXXXNaXXXXXXXXXXX-375-262.jpg",
-            "url": "https://chaoshi.m.tmall.com/"
-          },
-          {
-            "img": "https://img.alicdn.com/tps/TB1Ff_0LVXXXXXNaXXXXXXXXXXX-375-262.jpg",
-            "url": "https://chaoshi.m.tmall.com/"
-          }]
-        },
-        "category": {
-          "floorTitle": "https://gw.alicdn.com/tps/TB1._64LVXXXXatXVXXXXXXXXXX-750-100.jpg",
-          "_backup": {
-            "main": [],
-            "sub": [{
-              "finalScore": 0,
-              "industryUrl": "//pages.tmall.com/wow/act/15617/dqc?abbucket=_AB-M1011_B5&acm=03654.1003.1.735362&aldid=e5zPEI6R&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.OTHER_15_735362&pos=1",
-              "entityType": "OTHER",
-              "colour": "b4ebff",
-              "industryTitle": "数码",
-              "_pos_": 1,
-              "industryBenefit": "疯抢大牌新品",
-              "industryId": "15",
-              "industryImg": "//img.alicdn.com/tps/i4/TB1_xG.LVXXXXbWaXXXrdvGIFXX-248-155.jpg"
-            },
-            {
-              "finalScore": 0,
-              "industryUrl": "//pages.tmall.com/wow/act/15617/xihu?abbucket=_AB-M1011_B5&acm=03654.1003.1.735362&aldid=e5zPEI6R&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.OTHER_13_735362&pos=2",
-              "entityType": "OTHER",
-              "colour": "cdffa4",
-              "industryTitle": "洗护",
-              "_pos_": 2,
-              "industryBenefit": "爆款1分钱抢",
-              "industryId": "13",
-              "industryImg": "//img.alicdn.com/tps/i3/TB1Ft_CLVXXXXX2XXXXrdvGIFXX-248-155.jpg"
-            },
-            {
-              "finalScore": 0,
-              "industryUrl": "//pages.tmall.com/wow/act/15617/mobilephone?abbucket=_AB-M1011_B5&acm=03654.1003.1.735362&aldid=e5zPEI6R&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.OTHER_14_735362&pos=3",
-              "entityType": "OTHER",
-              "colour": "c5ffdf",
-              "industryTitle": "手机",
-              "_pos_": 3,
-              "industryBenefit": "1元抢优惠券",
-              "industryId": "14",
-              "industryImg": "//img.alicdn.com/tps/i3/TB1mJjuLVXXXXc.XXXXrdvGIFXX-248-155.jpg"
-            },
-            {
-              "finalScore": 0,
-              "industryUrl": "//pages.tmall.com/wow/act/15617/xiangbaohuanxin?abbucket=_AB-M1011_B5&acm=03654.1003.1.735362&aldid=e5zPEI6R&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.OTHER_11_735362&pos=4",
-              "entityType": "OTHER",
-              "colour": "ffccdc",
-              "industryTitle": "箱包",
-              "_pos_": 4,
-              "industryBenefit": "极致焕新尖货",
-              "industryId": "11",
-              "industryImg": "//img.alicdn.com/tps/i2/TB1_5P9KVXXXXayaXXXrdvGIFXX-248-155.jpg"
-            },
-            {
-              "finalScore": 0,
-              "industryUrl": "//pages.tmall.com/wow/act/15617/newfood?abbucket=_AB-M1011_B5&acm=03654.1003.1.735362&aldid=e5zPEI6R&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.OTHER_12_735362&pos=5",
-              "entityType": "OTHER",
-              "colour": "fff5a3",
-              "industryTitle": "食品",
-              "_pos_": 5,
-              "industryBenefit": "新品1分试吃",
-              "industryId": "12",
-              "industryImg": "//img.alicdn.com/tps/i2/TB1HfLzLVXXXXb_XXXXrdvGIFXX-248-155.jpg"
-            },
-            {
-              "finalScore": 0,
-              "industryUrl": "//pages.tmall.com/wow/act/15617/zbps?abbucket=_AB-M1011_B5&acm=03654.1003.1.735362&aldid=e5zPEI6R&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.OTHER_3_735362&pos=6",
-              "entityType": "OTHER",
-              "colour": "bbffe5",
-              "industryTitle": "珠宝配饰",
-              "_pos_": 6,
-              "industryBenefit": "大牌1折秒杀",
-              "industryId": "3",
-              "industryImg": "//img.alicdn.com/tps/i1/TB1s5y.LVXXXXb.aXXXrdvGIFXX-248-155.jpg"
-            },
-            {
-              "finalScore": 0,
-              "industryUrl": "//pages.tmall.com/wow/act/15617/getbeauty?abbucket=_AB-M1011_B5&acm=03654.1003.1.735362&aldid=e5zPEI6R&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.OTHER_2_735362&pos=7",
-              "entityType": "OTHER",
-              "colour": "ffd1b6",
-              "industryTitle": "美妆",
-              "_pos_": 7,
-              "industryBenefit": "即刻预约美丽",
-              "industryId": "2",
-              "industryImg": "//img.alicdn.com/tps/i1/TB1lNvoLVXXXXaoXFXXrdvGIFXX-248-155.jpg"
-            },
-            {
-              "finalScore": 0,
-              "industryUrl": "//pages.tmall.com/wow/act/15617/guojixfs?abbucket=_AB-M1011_B5&acm=03654.1003.1.735362&aldid=e5zPEI6R&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.OTHER_1_735362&pos=8",
-              "entityType": "OTHER",
-              "colour": "b9eaf2",
-              "industryTitle": "天猫国际",
-              "_pos_": 8,
-              "industryBenefit": "唤醒全球潮流",
-              "industryId": "1",
-              "industryImg": "//img.alicdn.com/tps/i4/TB1JHbkLVXXXXblXFXXrdvGIFXX-248-155.jpg"
-            },
-            {
-              "finalScore": 0,
-              "industryUrl": "//pages.tmall.com/wow/act/15617/newnv?abbucket=_AB-M1011_B5&acm=03654.1003.1.735362&aldid=e5zPEI6R&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.OTHER_10_735362&pos=9",
-              "entityType": "OTHER",
-              "colour": "fff8ee",
-              "industryTitle": "鞋履",
-              "_pos_": 9,
-              "industryBenefit": "潮品精选鞋履",
-              "industryId": "10",
-              "industryImg": "//img.alicdn.com/tps/i2/TB1RovwLVXXXXXnXpXXrdvGIFXX-248-155.jpg"
-            },
-            {
-              "finalScore": 0,
-              "industryUrl": "//pages.tmall.com/wow/act/15617/nvzhuang?abbucket=_AB-M1011_B5&acm=03654.1003.1.735362&aldid=e5zPEI6R&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.OTHER_7_735362&pos=10",
-              "entityType": "OTHER",
-              "colour": "d5cbe8",
-              "industryTitle": "女装",
-              "_pos_": 10,
-              "industryBenefit": "折后用券抢新",
-              "industryId": "7",
-              "industryImg": "//img.alicdn.com/tps/i1/TB1BOncLVXXXXXSaXXXrdvGIFXX-248-155.jpg"
-            },
-            {
-              "finalScore": 0,
-              "industryUrl": "//pages.tmall.com/wow/act/15617/man?abbucket=_AB-M1011_B5&acm=03654.1003.1.735362&aldid=e5zPEI6R&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.OTHER_6_735362&pos=11",
-              "entityType": "OTHER",
-              "colour": "cbe9a9",
-              "industryTitle": "男装",
-              "_pos_": 11,
-              "industryBenefit": "新品低至9.9元",
-              "industryId": "6",
-              "industryImg": "//img.alicdn.com/tps/i4/TB1t9TmLVXXXXbkXFXXrdvGIFXX-248-155.jpg"
-            },
-            {
-              "finalScore": 0,
-              "industryUrl": "//pages.tmall.com/wow/act/15617/myxfs?abbucket=_AB-M1011_B5&acm=03654.1003.1.735362&aldid=e5zPEI6R&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.OTHER_5_735362&pos=12",
-              "entityType": "OTHER",
-              "colour": "f8e1ff",
-              "industryTitle": "母婴童装",
-              "_pos_": 12,
-              "industryBenefit": "跨店满299减40",
-              "industryId": "5",
-              "industryImg": "//img.alicdn.com/tps/i3/TB1kpziLVXXXXabXVXXrdvGIFXX-248-155.jpg"
-            },
-            {
-              "finalScore": 0,
-              "industryUrl": "//pages.tmall.com/wow/act/15617/jfjs?abbucket=_AB-M1011_B5&acm=03654.1003.1.735362&aldid=e5zPEI6R&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.OTHER_4_735362&pos=13",
-              "entityType": "OTHER",
-              "colour": "bbffe5",
-              "industryTitle": "家纺家饰",
-              "_pos_": 13,
-              "industryBenefit": "全场低至9.9元",
-              "industryId": "4",
-              "industryImg": "//img.alicdn.com/tps/i1/TB1lUjzLVXXXXbAXXXXrdvGIFXX-248-155.jpg"
-            },
-            {
-              "finalScore": 0,
-              "industryUrl": "//pages.tmall.com/wow/act/15617/neiyi328?abbucket=_AB-M1011_B5&acm=03654.1003.1.735362&aldid=e5zPEI6R&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.OTHER_9_735362&pos=14",
-              "entityType": "OTHER",
-              "colour": "ffc7c9",
-              "industryTitle": "内衣",
-              "_pos_": 14,
-              "industryBenefit": "新品3折起",
-              "industryId": "9",
-              "industryImg": "//img.alicdn.com/tps/i1/TB1S7PuLVXXXXcVXXXXrdvGIFXX-248-155.jpg"
-            },
-            {
-              "finalScore": 0,
-              "industryUrl": "//pages.tmall.com/wow/act/15617/ydhw?abbucket=_AB-M1011_B5&acm=03654.1003.1.735362&aldid=e5zPEI6R&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.OTHER_8_735362&pos=15",
-              "entityType": "OTHER",
-              "colour": "cbdbfe",
-              "industryTitle": "运动户外",
-              "_pos_": 15,
-              "industryBenefit": "大牌新品抢券",
-              "industryId": "8",
-              "industryImg": "//img.alicdn.com/tps/i2/TB1mQDALVXXXXbdXXXXrdvGIFXX-248-155.jpg"
-            }],
-            "isFormal": false,
-            "exposureParam": "//ac.mmstat.com/1.gif?apply=vote&abbucket=_AB-M1011_B5&com=02&acm=03654.1003.1.735362&cod=03654&cache=CG5ZB02B&aldid=e5zPEI6R&logtype=4&abtest=_AB-LR1011-PR1011&scm=1003.1.03654.735362&ip=42.120.74.159",
-            "id": "03654"
-          }
-        },
-        "brand": {
-          "floorTitle": "https://gw.alicdn.com/tps/TB1._64LVXXXXatXVXXXXXXXXXX-750-100.jpg",
-          "bannerItems": [{
-            "leftImg": "https://gw.alicdn.com/tps/TB1F2fJLVXXXXccXFXXXXXXXXXX-750-230.jpg",
-            "leftUrl": "https://chaoshi.m.tmall.com/",
-            "rightImg": "https://gw.alicdn.com/tps/TB1F2fJLVXXXXccXFXXXXXXXXXX-750-230.jpg",
-            "rightUrl": "https://chaoshi.m.tmall.com/"
-          },
-          {
-            "leftImg": "https://gw.alicdn.com/tps/TB1F2fJLVXXXXccXFXXXXXXXXXX-750-230.jpg",
-            "leftUrl": "https://chaoshi.m.tmall.com/",
-            "rightImg": "https://gw.alicdn.com/tps/TB1F2fJLVXXXXccXFXXXXXXXXXX-750-230.jpg",
-            "rightUrl": "https://chaoshi.m.tmall.com/"
-          },
-          {
-            "leftImg": "https://gw.alicdn.com/tps/TB1F2fJLVXXXXccXFXXXXXXXXXX-750-230.jpg",
-            "leftUrl": "https://chaoshi.m.tmall.com/",
-            "rightImg": "https://gw.alicdn.com/tps/TB1F2fJLVXXXXccXFXXXXXXXXXX-750-230.jpg",
-            "rightUrl": "https://chaoshi.m.tmall.com/"
-          },
-          {
-            "leftImg": "https://gw.alicdn.com/tps/TB1F2fJLVXXXXccXFXXXXXXXXXX-750-230.jpg",
-            "leftUrl": "https://chaoshi.m.tmall.com/",
-            "rightImg": "https://gw.alicdn.com/tps/TB1F2fJLVXXXXccXFXXXXXXXXXX-750-230.jpg",
-            "rightUrl": "https://chaoshi.m.tmall.com/"
-          },
-          {
-            "leftImg": "https://gw.alicdn.com/tps/TB1F2fJLVXXXXccXFXXXXXXXXXX-750-230.jpg",
-            "leftUrl": "https://chaoshi.m.tmall.com/",
-            "rightImg": "https://gw.alicdn.com/tps/TB1F2fJLVXXXXccXFXXXXXXXXXX-750-230.jpg",
-            "rightUrl": "https://chaoshi.m.tmall.com/"
-          },
-          {
-            "leftImg": "https://gw.alicdn.com/tps/TB1F2fJLVXXXXccXFXXXXXXXXXX-750-230.jpg",
-            "leftUrl": "https://chaoshi.m.tmall.com/",
-            "rightImg": "https://gw.alicdn.com/tps/TB1F2fJLVXXXXccXFXXXXXXXXXX-750-230.jpg",
-            "rightUrl": "https://chaoshi.m.tmall.com/"
-          },
-          {
-            "leftImg": "https://gw.alicdn.com/tps/TB1F2fJLVXXXXccXFXXXXXXXXXX-750-230.jpg",
-            "leftUrl": "https://chaoshi.m.tmall.com/",
-            "rightImg": "https://gw.alicdn.com/tps/TB1F2fJLVXXXXccXFXXXXXXXXXX-750-230.jpg",
-            "rightUrl": "https://chaoshi.m.tmall.com/"
-          },
-          {
-            "leftImg": "https://gw.alicdn.com/tps/TB1F2fJLVXXXXccXFXXXXXXXXXX-750-230.jpg",
-            "leftUrl": "https://chaoshi.m.tmall.com/",
-            "rightImg": "https://gw.alicdn.com/tps/TB1F2fJLVXXXXccXFXXXXXXXXXX-750-230.jpg",
-            "rightUrl": "https://chaoshi.m.tmall.com/"
-          },
-          {
-            "leftImg": "https://gw.alicdn.com/tps/TB1F2fJLVXXXXccXFXXXXXXXXXX-750-230.jpg",
-            "leftUrl": "https://chaoshi.m.tmall.com/",
-            "rightImg": "https://gw.alicdn.com/tps/TB1F2fJLVXXXXccXFXXXXXXXXXX-750-230.jpg",
-            "rightUrl": "https://chaoshi.m.tmall.com/"
-          }]
-        },
-        "match": {
-          "floorTitle": "https://gw.alicdn.com/tps/TB1._64LVXXXXatXVXXXXXXXXXX-750-100.jpg",
-          "isShowTmSpecBanner": true,
-          "tmSpecBanner": {
-            "img": "https://gw.alicdn.com/tps/TB1F2fJLVXXXXccXFXXXXXXXXXX-750-230.jpg",
-            "url": "https://chaoshi.m.tmall.com/"
-          },
-          "bannerItems": [{
-            "leftImg": "https://gw.alicdn.com/tps/TB1OUnILVXXXXcoXFXXXXXXXXXX-374-416.jpg",
-            "leftUrl": "https://chaoshi.m.tmall.com/",
-            "rightImg": "https://gw.alicdn.com/tps/TB1OUnILVXXXXcoXFXXXXXXXXXX-374-416.jpg",
-            "rightUrl": "https://chaoshi.m.tmall.com/"
-          },
-          {
-            "leftImg": "https://gw.alicdn.com/tps/TB1OUnILVXXXXcoXFXXXXXXXXXX-374-416.jpg",
-            "leftUrl": "https://chaoshi.m.tmall.com/",
-            "rightImg": "https://gw.alicdn.com/tps/TB1OUnILVXXXXcoXFXXXXXXXXXX-374-416.jpg",
-            "rightUrl": "https://chaoshi.m.tmall.com/"
-          }]
-        }
-      }
-      this.simLoadingData(this.cnt++)
-    },
-    methods: {
-      handleRefresh: function (e) {
-        var vm = this
-        vm.displayRefresh = 'show'
-        if (timer) {
-          timer.setTimeout(function () {
-            vm.displayRefresh = 'hide'
-          }, 2000)
-        } else {
-          modal.alert({
-            message: 'refreshing.'
-          }, function () {
-            vm.displayRefresh = 'hide'
-          })
-        }
-      },
-      handleLoading: function (e) {
-        var vm = this
-        vm.displayLoading = 'show'
-        modal.toast({
-          message: 'loading.'
-        })
-        if (timer) {
-          timer.setTimeout(function () {
-            vm.simLoadingData(vm.cnt++)
-            vm.displayLoading = 'hide'
-          }, 2000)
-        } else {
-          vm.simLoadingData(vm.cnt++)
-          vm.displayLoading = 'hide'
-        }
-      },
-      simLoadingData: function (num) {
-        if (num >= 3) {
-          modal.toast({
-            message: '已到底部'
-          })
-          return
-        }
-        this['show' + num] = true
-      }
-    }
-  };
-</script>
diff --git a/examples/vue/showcase/progress.vue b/examples/vue/showcase/progress.vue
deleted file mode 100644
index 8311bcf..0000000
--- a/examples/vue/showcase/progress.vue
+++ /dev/null
@@ -1,44 +0,0 @@
-<template>
-  <scroller>
-    <panel title="Basic" type="primary">
-      <div
-        :style="{
-          width: fullW,
-          borderColor: '#333',
-          borderWidth: 1,
-          borderStyle: 'solid'
-        }">
-        <div
-          :style="{
-            width: w,
-            height: 60,
-            backgroundColor: '#333'
-          }"></div>
-      </div>
-    </panel>
-  </scroller>
-</template>
-
-<script>
-  var INC = 20;
-  module.exports = {
-    data: function () {
-      return {
-        fullW: 600,
-        w: 40
-      }
-    },
-    components: {
-      panel: require('../include/panel.vue')
-    },
-    created: function() {
-      var me = this;
-      setInterval(function () {
-        if (me.w >= me.fullW) {
-          me.w = 0
-        }
-        me.w = (me.w + INC >= me.fullW) ? me.fullW : me.w + INC
-      }, 33);
-    }
-  }
-</script>
diff --git a/examples/vue/showcase/tap-penetrate.vue b/examples/vue/showcase/tap-penetrate.vue
deleted file mode 100644
index d6ac160..0000000
--- a/examples/vue/showcase/tap-penetrate.vue
+++ /dev/null
@@ -1,206 +0,0 @@
-<template>
-  <div>
-  <div class="items-box">
-    <a weex-type="a" class="items" @click="clickitem('Tap1')">
-      <text class="text">Tap1</text>
-    </a>
-    <a weex-type="a" class="items" @click="clickitem('Tap2')">
-      <text class="text">Tap2</text>
-    </a>
-  </div>
-  <div class="items-box">
-    <a weex-type="a" class="items" @click="clickitem('Tap in the a tag')" href="http://weex.apache.org/cn/references/" target="_blank">
-      <text class="text">Tap in the A tag</text>
-    </a>
-    <a weex-type="a" class="items" @click="preventDefault" :href="href" target="_blank">
-      <text class="text">Prevent A tag from href jumping</text>
-    </a>
-  </div>
-  <div class="items-box">
-    <a weex-type="a" class="items" href="http://weex.apache.org/cn/references/" target="_blank">
-      <text class="text">Url</text>
-    </a>
-    <a weex-type="a" class="items" href="http://weex.apache.org/cn/references/" target="_blank">
-      <text class="text">Url</text>
-    </a>
-  </div>
-  <div class="items-box">
-    <a weex-type="a" class="items" href="http://weex.apache.org/cn/references/" target="_blank">
-      <text class="text">Url</text>
-    </a>
-    <a weex-type="a" class="items" href="http://weex.apache.org/cn/references/" target="_blank">
-      <text class="text">Url</text>
-    </a>
-  </div>
-  <div class="items-box">
-    <a weex-type="a" class="items" href="http://weex.apache.org/cn/references/" target="_blank">
-      <text class="text">Url</text>
-    </a>
-    <a weex-type="a" class="items" href="http://weex.apache.org/cn/references/" target="_blank">
-      <text class="text">Url</text>
-    </a>
-  </div>
-  
-
-  <div class="wrapper" @click="backTop" v-if="show">
-    <text class="text">Tap</text>
-  </div>
-  </div>
-</template>
-
-<style scoped>
-  .items-box{
-    flex-direction: row;
-    justify-content: space-between;
-    -webkit-box-orient: horizontal;
-    -webkit-box-direction: normal;
-    -webkit-box-pack: justify;
-  }
-  .items{
-    flex-flow: row nowrap; 
-    align-items: center; 
-    overflow: hidden; 
-    position: relative; 
-    top: 0px; left: 0px; 
-    box-sizing: border-box; 
-    width: 374px; 
-    height: 564px; 
-    flex-basis: auto; 
-    font-size: 0px; 
-    border-color: rgb(0, 0, 0); 
-    border-style: solid; 
-    background-color: rgb(245, 245, 245); 
-    margin-bottom: 2px; 
-    text-align: center; 
-  }
-  .flexRow {
-    flex-direction: row;
-  }
-
-  .flexColumn {
-    flex-direction: column;
-  }
-
-  .text {
-    flex: 1;
-    text-align: center;
-  }
-  
-  .fixed {
-    position: fixed;
-    bottom: 50px;
-    left: 50px;
-    width: 300px;
-    height: 50px;
-    align-items: center;
-    justify-content: center
-  }
-
-  .shopImg {
-    width: 220px;
-    height: 220px;
-  }
-
-  .list {
-    flex-direction: column;
-    overflow: hidden;
-    width: 750px;
-    height: 100%;
-    background-color: #dddddd;
-  }
-
-  .cell {
-    background-color: #dddddd;
-    flex-direction: column;
-    width: 750px;
-  }
-
-  .test {
-    width:60px;
-    height:60px;
-  }
-
-  .shopDiv {
-    flex-direction: column;
-    background-color: #ffffff;
-    margin: 5px;
-    padding: 10px;
-    border-width: 1px;
-    border-color: #cccccc;
-    overflow: visible;
-  }
-
-  .shopRowList {
-    flex-direction: column;
-    border-width: 1px;
-    border-color: #cccccc;
-    overflow: visible;
-    margin: 5px;
-    padding: 10px;
-    background-color: #ffffff;
-  }
-
-  .shopHeader {
-    flex-direction: row;
-    width: 720px;
-  }
-
-  .shopFooter {
-    flex-direction: row;
-    width: 720px;
-  }
-
-  .smallImg {
-    width: 20px;
-    height: 20px;
-  }
-  .wrapper {
-    background-color: #f8f8f8;
-    border:1px solid #ddd;
-    position: fixed;
-    bottom: 20px;
-    right: 20px;
-    width: 88px;
-    height: 88px;
-    z-index: 10100;
-    flex-flow: row nowrap; 
-    align-items: center; 
-    cursor: pointer;
-  }
-  .backTop {
-    width: 88px;
-    height: 88px;
-  }
-</style>
-
-<script>
-  var modal = weex.requireModule('modal')
-  var dom = weex.requireModule('dom')
-  module.exports = {
-    data: function () {
-      return {
-        show: true,
-        href: 'http://weex.apache.org/cn/references/'
-      }
-    },
-    methods: {
-      clickitem: function(e) {
-        modal.toast({
-          message:'click' + e
-        })
-      },
-      preventDefault: function(e) {
-        this.href = 'javascript:void(0)'
-        modal.toast({
-          message:'click'
-        })
-      },
-      backTop: function () {
-        let self = this
-        window.scrollTo(0, 0)
-        this.show = false
-      }
-    }
-
-  }
-</script>
diff --git a/examples/vue/style/index.vue b/examples/vue/style/index.vue
deleted file mode 100644
index abee8e7..0000000
--- a/examples/vue/style/index.vue
+++ /dev/null
@@ -1,41 +0,0 @@
-<template>
-  <scroller style="overflow-x:hidden;">
-    <style-box></style-box>
-    <style-flex></style-flex>
-    <panel title="opacity" type="primary">
-      <div style="flex-direction:row;">
-        <style-item style="opacity:1" value="1"></style-item>
-        <style-item style="opacity:0.9" value="0.9"></style-item>
-        <style-item style="opacity:0.5" value="0.5"></style-item>
-        <style-item style="opacity:0.2" value="0.2"></style-item>
-      </div>
-    </panel>
-    <panel title="background-color" type="primary">
-      <div>
-        <style-item class="bg-item" style="background-color: #333;" value="#333"></style-item>
-        <style-item class="bg-item" style="background-color: #333333;" value="#333333"></style-item>
-        <style-item class="bg-item" style="background-color: rgb(238, 162, 54);" value="rgb()"></style-item>
-        <style-item class="bg-item" style="background-color: rgba(238, 162, 54, 0.5);" value="rgba()"></style-item>
-        <style-item class="bg-item" style="background-color: red;" value="red"></style-item>
-      </div>
-    </panel>
-  </scroller>
-</template>
-
-<style scoped>
-  .bg-item {
-    width: 690px;
-    margin-bottom: 10px;
-  }
-</style>
-
-<script>
-  module.exports = {
-    components: {
-      panel: require('../include/panel.vue'),
-      styleBox: require('./style-box.vue'),
-      styleFlex: require('./style-flex.vue'),
-      styleItem: require('./style-item.vue')
-    }
-  }
-</script>
diff --git a/examples/vue/style/style-box.vue b/examples/vue/style/style-box.vue
deleted file mode 100644
index 76d7195..0000000
--- a/examples/vue/style/style-box.vue
+++ /dev/null
@@ -1,70 +0,0 @@
-<template>
-  <div>
-    <panel title="Box Model" padding-body="0" type="primary">
-      <text class="box">Box</text>
-    </panel>
-
-    <panel title="border" type="primary">
-      <panel title="border-width" type="">
-        <div style="flex-direction: row;">
-          <style-item style="border-style: solid;border-width: 2px;border-color: #333;" value=""></style-item>
-          <style-item style="border-style: solid;border-width: 10px;border-color: #333;" value=""></style-item>
-          <style-item style="border-style: solid;border-left-width: 4px;border-color: #333;" value=""></style-item>
-          <style-item style="border-style: solid;border-bottom-width: 4px;border-color: #333;" value=""></style-item>
-        </div>
-      </panel>
-      <panel title="border-color" type="">
-        <div style="flex-direction: row;">
-          <style-item style="border-style: solid;border-width: 4px;border-color: #333;" value=""></style-item>
-          <style-item style="border-style: solid;border-width: 4px;border-color: #ddd;" value=""></style-item>
-          <style-item style="border-style: solid;border-width: 4px;border-color: red;" value=""></style-item>
-        </div>
-      </panel>
-      <panel title="border-style" type="">
-        <tip type="warning" value="just support four edges" style="margin-bottom: 10px;"></tip>
-        <div style="flex-direction: row;">
-          <style-item style="border-style: solid;border-width: 4px;border-color: #333;" value=""></style-item>
-          <style-item style="border-style: dashed;border-width: 4px;border-color: #333;" value="" type=""></style-item>
-          <style-item style="border-style: dotted;border-width: 4px;border-color: #333;" value=""></style-item>
-        </div>
-      </panel>
-      <panel title="border-radius" type="">
-        <div style="flex-direction: row;">
-          <style-item style="width: 75px;border-radius:38px" value=""></style-item>
-          <style-item style="border-radius:20px" value=""></style-item>
-          <style-item style="border-top-left-radius:20px;border-top-right-radius:20px" value=""></style-item>
-          <style-item style="border-bottom-left-radius:20px;border-bottom-right-radius:20px" value=""></style-item>
-        </div>
-      </panel>
-    </panel>
-  </div>
-</template>
-
-<style scoped>
-  .box {
-    background-color: #f5f5f5;
-    width: 260px;
-    height: 260px;
-    padding-left: 40px;
-    padding-top: 40px;
-    padding-right: 40px;
-    padding-bottom: 40px;
-    margin-left: 40px;
-    margin-top: 40px;
-    margin-right: 40px;
-    margin-bottom: 40px;
-    border-width: 40px;
-    border-color: #333;
-    border-style: solid;
-  }
-</style>
-
-<script>
-  module.exports = {
-    components: {
-      panel: require('../include/panel.vue'),
-      tip: require('../include/tip.vue'),
-      styleItem: require('./style-item.vue')
-    }
-  }
-</script>
diff --git a/examples/vue/style/style-flex.vue b/examples/vue/style/style-flex.vue
deleted file mode 100644
index 246014d..0000000
--- a/examples/vue/style/style-flex.vue
+++ /dev/null
@@ -1,125 +0,0 @@
-<template>
-  <div>
-    <panel title="flex-direction" type="primary">
-      <div class="row" style="flex-direction: row;">
-        <style-item value="row" style="margin-right: 0;"></style-item>
-        <style-item type="1"></style-item>
-      </div>
-      <div class="row" style="flex-direction: column">
-        <style-item value="column"></style-item>
-        <style-item type="1"></style-item>
-      </div>
-    </panel>
-
-    <panel title="justify-content" type="primary">
-      <div class="row" style="justify-content: flex-start">
-        <style-item style="margin-right:0;"></style-item>
-        <style-item style="margin-right:0;" type="1"></style-item>
-        <style-item style="margin-right:0;"></style-item>
-      </div>
-      <div class="row" style="justify-content: flex-end">
-        <style-item style="margin-right:0;"></style-item>
-        <style-item style="margin-right:0;" type="1"></style-item>
-        <style-item style="margin-right:0;"></style-item>
-      </div>
-      <div class="row" style="justify-content: center">
-        <style-item style="margin-right:0;"></style-item>
-        <style-item style="margin-right:0;" type="1"></style-item>
-        <style-item style="margin-right:0;"></style-item>
-      </div>
-      <div class="row" style="justify-content: space-between">
-        <style-item style="margin-right:0;"></style-item>
-        <style-item style="margin-right:0;" type="1"></style-item>
-        <style-item style="margin-right:0;"></style-item>
-      </div>
-    </panel>
-
-    <panel title="align-items" type="primary">
-      <div class="row row-align" style="align-items: flex-start">
-        <style-item style="margin-right:0;"></style-item>
-        <style-item style="margin-right:0;" type="1"></style-item>
-        <style-item style="margin-right:0;"></style-item>
-      </div>
-      <div class="row row-align" style="align-items: flex-end">
-        <style-item style="margin-right:0;"></style-item>
-        <style-item style="margin-right:0;" type="1"></style-item>
-        <style-item style="margin-right:0;"></style-item>
-      </div>
-      <div class="row row-align" style="align-items: center">
-        <style-item style="margin-right:0;"></style-item>
-        <style-item style="margin-right:0;" type="1"></style-item>
-        <style-item style="margin-right:0;"></style-item>
-      </div>
-      <div class="row row-align" style="align-items: stretch">
-        <style-item style="margin-right:0;"></style-item>
-        <style-item style="margin-right:0;" type="1"></style-item>
-        <style-item style="margin-right:0;"></style-item>
-      </div>
-    </panel>
-
-    <panel title="flex" type="primary">
-      <div class="row" style="align-items: flex-start">
-        <style-item style="margin-right:0;" value="no flex"></style-item>
-        <style-item style="margin-right:0;" value="no flex" type="1"></style-item>
-        <style-item style="margin-right:0;" value="no flex"></style-item>
-      </div>
-      <div class="row" style="align-items: flex-start">
-        <style-item style="margin-right:0;" value="no flex"></style-item>
-        <style-item style="margin-right:0; flex:1;" type="1" value="flex:1"></style-item>
-        <style-item style="margin-right:0; flex:2;" value="flex:2"></style-item>
-      </div>
-      <div class="row" style="align-items: flex-start">
-        <style-item style="margin-right:0; flex:1;" value="flex:1"></style-item>
-        <style-item style="margin-right:0; flex:1;" type="1" value="flex:1"></style-item>
-        <style-item style="margin-right:0; flex:1;" value="flex:1"></style-item>
-      </div>
-      <div class="row" style="align-items: flex-start">
-        <style-item style="margin-right:0; flex:1;" value="flex:1"></style-item>
-        <style-item style="margin-right:0; flex:2;" type="1" value="flex:2"></style-item>
-        <style-item style="margin-right:0; flex:3;" value="flex:3"></style-item>
-      </div>
-    </panel>
-    
-    <panel title="flex-wrap" type="primary">
-      <div class="row" style="flex-wrap:wrap;background-color:grey;padding:10;">
-        <style-item value="1:wrap"></style-item>
-        <style-item value="2:wrap"></style-item>
-        <style-item value="3:wrap"></style-item>
-        <style-item value="4:wrap"></style-item>
-        <style-item value="5:wrap"></style-item>
-        <style-item value="6:wrap"></style-item>
-      </div>
-      <div class="row" style="flex-wrap:nowrap;background-color:grey;padding:10;">
-        <style-item value="1:nowrap"></style-item>
-        <style-item value="2:nowrap"></style-item>
-        <style-item value="3:nowrap"></style-item>
-        <style-item value="4:nowrap"></style-item>
-        <style-item value="5:nowrap"></style-item>
-        <style-item value="6:nowrap"></style-item>
-      </div>
-    </panel>
-  </div>
-</template>
-
-<style scoped>
-  .row {
-    flex-direction: row;
-    margin-bottom: 10px;
-  }
-
-  .row-align {
-    height: 160px;
-    border-width: 3px;
-    border-color: #ddd;
-    border-style: solid;
-  }
-</style>
-
-<script>
-  module.exports = {
-    components: {
-      panel: require('../include/panel.vue'),
-      styleItem: require('./style-item.vue')
-    }
-  }
-</script>
diff --git a/examples/vue/style/style-item.vue b/examples/vue/style/style-item.vue
deleted file mode 100644
index d53e243..0000000
--- a/examples/vue/style/style-item.vue
+++ /dev/null
@@ -1,37 +0,0 @@
-<template>
-  <text
-    :value="value"
-    :style="{ backgroundColor: bgColor }"
-    class="item txt"></text>
-</template>
-
-<script>
-  module.exports = {
-    props: {
-      value: { default: '' },
-      type: { default: '0' } // 0, 1
-    },
-    computed: {
-      bgColor: function () {
-        return this.type == '1' ? '#7BA3A8' : '#BEAD92';
-      }
-    }
-  }
-</script>
-
-<style scoped>
-  .item {
-    margin-right: 10px;
-    /*margin-bottom: 10px;*/
-    width: 160px;
-    height: 75px;
-    padding-left: 8px;
-    padding-right: 8px;
-    padding-top: 8px;
-    padding-bottom: 8px;
-  }
-
-  .txt {
-    color: #eee;
-  }
-</style>
diff --git a/examples/vue/syntax/hello-world-1.vue b/examples/vue/syntax/hello-world-1.vue
deleted file mode 100644
index 495b95e..0000000
--- a/examples/vue/syntax/hello-world-1.vue
+++ /dev/null
@@ -1,7 +0,0 @@
-<!-- template: html-like syntax -->
-
-<template>
-  <div>
-    <text>Hello World</text>
-  </div>
-</template>
diff --git a/examples/vue/syntax/hello-world-2.vue b/examples/vue/syntax/hello-world-2.vue
deleted file mode 100644
index 00ae48f..0000000
--- a/examples/vue/syntax/hello-world-2.vue
+++ /dev/null
@@ -1,14 +0,0 @@
-<!--
-  * <template>: html-like syntax
-  * CSS-like inline style
--->
-
-<template>
-  <div style="align-items: center; margin-top: 120px;">
-    <image
-      src="https://alibaba.github.io/weex/img/weex_logo_blue@3x.png"
-      style="width: 360px; height: 82px;"
-    ></image>
-    <text style="font-size: 48px;">Hello World</text>
-  </div>
-</template>
diff --git a/examples/vue/syntax/hello-world-3.vue b/examples/vue/syntax/hello-world-3.vue
deleted file mode 100644
index 78b05ce..0000000
--- a/examples/vue/syntax/hello-world-3.vue
+++ /dev/null
@@ -1,21 +0,0 @@
-<!--
-  * <template>: html-like syntax
-  * CSS-like inline style
-  * <style scoped>: only support single-class selector
--->
-
-<template>
-  <div class="wrapper">
-    <image
-      src="https://alibaba.github.io/weex/img/weex_logo_blue@3x.png"
-      class="logo"
-    ></image>
-    <text class="title">Hello World</text>
-  </div>
-</template>
-
-<style scoped>
-  .wrapper {align-items: center; margin-top: 120px;}
-  .title {font-size: 48px;}
-  .logo {width: 360px; height: 82px;}
-</style>
diff --git a/examples/vue/syntax/hello-world-4.vue b/examples/vue/syntax/hello-world-4.vue
deleted file mode 100644
index f5898a1..0000000
--- a/examples/vue/syntax/hello-world-4.vue
+++ /dev/null
@@ -1,32 +0,0 @@
-<!--
-  * <template>: html-like syntax
-  * CSS-like inline style
-  * <style scoped>: only support single-class selector
-  * <script>: define the behavior of component
-  * :attr data-binding support
--->
-
-<template>
-  <div class="wrapper">
-    <image
-      :src="logoUrl"
-      class="logo"
-    ></image>
-    <text class="title">Hello {{target}}</text>
-  </div>
-</template>
-
-<style scoped>
-  .wrapper {align-items: center; margin-top: 120px;}
-  .title {font-size: 48px;}
-  .logo {width: 360px; height: 82px;}
-</style>
-
-<script>
-  module.exports = {
-    data: {
-      logoUrl: 'https://alibaba.github.io/weex/img/weex_logo_blue@3x.png',
-      target: 'World'
-    }
-  }
-</script>
diff --git a/examples/vue/syntax/hello-world-5.vue b/examples/vue/syntax/hello-world-5.vue
deleted file mode 100644
index 32e0e89..0000000
--- a/examples/vue/syntax/hello-world-5.vue
+++ /dev/null
@@ -1,35 +0,0 @@
-<!--
-  * <template>: html-like syntax
-  * CSS-like inline style
-  * <style scoped>: only support single-class selector
-  * <script>: define the behavior of component
-  * :attr data-binding support
-  * @xxx syntax to bind event with a component method
--->
-
-<template>
-  <div class="wrapper" @click="update">
-    <image :src="logoUrl" class="logo"></image>
-    <text class="title">Hello {{target}}</text>
-  </div>
-</template>
-
-<style scoped>
-  .wrapper {align-items: center; margin-top: 120px;}
-  .title {font-size: 48px;}
-  .logo {width: 360px; height: 82px;}
-</style>
-
-<script>
-  module.exports = {
-    data: {
-      logoUrl: 'https://alibaba.github.io/weex/img/weex_logo_blue@3x.png',
-      target: 'World'
-    },
-    methods: {
-      update: function (e) {
-        this.target = 'Weex'
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/syntax/hello-world.vue b/examples/vue/syntax/hello-world.vue
deleted file mode 100644
index 073a966..0000000
--- a/examples/vue/syntax/hello-world.vue
+++ /dev/null
@@ -1,45 +0,0 @@
-<!--
-  * <template>: html-like syntax
-  * CSS-like inline style
-  * <style scoped>: only support single-class selector
-  * <script>: define the behavior of component
-  * :attr data-binding support
-  * @xxx syntax to bind event with a component method
--->
-
-<!--
-  notes:
-  * <template> only could have just one child
-  * the text node is only allowed as the child of <text> as the shorthand of its `value` attribute
-  * the style is not inherited from parent (for example: `font-size`)
-  * <script> support ECMAScript 5
-  * all component options assigns to `module.exports`
--->
-
-<template>
-  <div class="wrapper" @click="update">
-    <image :src="logoUrl" class="logo"></image>
-    <text class="title">Hello {{target}}</text>
-  </div>
-</template>
-
-<style scoped>
-  .wrapper {align-items: center; margin-top: 120px;}
-  .title {font-size: 48px;}
-  .logo {width: 360px; height: 82px;}
-</style>
-
-<script>
-  module.exports = {
-    data: {
-      logoUrl: 'https://alibaba.github.io/weex/img/weex_logo_blue@3x.png',
-      target: 'World'
-    },
-    methods: {
-      update: function (e) {
-        this.target = 'Weex'
-        console.log('target:', this.target)
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/syntax/include/btn.vue b/examples/vue/syntax/include/btn.vue
deleted file mode 100644
index 6fed870..0000000
--- a/examples/vue/syntax/include/btn.vue
+++ /dev/null
@@ -1,9 +0,0 @@
-<template>
-  <div class="btn">
-    <slot></slot>
-  </div>
-</template>
-
-<style scoped>
-  .btn {font-size: 36px; text-align: center; color: white; background-color: gray; padding: 20px; border-radius: 5px;}
-</style>
diff --git a/examples/vue/syntax/include/sub.vue b/examples/vue/syntax/include/sub.vue
deleted file mode 100644
index c34ccec..0000000
--- a/examples/vue/syntax/include/sub.vue
+++ /dev/null
@@ -1,16 +0,0 @@
-<template>
-  <text class="item-txt">{{title}}</text>
-</template>
-
-<style scoped>
-  .item-txt {
-    font-size: 48px;
-    color: #555;
-  }
-</style>
-
-<script>
-  module.exports = {
-    props: ['url', 'title']
-  }
-</script>
diff --git a/examples/vue/syntax/script-component.vue b/examples/vue/syntax/script-component.vue
deleted file mode 100644
index 5208fd4..0000000
--- a/examples/vue/syntax/script-component.vue
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-  * `components` option to require sub components
-  * use attribute to pass props to sub components
-  * see `./include/sub.vue` source code for more details
--->
-
-<template>
-  <list>
-    <cell v-for="(item,i) in items" :key="i" >
-      <text>{{item.title}}</text>
-      <item :title="'a'"></item>
-    </cell>
-  </list>
-</template>
-
-<script>
-  module.exports = {
-    data: function () {
-      return {
-        items: [
-          {title: 'A', url: 'a'},
-          {title: 'B', url: 'b'},
-          {title: 'C', url: 'c'}
-        ]
-      }
-    },
-    components: {
-      item: require('./include/sub.vue')
-    }
-  }
-</script>
diff --git a/examples/vue/syntax/script-data.vue b/examples/vue/syntax/script-data.vue
deleted file mode 100644
index 355fb14..0000000
--- a/examples/vue/syntax/script-data.vue
+++ /dev/null
@@ -1,84 +0,0 @@
-<!--
-  * in root component `data` is an plain object
-  * in sub component `data` is a function which returns an plain object
-  * `data` means (internal) data
-  * `props` means external data, only used in sub components
-  * `props` could be set from parent by an attribute with the same name
-  * `props` cound be a string array or an object
-  * `props` object may have `type`, `default`
-  * `computed` support a single getter or a getter/setter object
--->
-
-<template>
-  <div @click="update">
-    <text class="title">{{firstName}}</text>
-    <text class="title">{{lastName}}</text>
-    <text class="title">{{fullName}}</text>
-    <text class="title">{{today}}</text>
-  </div>
-</template>
-
-<style scoped>
-  .title {font-size: 48px;}
-</style>
-
-<script>
-  // // if this is a sub component and the parent component could set `firstName` and `lastName` by:
-  // // `<subcomponent first-name="John" last-name="Smith"></subcomponent>`
-  // // but the `date` won't be changed from parent component
-  // module.exports = {
-  //   props: ['firstName', 'lastName'],
-  //   data: function () {
-  //     return {
-  //       date: Date.now()
-  //     }
-  //   }
-  // }
-
-  // // more `props` formats like
-  // module.exports = {
-  //   props: {
-  //     firstName: {
-  //       default: 'John'
-  //     },
-  //     lastName: {
-  //       type: String,
-  //       default: 'Smith'
-  //     }
-  //   },
-  //   data: function () {
-  //     return {
-  //       date: Date.now()
-  //     }
-  //   }
-  // }
-
-  module.exports = {
-    data: function () {
-      return {
-        firstName: 'John',
-        lastName: 'Smith',
-        date: Date.now()
-      }
-    },
-    methods: {
-      update: function () {
-        this.today = '2016-01-01'
-        console.log('today:', this.today)
-      }
-    },
-    computed: {
-      fullName: function () {
-        return this.firstName + ' ' + this.lastName
-      },
-      today: {
-        get: function () {
-          return new Date(this.date).toDateString()
-        },
-        set: function (v) {
-          this.date = Date.parse(v)
-        }
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/syntax/script-events.vue b/examples/vue/syntax/script-events.vue
deleted file mode 100644
index 13487f9..0000000
--- a/examples/vue/syntax/script-events.vue
+++ /dev/null
@@ -1,39 +0,0 @@
-<!--
-  * `this.$on(type, handler)`: registers a component event listener
-  * `this.$off(type, handler)`: removes a component event listener
-  * `this.$emit(type, detail)`: sends component event to itself
--->
-
-<template>
-  <div>
-    <text class="title" v-for="(value, i) in list" :key="i" >{{value}}</text>
-  </div>
-</template>
-
-<style scoped>
-  .title {font-size: 48px;}
-</style>
-
-<script>
-  module.exports = {
-    data: function () {
-      return {
-        list: []
-      }
-    },
-    mounted: function () {
-      function custom(e) {
-        this.list.push('custom: ' + JSON.stringify(e))
-        console.log(this.list)
-      }
-
-      this.$emit('custom', {x: 1})
-
-      this.$on('custom', custom)
-      this.$emit('custom', {x: 2})
-
-      this.$off('custom', custom)
-      this.$emit('custom', {x: 3})
-    }
-  }
-</script>
diff --git a/examples/vue/syntax/script-instance.vue b/examples/vue/syntax/script-instance.vue
deleted file mode 100644
index fb31d5d..0000000
--- a/examples/vue/syntax/script-instance.vue
+++ /dev/null
@@ -1,71 +0,0 @@
-<!--
-  * access data/props
-  * access computed
-  * call methods
-  * get config
-  * listen and fire component events
-  * parent component and sub components
-  * find element
--->
-
-<template>
-  <div>
-    <text id="title" class="title">Please check out the source code.</text>
-    <!-- <subcomponent ref="sub"></subcomponent> -->
-  </div>
-</template>
-
-<style scoped>
-  .title {font-size: 48px;}
-</style>
-
-<script>
-  module.exports = {
-    data: function () {
-      return {
-        x: 1,
-        y: 2
-      }
-    },
-    methods: {
-      foo: function () {
-        console.log('foo')
-      },
-      test: function () {
-
-        // access data/props
-        console.log(this.x)
-
-        // access computed
-        console.log(this.z)
-
-        // call methods
-        this.foo()
-
-        // get config
-        console.log(this.$getConfig())
-
-        // listen and fire component events
-        this.$emit('custom')
-        this.$on('custom', this.foo)
-        this.$off('custom', this.foo)
-
-        // // parent component and sub components
-        // this.$parent.$emit('custom')
-        // this.$refs['sub'].$emit('custom')
-
-        // // find element
-        // var dom = weex.requireModule('dom')
-        // dom.scrollToElement(this.$el('title'), {offset: 0})
-      }
-    },
-    computed: {
-      z: function () {
-        return this.x + this.y
-      }
-    },
-    mounted: function () {
-      this.test()
-    }
-  }
-</script>
diff --git a/examples/vue/syntax/script-lifecycle.vue b/examples/vue/syntax/script-lifecycle.vue
deleted file mode 100644
index 63b2e32..0000000
--- a/examples/vue/syntax/script-lifecycle.vue
+++ /dev/null
@@ -1,33 +0,0 @@
-<template>
-  <div>
-    <text class="title" v-for="(value, i) in list" :key="i" >{{value}}</text>
-  </div>
-</template>
-
-<style scoped>
-  .title {font-size: 48px;}
-</style>
-
-<script>
-  var initMessage
-  module.exports = {
-    data: function () {
-      return {
-        list: ['Lifecycle List']
-      }
-    },
-    init: function () {
-      initMessage = 'component init: nothing more happen even the data initialization'
-      console.log('init:', this.list)
-    },
-    created: function () {
-      this.list.push(initMessage)
-      this.list.push('component created: data observed')
-      console.log('created:', this.list)
-    },
-    mounted: function () {
-      this.list.push('component mounted: virtual dom generated')
-      console.log('mounted:', this.list)
-    }
-  }
-</script>
diff --git a/examples/vue/syntax/script-module.vue b/examples/vue/syntax/script-module.vue
deleted file mode 100644
index be63313..0000000
--- a/examples/vue/syntax/script-module.vue
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-  * `var module = weex.requireModule('module')` to import a native module
-  * `module.method(...)` to call a native API
--->
-
-<template>
-  <div>
-    <text class="btn" @click="test">Toast!</text>
-  </div>
-</template>
-
-<style scoped>
-  .btn {font-size: 36px; text-align: center; color: white; background-color: gray; padding: 20px; border-radius: 5px;}
-</style>
-
-<script>
-  var modal = weex.requireModule('modal')
-  module.exports = {
-    methods: {
-      test: function () {
-        modal.toast({
-          message: 'Toast!',
-          duration: 3
-        })
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/syntax/script-options.vue b/examples/vue/syntax/script-options.vue
deleted file mode 100644
index 1b997cb..0000000
--- a/examples/vue/syntax/script-options.vue
+++ /dev/null
@@ -1,60 +0,0 @@
-<!--
-  * components
-  * props
-  * data
-  * computed
-  * methods
-  * lifecycle
--->
-
-<template>
-  <div>
-    <text class="title">Please check out the source code.</text>
-    <!-- <item ref="sub"></item> -->
-  </div>
-</template>
-
-<style scoped>
-  .title {font-size: 48px;}
-</style>
-
-<script>
-  module.exports = {
-    // // import sub components
-    // components: {
-    //   item: require('./components/sub.vue')
-    // },
-
-    // // for sub component only
-    // props: ['a', 'b'],
-
-    // for root component only
-    data: {
-      x: 1,
-      y: 2
-    },
-    // // for sub component only
-    // data: function () {
-    //   return {
-    //     x: 1,
-    //     y: 2
-    //   }
-    // }
-
-    methods: {
-      foo: function () {
-        console.log('foo')
-      }
-    },
-
-    computed: {
-      z: function () {
-        return this.x + this.y
-      }
-    },
-
-    init: function () {},
-    created: function () {},
-    mounted: function () {}
-  }
-</script>
diff --git a/examples/vue/syntax/template-class.vue b/examples/vue/syntax/template-class.vue
deleted file mode 100644
index 5a194db..0000000
--- a/examples/vue/syntax/template-class.vue
+++ /dev/null
@@ -1,30 +0,0 @@
-<!--
-  * class name with data binding
--->
-
-<template>
-  <div @click="update">
-    <text class="a">Hello</text>
-    <text class="b">Hello</text>
-    <text :class="['a', x]">Hello</text>
-  </div>
-</template>
-
-<style scoped>
-  .a {font-size: 48px;}
-  .b {color: #ff0000;}
-</style>
-
-<script>
-  module.exports = {
-    data: {
-      x: ''
-    },
-    methods: {
-      update: function (e) {
-        this.x = 'b'
-        console.log('x', this.x)
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/syntax/template-content.vue b/examples/vue/syntax/template-content.vue
deleted file mode 100644
index 0b58cd6..0000000
--- a/examples/vue/syntax/template-content.vue
+++ /dev/null
@@ -1,20 +0,0 @@
-<!--
-  * `<slot>` will let the sub component contains the parent's children
-  * see `./include/btn.vue` source code for more details
--->
-
-<template>
-  <div>
-    <btn>
-      <text>Click!</text>
-    </btn>
-  </div>
-</template>
-
-<script>
-  module.exports = {
-    components: {
-      btn: require('./include/btn.vue')
-    }
-  }
-</script>
diff --git a/examples/vue/syntax/template-event.vue b/examples/vue/syntax/template-event.vue
deleted file mode 100644
index 4e813bd..0000000
--- a/examples/vue/syntax/template-event.vue
+++ /dev/null
@@ -1,40 +0,0 @@
-<!--
-  * inline event listener
--->
-
-<template>
-  <div>
-    <text class="title">Hello {{name}}</text>
-    <text class="btn" @click="update">Update 1</text>
-    <text class="btn" @click="update($event)">Update 1</text>
-    <text class="btn" @click="setName(temp, $event)">Update 2</text>
-    <text class="btn" @click="setName('John')">Update 3</text>
-  </div>
-</template>
-
-<style scoped>
-  .title {font-size: 48px;}
-  .subtitle {font-size: 36px;}
-  .btn {font-size: 36px; text-align: center; color: white; background-color: gray; padding: 20px; border-radius: 5px;}
-</style>
-
-<script>
-  module.exports = {
-    data: function () {
-      return {
-        name: 'Steve',
-        temp: 'Mike'
-      }
-    },
-    methods: {
-      update: function (e) {
-        this.setName('David')
-        console.log('setName', this.name)
-      },
-      setName: function (value) {
-        this.name = value
-        console.log('name', this.name)
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/syntax/template-if.vue b/examples/vue/syntax/template-if.vue
deleted file mode 100644
index 0bfdcd9..0000000
--- a/examples/vue/syntax/template-if.vue
+++ /dev/null
@@ -1,30 +0,0 @@
-<!--
-  * v-if="flag": display or not by the truthy/falsy result
--->
-
-<template>
-  <div>
-    <text class="btn" @click="toggle">Toggle</text>
-    <text v-if="flag" class="title">I'm ON</text>
-    <text v-if="!flag" class="title">I'm Off</text>
-  </div>
-</template>
-
-<style scoped>
-  .title {font-size: 48px;}
-  .btn {font-size: 36px; text-align: center; color: white; background-color: gray; padding: 20px; border-radius: 5px;}
-</style>
-
-<script>
-  module.exports = {
-    data: {
-      flag: true
-    },
-    methods: {
-      toggle: function (e) {
-        this.flag = !this.flag
-        console.log('this.flag:', this.flag)
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/syntax/template-repeat-update.vue b/examples/vue/syntax/template-repeat-update.vue
deleted file mode 100644
index 5f69849..0000000
--- a/examples/vue/syntax/template-repeat-update.vue
+++ /dev/null
@@ -1,54 +0,0 @@
-<!--
-  * track-by="primary": diff array by this as the primary key, default is the index
-  * use `Vue.set(list, index, value)` to set a item value, do not use `list[index] = value`
-  * use `list.splice()`, `list.push()`, `list.pop()`, `list.shift()`, `list.unshift()`, `list.sort()`, `list.reverse()`, do not use `list.length = x`
--->
-
-<template>
-  <div>
-    <text class="title">Track by</text>
-    <text class="subtitle" v-for="(item, k, $index) in list" track-by="item.key">{{$index}}-{{item.text}}</text>
-    <text class="btn" @click="update">Update</text>
-    <text class="btn" @click="mutate">Mutate</text>
-  </div>
-</template>
-
-<style scoped>
-  .title {font-size: 48px;}
-  .subtitle {font-size: 36px;}
-  .btn {font-size: 36px; text-align: center; color: white; background-color: gray; padding: 20px; border-radius: 5px;}
-</style>
-
-<script>
-  module.exports = {
-    data: function () {
-      return {
-        list: [
-          {key: 1, text: 'a'},
-          {key: 2, text: 'a'},
-          {key: 3, text: 'b'},
-          {key: 4, text: 'c'},
-          {key: 5, text: 'a'}
-        ],
-        flag: true
-      }
-    },
-    methods: {
-      update: function (e) {
-        // equals to `this.list.text = 'foo'`
-        // DO NOT USE: `this.list[2] = {key: 3, text: 'foo'}}`
-        Vue.set(this.list, 2, {key: 3, text: 'foo'})
-        console.log('this.list', this.list)
-      },
-      mutate: function (e) {
-        if (this.list.length % 2) {
-          this.list.push({key: 'x', text: 'bar'})
-        }
-        else {
-          this.list.pop()
-        }
-        console.log('this.list', this.list)
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/syntax/template-repeat.vue b/examples/vue/syntax/template-repeat.vue
deleted file mode 100644
index 3a7facd..0000000
--- a/examples/vue/syntax/template-repeat.vue
+++ /dev/null
@@ -1,43 +0,0 @@
-<!--
-  * v-for="item in list": assign item and $index to this
-  * v-for="(index, item) in list" assign index and item to this
--->
-
-<template>
-  <div>
-    <text class="title">Custom item</text>
-    <text class="subtitle" v-for="item in list" :key="item.index" >{{item}}</text>
-    <text class="title">Custom key and item</text>
-    <text class="subtitle" v-for="(v,i) in list" :key="i" >{{i}}-{{v}}</text>
-    <text class="title">Array of Object</text>
-    <text class="subtitle" v-for="(item, k, index) in list2" :key="index" >> {{index}}-{{item.text}}</text>
-  </div>
-</template>
-
-<style scoped>
-  .title {font-size: 48px;}
-  .subtitle {font-size: 36px;}
-</style>
-
-<script>
-  module.exports = {
-    data: function () {
-      return {
-        list: [
-          'a',
-          'b',
-          'c',
-          'd',
-          'e'
-        ],
-        list2: [
-          {text: 'a'},
-          {text: 'b'},
-          {text: 'c'},
-          {text: 'd'},
-          {text: 'e'}
-        ]
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/syntax/template-style.vue b/examples/vue/syntax/template-style.vue
deleted file mode 100644
index c150919..0000000
--- a/examples/vue/syntax/template-style.vue
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-  * inline style with data binding
--->
-
-<template>
-  <div @click="update">
-    <text style="font-size: 48px; color: #0000ff">Hello</text>
-    <text :style="{ fontSize: size, color: color }">Hello</text>
-  </div>
-</template>
-
-<script>
-  module.exports = {
-    data: function () {
-      return {
-        size: 32,
-        color: '#ff0000'
-      }
-    },
-    methods: {
-      update: function (e) {
-        this.size = 48
-        console.log('this.size', this.size)
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/template.vue b/examples/vue/template.vue
deleted file mode 100644
index 249512c..0000000
--- a/examples/vue/template.vue
+++ /dev/null
@@ -1,40 +0,0 @@
-<template>
-  <scroller>
-    <panel title="Dialog" type="primary">
-      <tip type="success" value="It's a weex example template." style="margin-bottom: 20px;"></tip>
-      <hn level="1" value="H1"></hn>
-      <button type="primary" @click.native="toast" value="Toast"></button>
-      <hn level="2" value="H3"></hn>
-      <button type="warning" @click.native="toast" value="Toast"></button>
-    </panel>
-    <panel title="Image" type="primary">
-      <tip type="warning" value="Weex screen width is 750" style="margin-bottom: 20px;"></tip>
-      <image class="img" style="width: 400px; height: 400px;" :src="img"></image>
-      <panel title="Image" type="default">
-        <text>sub info</text>
-      </panel>
-    </panel>
-  </scroller>
-</template>
-
-<script>
-  var modal = weex.requireModule('modal')
-  module.exports = {
-    data: function () {
-      return {
-        img: '//gw.alicdn.com/tps/i2/TB1DpsmMpXXXXabaXXX20ySQVXX-512-512.png_400x400.jpg'
-      }
-    },
-    components: {
-      panel: require('./include/panel.vue'),
-      hn: require('./include/hn.vue'),
-      tip: require('./include/tip.vue'),
-      button: require('./include/button.vue')
-    },
-    methods: {
-      toast: function() {
-        modal.toast({ message: 'a toast', duration: 2 })
-      }
-    }
-  }
-</script>
diff --git a/examples/vue/transition.vue b/examples/vue/transition.vue
deleted file mode 100644
index abcf830..0000000
--- a/examples/vue/transition.vue
+++ /dev/null
@@ -1,110 +0,0 @@
-<template>
-    <list class="list">
-        <cell class="cell" v-for="(item, i) in panels" @click="change(i)">
-            <div class="panel" :style="{height: item.height,width:item.width,backgroundColor:item.bgc,opacity:item.opacity,transform:item.transform}">
-                 <text class="text">{{item.label}}</text> 
-            </div>
-            <div class="panel" :style="{height: item.height,width:item.width,backgroundColor:item.bgc,opacity:item.opacity,transform:item.transform}">
-                 <text class="text">{{item.label}}</text> 
-            </div>
-        </cell>
-    </list>
-</template>
-<script>
-    export default {
-        created () {
-            this.datasource = ['width+height','backgroundColor','opactity','transform/translateX','transform/translateY','transform/scaleX','transform/scaleY','transform/rotate']
-            this.panels = this.randomfn()
-        },
-        data () {
-            return {
-                panels: []
-            }
-        },
-        methods: {
-            change (i) {
-                const item = this.panels[i]
-                if (item) {
-
-                    if(i==0)
-                    {
-                        item.height = item.height === 330 ? 200 : 330
-                        item.width = item.width === 350 ? 730 : 350
-                    }
-                    if(i==1)
-                    {
-                        item.bgc = item.bgc ===  '#69BE96' ? 'red':'#69BE96'
-                    }
-                    if(i==2)
-                    {
-                        item.opacity = item.opacity === 1.0 ? 0.6 : 1.0
-                    }
-                    if(i==3)
-                    {
-                        item.bgc = item.bgc ===  '#69BE96' ? '#72B8DF':'#69BE96'
-                        item.transform = item.transform === 'translateX(200px)'?'translateX(0px)':'translateX(200px)'
-                    }
-                    if(i==4)
-                    {
-                        item.bgc = item.bgc ===  '#69BE96' ? '#72B8DF':'#69BE96'
-                        item.transform = item.transform === 'translateY(-150px)'?'translateY(0px)':'translateY(-150px)'
-                    }
-                    if(i==5)
-                    {
-                       item.bgc = item.bgc ===  '#69BE96' ? '#72B8DF':'#69BE96'
-                       item.transform = item.transform === 'scaleX(0.5)'?'scaleX(1)':'scaleX(0.5)'
-                    }
-                    if(i==6)
-                    {
-                       item.bgc = item.bgc ===  '#69BE96' ? '#72B8DF':'#69BE96'
-                       item.transform = item.transform === 'scaleY(0.5)'?'scaleY(1)':'scaleY(0.5)'
-                    }
-                    if(i==7)
-                    {
-                       item.bgc = item.bgc ===  '#69BE96' ? '#72B8DF':'#69BE96'
-                       item.transform = item.transform === 'rotate(40deg)'?'rotate(0deg)':'rotate(40deg)'
-                    }
-                    
-                }
-            },
-            randomfn () {
-                let ary = [];
-                for(let i = 0; i<= 7; i++) {
-                    ary.push({label: this.datasource[i] ,height: 200 , width:730, bgc:'#69BE96',opacity:1,right:20})
-                }
-                return ary;
-            },
-        }
-    }
-</script>
-
-<style scoped>
-    .panel {
-        margin: 10px;
-        top:10px;
-        align-items: center;
-        justify-content: center;
-        border: solid;
-        border-radius: 10px; 
-          
-        transition-property: right,left,top,bottom,width,height,backgroundColor,opacity,transform;
-        transition-duration: 0.5s; 
-        transition-delay: 0s;
-        transition-timing-function: cubic-bezier(0.58, 0.1, 0.42, 1.0); 
-    }
-    .cell{
-        background-color:white;
-        flex-direction: row;
-    }
-
-
-    .text {
-        font-size: 60px; 
-        text-align: center;
-        color: white;
-
-    }
-    .list{
-        background-color:white;
-    }
-</style>
diff --git a/index.html b/index.html
deleted file mode 100644
index da7ebae..0000000
--- a/index.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>Weex Vue Demo</title>
-
-  <!-- You should set 'weex-viewport' to your design pixel width, and the
-    viewport meta should be set like below, OTHERWISE it won't work.-->
-  <meta name="weex-viewport" content="750">
-  <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
-
-  <meta name="apple-mobile-web-app-capable" content="yes" />
-  <meta name="apple-mobile-web-app-status-bar-style" content="black" />
-  <meta name="apple-touch-fullscreen" content="yes" />
-  <meta name="format-detection" content="telephone=no, email=no" />
-
-  <!-- About style below: html's height should set to 100%, and this
-    style should be added before the weex-vue-render script loaded.
-    OTHERWISE the 'weex.config.env.deviceHeight' will not work. -->
-  <style>
-    html, body {
-      -ms-overflow-style: scrollbar;
-      -webkit-tap-highlight-color: transparent;
-      padding: 0;
-      margin: 0;
-      width: 100%;
-      height: 100%;
-      background-color: green;
-      overflow-x: hidden;
-    }
-    #info {
-      position: fixed;
-      z-index: 999999;
-      top: 100px;
-      left: 0;
-      width: 100%;
-      height: 400px;
-      font-size: 24px;
-      color: green;
-      padding: 10px;
-      overflow-x: hidden;
-      overflow-y: scroll;
-      background-color: #eee;
-      opacity: 0.7;
-    }
-  </style>
-</head>
-<body>
-  <div id="root"></div>
-  <script src="./node_modules/vue/dist/vue.runtime.js"></script>
-  <script src="./node_modules/weex-vue-render/dist/index.js"></script>
-  <script src="./packages/weex-vue-render/dist/index.js"></script>
-  <script>
-    /**
-     * these iife is just for the convenience for the showcase of demos.
-     * you can import a jsbundle by wrapping it in a <script> tag.
-     * e.g. <script src="examples/build/vue-web/vue/index.js"></*script>
-     */
-    ; (function () {
-      function getUrlParam (key) {
-        var reg = new RegExp('[?|&]' + key + '=([^&]+)')
-        var match = location.search.match(reg)
-        return match && match[1]
-      }
-
-      var page = getUrlParam('page')
-      var defaultPage = 'examples/build/vue-web/vue/index.js'
-      if (!page) {
-        var url = location.href.replace(/\?|$/, function(f) {
-          var query = '?page=' + defaultPage
-          return f ? query + '&' : query
-        })
-        return location.href = url
-      }
-
-      var bundle = document.createElement('script')
-      bundle.src = page
-      document.body.appendChild(bundle)
-    })()
-  </script>
-</body>
-</html>
diff --git a/package-lock.json b/package-lock.json
index 3d9777a..160173d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5,80 +5,169 @@
   "requires": true,
   "dependencies": {
     "@babel/polyfill": {
-      "version": "7.6.0",
-      "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.6.0.tgz",
-      "integrity": "sha512-q5BZJI0n/B10VaQQvln1IlDK3BTBJFbADx7tv+oXDPIDZuTo37H5Adb9jhlXm/fEN4Y7/64qD9mnrJJG7rmaTw==",
+      "version": "7.12.1",
+      "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.12.1.tgz",
+      "integrity": "sha512-X0pi0V6gxLi6lFZpGmeNa4zxtwEmCs42isWLNjZZDE0Y8yVfgu0T2OAHlzBbdYlqbW/YXVvoBHpATEM+goCj8g==",
       "dev": true,
       "requires": {
         "core-js": "^2.6.5",
-        "regenerator-runtime": "^0.13.2"
+        "regenerator-runtime": "^0.13.4"
       },
       "dependencies": {
-        "core-js": {
-          "version": "2.6.10",
-          "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.10.tgz",
-          "integrity": "sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA==",
-          "dev": true
-        },
         "regenerator-runtime": {
-          "version": "0.13.3",
-          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz",
-          "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==",
+          "version": "0.13.7",
+          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
+          "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==",
           "dev": true
         }
       }
     },
-    "@octokit/endpoint": {
-      "version": "5.5.0",
-      "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-5.5.0.tgz",
-      "integrity": "sha512-TXYS6zXeBImNB9BVj+LneMDqXX+H0exkOpyXobvp92O3B1348QsKnNioISFKgOMsb3ibZvQGwCdpiwQd3KAjIA==",
+    "@octokit/auth-token": {
+      "version": "2.4.5",
+      "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.5.tgz",
+      "integrity": "sha512-BpGYsPgJt05M7/L/5FoE1PiAbdxXFZkX/3kDYcsvd1v6UhlnE5e96dTDr0ezX/EFwciQxf3cNV0loipsURU+WA==",
       "dev": true,
       "requires": {
-        "@octokit/types": "^1.0.0",
-        "is-plain-object": "^3.0.0",
-        "universal-user-agent": "^4.0.0"
+        "@octokit/types": "^6.0.3"
+      }
+    },
+    "@octokit/endpoint": {
+      "version": "6.0.11",
+      "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.11.tgz",
+      "integrity": "sha512-fUIPpx+pZyoLW4GCs3yMnlj2LfoXTWDUVPTC4V3MUEKZm48W+XYpeWSZCv+vYF1ZABUm2CqnDVf1sFtIYrj7KQ==",
+      "dev": true,
+      "requires": {
+        "@octokit/types": "^6.0.3",
+        "is-plain-object": "^5.0.0",
+        "universal-user-agent": "^6.0.0"
+      },
+      "dependencies": {
+        "universal-user-agent": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
+          "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==",
+          "dev": true
+        }
+      }
+    },
+    "@octokit/openapi-types": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-7.0.0.tgz",
+      "integrity": "sha512-gV/8DJhAL/04zjTI95a7FhQwS6jlEE0W/7xeYAzuArD0KVAVWDLP2f3vi98hs3HLTczxXdRK/mF0tRoQPpolEw==",
+      "dev": true
+    },
+    "@octokit/plugin-paginate-rest": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-1.1.2.tgz",
+      "integrity": "sha512-jbsSoi5Q1pj63sC16XIUboklNw+8tL9VOnJsWycWYR78TKss5PVpIPb1TUUcMQ+bBh7cY579cVAWmf5qG+dw+Q==",
+      "dev": true,
+      "requires": {
+        "@octokit/types": "^2.0.1"
+      },
+      "dependencies": {
+        "@octokit/types": {
+          "version": "2.16.2",
+          "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz",
+          "integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==",
+          "dev": true,
+          "requires": {
+            "@types/node": ">= 8"
+          }
+        }
+      }
+    },
+    "@octokit/plugin-request-log": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.3.tgz",
+      "integrity": "sha512-4RFU4li238jMJAzLgAwkBAw+4Loile5haQMQr+uhFq27BmyJXcXSKvoQKqh0agsZEiUlW6iSv3FAgvmGkur7OQ==",
+      "dev": true
+    },
+    "@octokit/plugin-rest-endpoint-methods": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-2.4.0.tgz",
+      "integrity": "sha512-EZi/AWhtkdfAYi01obpX0DF7U6b1VRr30QNQ5xSFPITMdLSfhcBqjamE3F+sKcxPbD7eZuMHu3Qkk2V+JGxBDQ==",
+      "dev": true,
+      "requires": {
+        "@octokit/types": "^2.0.1",
+        "deprecation": "^2.3.1"
+      },
+      "dependencies": {
+        "@octokit/types": {
+          "version": "2.16.2",
+          "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz",
+          "integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==",
+          "dev": true,
+          "requires": {
+            "@types/node": ">= 8"
+          }
+        }
       }
     },
     "@octokit/request": {
-      "version": "5.3.0",
-      "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.3.0.tgz",
-      "integrity": "sha512-mMIeNrtYyNEIYNsKivDyUAukBkw0M5ckyJX56xoFRXSasDPCloIXaQOnaKNopzQ8dIOvpdq1ma8gmrS+h6O2OQ==",
+      "version": "5.4.15",
+      "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.15.tgz",
+      "integrity": "sha512-6UnZfZzLwNhdLRreOtTkT9n57ZwulCve8q3IT/Z477vThu6snfdkBuhxnChpOKNGxcQ71ow561Qoa6uqLdPtag==",
       "dev": true,
       "requires": {
-        "@octokit/endpoint": "^5.5.0",
-        "@octokit/request-error": "^1.0.1",
-        "@octokit/types": "^1.0.0",
-        "deprecation": "^2.0.0",
-        "is-plain-object": "^3.0.0",
-        "node-fetch": "^2.3.0",
-        "once": "^1.4.0",
-        "universal-user-agent": "^4.0.0"
+        "@octokit/endpoint": "^6.0.1",
+        "@octokit/request-error": "^2.0.0",
+        "@octokit/types": "^6.7.1",
+        "is-plain-object": "^5.0.0",
+        "node-fetch": "^2.6.1",
+        "universal-user-agent": "^6.0.0"
       },
       "dependencies": {
-        "node-fetch": {
-          "version": "2.6.0",
-          "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
-          "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==",
+        "@octokit/request-error": {
+          "version": "2.0.5",
+          "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.0.5.tgz",
+          "integrity": "sha512-T/2wcCFyM7SkXzNoyVNWjyVlUwBvW3igM3Btr/eKYiPmucXTtkxt2RBsf6gn3LTzaLSLTQtNmvg+dGsOxQrjZg==",
+          "dev": true,
+          "requires": {
+            "@octokit/types": "^6.0.3",
+            "deprecation": "^2.0.0",
+            "once": "^1.4.0"
+          }
+        },
+        "universal-user-agent": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
+          "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==",
           "dev": true
         }
       }
     },
     "@octokit/request-error": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-1.0.4.tgz",
-      "integrity": "sha512-L4JaJDXn8SGT+5G0uX79rZLv0MNJmfGa4vb4vy1NnpjSnWDLJRy6m90udGwvMmavwsStgbv2QNkPzzTCMmL+ig==",
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-1.2.1.tgz",
+      "integrity": "sha512-+6yDyk1EES6WK+l3viRDElw96MvwfJxCt45GvmjDUKWjYIb3PJZQkq3i46TwGwoPD4h8NmTrENmtyA1FwbmhRA==",
       "dev": true,
       "requires": {
+        "@octokit/types": "^2.0.0",
         "deprecation": "^2.0.0",
         "once": "^1.4.0"
+      },
+      "dependencies": {
+        "@octokit/types": {
+          "version": "2.16.2",
+          "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz",
+          "integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==",
+          "dev": true,
+          "requires": {
+            "@types/node": ">= 8"
+          }
+        }
       }
     },
     "@octokit/rest": {
-      "version": "16.34.1",
-      "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.34.1.tgz",
-      "integrity": "sha512-JUoS12cdktf1fv86rgrjC/RvYLuL+o7p57W7zX1x7ANFJ7OvdV8emvUNkFlcidEaOkYrxK3SoWgQFt3FhNmabA==",
+      "version": "16.43.2",
+      "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.43.2.tgz",
+      "integrity": "sha512-ngDBevLbBTFfrHZeiS7SAMAZ6ssuVmXuya+F/7RaVvlysgGa1JKJkKWY+jV6TCJYcW0OALfJ7nTIGXcBXzycfQ==",
       "dev": true,
       "requires": {
+        "@octokit/auth-token": "^2.4.0",
+        "@octokit/plugin-paginate-rest": "^1.1.1",
+        "@octokit/plugin-request-log": "^1.0.0",
+        "@octokit/plugin-rest-endpoint-methods": "2.4.0",
         "@octokit/request": "^5.2.0",
         "@octokit/request-error": "^1.0.2",
         "atob-lite": "^2.0.0",
@@ -94,18 +183,18 @@
       }
     },
     "@octokit/types": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@octokit/types/-/types-1.1.0.tgz",
-      "integrity": "sha512-t4ZD74UnNVMq6kZBDZceflRKK3q4o5PoCKMAGht0RK84W57tqonqKL3vCxJHtbGExdan9RwV8r7VJBZxIM1O7Q==",
+      "version": "6.14.2",
+      "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.14.2.tgz",
+      "integrity": "sha512-wiQtW9ZSy4OvgQ09iQOdyXYNN60GqjCL/UdMsepDr1Gr0QzpW6irIKbH3REuAHXAhxkEk9/F2a3Gcs1P6kW5jA==",
       "dev": true,
       "requires": {
-        "@types/node": "^12.11.1"
+        "@octokit/openapi-types": "^7.0.0"
       }
     },
     "@types/node": {
-      "version": "12.12.3",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.3.tgz",
-      "integrity": "sha512-opgSsy+cEF9N8MgaVPnWVtdJ3o4mV2aMHvDq7thkQUFt0EuOHJon4rQpJfhjmNHB+ikl0Cd6WhWIErOyQ+f7tw==",
+      "version": "15.0.3",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.3.tgz",
+      "integrity": "sha512-/WbxFeBU+0F79z9RdEOXH4CsDga+ibi5M8uEYr91u3CkT/pdWcV8MCook+4wDPnZBexRdwWS+PiVZ2xJviAzcQ==",
       "dev": true
     },
     "@weex-project/downgrade": {
@@ -120,9 +209,9 @@
       "dev": true
     },
     "JSONStream": {
-      "version": "1.3.3",
-      "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.3.tgz",
-      "integrity": "sha512-3Sp6WZZ/lXl+nTDoGpGWHEpTnnC6X5fnkolYZR6nwIfzbxxvA8utPWe1gCt7i0m9uVGsSz2IS8K8mJ7HmlduMg==",
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz",
+      "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==",
       "dev": true,
       "requires": {
         "jsonparse": "^1.2.0",
@@ -152,22 +241,11 @@
         }
       }
     },
-    "acorn-dynamic-import": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz",
-      "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==",
-      "dev": true,
-      "requires": {
-        "acorn": "^5.0.0"
-      },
-      "dependencies": {
-        "acorn": {
-          "version": "5.7.1",
-          "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz",
-          "integrity": "sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ==",
-          "dev": true
-        }
-      }
+    "acorn": {
+      "version": "5.7.4",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz",
+      "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==",
+      "dev": true
     },
     "acorn-es7-plugin": {
       "version": "1.0.18",
@@ -193,24 +271,30 @@
       }
     },
     "acorn-node": {
-      "version": "1.5.2",
-      "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.5.2.tgz",
-      "integrity": "sha512-krFKvw/d1F17AN3XZbybIUzEY4YEPNiGo05AfP3dBlfVKrMHETKpgjpuZkSF8qDNt9UkQcqj7am8yJLseklCMg==",
+      "version": "1.8.2",
+      "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz",
+      "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==",
       "dev": true,
       "requires": {
-        "acorn": "^5.7.1",
-        "acorn-dynamic-import": "^3.0.0",
-        "xtend": "^4.0.1"
+        "acorn": "^7.0.0",
+        "acorn-walk": "^7.0.0",
+        "xtend": "^4.0.2"
       },
       "dependencies": {
         "acorn": {
-          "version": "5.7.1",
-          "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz",
-          "integrity": "sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ==",
+          "version": "7.4.1",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+          "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
           "dev": true
         }
       }
     },
+    "acorn-walk": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz",
+      "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
+      "dev": true
+    },
     "acorn5-object-spread": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/acorn5-object-spread/-/acorn5-object-spread-4.0.0.tgz",
@@ -218,49 +302,32 @@
       "dev": true,
       "requires": {
         "acorn": "^5.1.2"
-      },
-      "dependencies": {
-        "acorn": {
-          "version": "5.7.1",
-          "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz",
-          "integrity": "sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ==",
-          "dev": true
-        }
       }
     },
     "address": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/address/-/address-1.0.3.tgz",
-      "integrity": "sha512-z55ocwKBRLryBs394Sm3ushTtBeg6VAeuku7utSoSnsJKvKcnXFIyC6vh27n3rXyxSgkJBBCAvyOn7gSUcTYjg==",
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz",
+      "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==",
       "dev": true
     },
     "agent-base": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz",
-      "integrity": "sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=",
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz",
+      "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==",
       "dev": true,
       "requires": {
-        "extend": "~3.0.0",
-        "semver": "~5.0.1"
-      },
-      "dependencies": {
-        "semver": {
-          "version": "5.0.3",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz",
-          "integrity": "sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no=",
-          "dev": true
-        }
+        "es6-promisify": "^5.0.0"
       }
     },
     "ajv": {
-      "version": "5.5.2",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
-      "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
+      "version": "6.12.6",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
       "requires": {
-        "co": "^4.6.0",
-        "fast-deep-equal": "^1.0.0",
+        "fast-deep-equal": "^3.1.1",
         "fast-json-stable-stringify": "^2.0.0",
-        "json-schema-traverse": "^0.3.0"
+        "json-schema-traverse": "^0.4.1",
+        "uri-js": "^4.2.2"
       }
     },
     "ajv-keywords": {
@@ -278,6 +345,17 @@
         "kind-of": "^3.0.2",
         "longest": "^1.0.1",
         "repeat-string": "^1.5.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
       }
     },
     "alphanum-sort": {
@@ -342,6 +420,82 @@
       "requires": {
         "micromatch": "^2.1.5",
         "normalize-path": "^2.0.0"
+      },
+      "dependencies": {
+        "arr-diff": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
+          "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
+          "dev": true,
+          "requires": {
+            "arr-flatten": "^1.0.1"
+          }
+        },
+        "array-unique": {
+          "version": "0.2.1",
+          "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
+          "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
+          "dev": true
+        },
+        "braces": {
+          "version": "1.8.5",
+          "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
+          "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
+          "dev": true,
+          "requires": {
+            "expand-range": "^1.8.1",
+            "preserve": "^0.2.0",
+            "repeat-element": "^1.1.2"
+          }
+        },
+        "expand-brackets": {
+          "version": "0.1.5",
+          "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
+          "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
+          "dev": true,
+          "requires": {
+            "is-posix-bracket": "^0.1.0"
+          }
+        },
+        "extglob": {
+          "version": "0.3.2",
+          "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
+          "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
+          "dev": true,
+          "requires": {
+            "is-extglob": "^1.0.0"
+          }
+        },
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        },
+        "micromatch": {
+          "version": "2.3.11",
+          "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
+          "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
+          "dev": true,
+          "requires": {
+            "arr-diff": "^2.0.0",
+            "array-unique": "^0.2.1",
+            "braces": "^1.8.2",
+            "expand-brackets": "^0.1.4",
+            "extglob": "^0.3.1",
+            "filename-regex": "^2.0.0",
+            "is-extglob": "^1.0.0",
+            "is-glob": "^2.0.1",
+            "kind-of": "^3.0.2",
+            "normalize-path": "^2.0.1",
+            "object.omit": "^2.0.0",
+            "parse-glob": "^3.0.4",
+            "regex-cache": "^0.4.2"
+          }
+        }
       }
     },
     "archiver": {
@@ -423,13 +577,10 @@
       }
     },
     "arr-diff": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
-      "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
-      "dev": true,
-      "requires": {
-        "arr-flatten": "^1.0.1"
-      }
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+      "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+      "dev": true
     },
     "arr-flatten": {
       "version": "1.1.0",
@@ -443,24 +594,6 @@
       "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
       "dev": true
     },
-    "array-filter": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz",
-      "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=",
-      "dev": true
-    },
-    "array-map": {
-      "version": "0.0.0",
-      "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz",
-      "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=",
-      "dev": true
-    },
-    "array-reduce": {
-      "version": "0.0.0",
-      "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz",
-      "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=",
-      "dev": true
-    },
     "array-slice": {
       "version": "0.2.3",
       "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz",
@@ -483,15 +616,9 @@
       "dev": true
     },
     "array-unique": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
-      "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
-      "dev": true
-    },
-    "arrify": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
-      "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+      "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
       "dev": true
     },
     "asap": {
@@ -500,16 +627,20 @@
       "integrity": "sha1-sqRdpf36ILBJb8N2jMJ8EvqRan0="
     },
     "asn1": {
-      "version": "0.2.3",
-      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
-      "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y="
+      "version": "0.2.4",
+      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
+      "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
+      "requires": {
+        "safer-buffer": "~2.1.0"
+      }
     },
     "assert": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz",
-      "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=",
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz",
+      "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==",
       "dev": true,
       "requires": {
+        "object-assign": "^4.1.1",
         "util": "0.10.3"
       },
       "dependencies": {
@@ -560,9 +691,9 @@
       "dev": true
     },
     "async-each": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
-      "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=",
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz",
+      "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==",
       "dev": true
     },
     "async-retry": {
@@ -580,9 +711,9 @@
       "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
     },
     "atob": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz",
-      "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=",
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+      "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
       "dev": true
     },
     "atob-lite": {
@@ -611,9 +742,9 @@
       "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
     },
     "aws4": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz",
-      "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w=="
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
+      "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA=="
     },
     "babel-code-frame": {
       "version": "6.26.0",
@@ -1235,9 +1366,9 @@
       "dev": true
     },
     "balanced-match": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
-      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
       "dev": true
     },
     "base": {
@@ -1292,40 +1423,27 @@
             "is-data-descriptor": "^1.0.0",
             "kind-of": "^6.0.2"
           }
-        },
-        "isobject": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
-          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
-          "dev": true
-        },
-        "kind-of": {
-          "version": "6.0.2",
-          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
-          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
-          "dev": true
         }
       }
     },
     "base64-js": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz",
-      "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==",
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
       "dev": true
     },
     "bcrypt-pbkdf": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
       "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
-      "optional": true,
       "requires": {
         "tweetnacl": "^0.14.3"
       }
     },
     "before-after-hook": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.1.0.tgz",
-      "integrity": "sha512-IWIbu7pMqyw3EAJHzzHbWa85b6oud/yfKYg5rqB5hNE8CeMi3nX+2C2sj0HswfblST86hpVEOAb9x34NZd6P7A==",
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.1.tgz",
+      "integrity": "sha512-/6FKxSTWoJdbsLDF8tdIjaRiFXiE6UHsEHE3OPI/cwPURCVi1ukP0gmLn7XWEiFk5TcwQjjY5PWsU+j+tgXgmw==",
       "dev": true
     },
     "big.js": {
@@ -1335,11 +1453,21 @@
       "dev": true
     },
     "binary-extensions": {
-      "version": "1.11.0",
-      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz",
-      "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=",
+      "version": "1.13.1",
+      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
+      "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
       "dev": true
     },
+    "bindings": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
+      "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "file-uri-to-path": "1.0.0"
+      }
+    },
     "bl": {
       "version": "0.9.5",
       "resolved": "https://registry.npmjs.org/bl/-/bl-0.9.5.tgz",
@@ -1374,18 +1502,18 @@
       }
     },
     "bluebird": {
-      "version": "3.5.1",
-      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
-      "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==",
+      "version": "3.7.2",
+      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+      "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
       "dev": true
     },
     "boom": {
-      "version": "2.10.1",
-      "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
-      "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
+      "version": "4.3.1",
+      "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz",
+      "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=",
       "dev": true,
       "requires": {
-        "hoek": "2.x.x"
+        "hoek": "4.x.x"
       }
     },
     "brace-expansion": {
@@ -1399,14 +1527,32 @@
       }
     },
     "braces": {
-      "version": "1.8.5",
-      "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
-      "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+      "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
       "dev": true,
       "requires": {
-        "expand-range": "^1.8.1",
-        "preserve": "^0.2.0",
-        "repeat-element": "^1.1.2"
+        "arr-flatten": "^1.1.0",
+        "array-unique": "^0.3.2",
+        "extend-shallow": "^2.0.1",
+        "fill-range": "^4.0.0",
+        "isobject": "^3.0.1",
+        "repeat-element": "^1.1.2",
+        "snapdragon": "^0.8.1",
+        "snapdragon-node": "^2.0.1",
+        "split-string": "^3.0.2",
+        "to-regex": "^3.0.1"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
       }
     },
     "browser-pack": {
@@ -1433,9 +1579,9 @@
       }
     },
     "browser-stdout": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz",
-      "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=",
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
+      "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
       "dev": true
     },
     "browserify": {
@@ -1569,10 +1715,16 @@
           "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
           "dev": true
         },
+        "punycode": {
+          "version": "1.4.1",
+          "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+          "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+          "dev": true
+        },
         "readable-stream": {
-          "version": "2.3.6",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
-          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "version": "2.3.7",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+          "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
           "dev": true,
           "requires": {
             "core-util-is": "~1.0.0",
@@ -1585,9 +1737,9 @@
           },
           "dependencies": {
             "process-nextick-args": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
-              "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+              "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
               "dev": true
             },
             "string_decoder": {
@@ -1601,6 +1753,12 @@
             }
           }
         },
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+          "dev": true
+        },
         "timers-browserify": {
           "version": "1.4.2",
           "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz",
@@ -1662,12 +1820,6 @@
         "vlq": "^0.2.2"
       },
       "dependencies": {
-        "acorn": {
-          "version": "5.7.1",
-          "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz",
-          "integrity": "sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ==",
-          "dev": true
-        },
         "ansi-styles": {
           "version": "3.2.1",
           "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
@@ -1678,9 +1830,9 @@
           }
         },
         "chalk": {
-          "version": "2.4.1",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
-          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
           "dev": true,
           "requires": {
             "ansi-styles": "^3.2.1",
@@ -1703,16 +1855,10 @@
             "vlq": "^0.2.2"
           }
         },
-        "minimist": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
-          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
-          "dev": true
-        },
         "supports-color": {
-          "version": "5.4.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
-          "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
           "dev": true,
           "requires": {
             "has-flag": "^3.0.0"
@@ -1721,9 +1867,9 @@
       }
     },
     "buffer": {
-      "version": "4.9.1",
-      "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
-      "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
+      "version": "4.9.2",
+      "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
+      "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
       "dev": true,
       "requires": {
         "base64-js": "^1.0.2",
@@ -1752,9 +1898,15 @@
       "dev": true
     },
     "buffer-from": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz",
-      "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==",
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
+      "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+      "dev": true
+    },
+    "builtin-modules": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-2.0.0.tgz",
+      "integrity": "sha512-3U5kUA5VPsRUA3nofm/BXX7GVHKfxz0hOBAPxXrIvHzlDRkQVqEn6yi8QJegxl4LzOHLdvb7XF5dVawa/VVYBg==",
       "dev": true
     },
     "builtin-status-codes": {
@@ -1784,14 +1936,6 @@
         "to-object-path": "^0.3.0",
         "union-value": "^1.0.0",
         "unset-value": "^1.0.0"
-      },
-      "dependencies": {
-        "isobject": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
-          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
-          "dev": true
-        }
       }
     },
     "cached-path-relative": {
@@ -1834,9 +1978,9 @@
       }
     },
     "caniuse-db": {
-      "version": "1.0.30000870",
-      "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000870.tgz",
-      "integrity": "sha1-85fNZJIsJPhdDOeAPJvVxaFXGxY=",
+      "version": "1.0.30001226",
+      "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30001226.tgz",
+      "integrity": "sha512-hnC3hnMKAn/VaRHFb4fCe7snQRQFy0EZrK0AAomFbqGT18KXOtnPvTm0m+NvyRrBCR1jwFCjbUQvar0r6lBvOw==",
       "dev": true
     },
     "caseless": {
@@ -1876,14 +2020,6 @@
         "has-ansi": "^2.0.0",
         "strip-ansi": "^3.0.0",
         "supports-color": "^2.0.0"
-      },
-      "dependencies": {
-        "supports-color": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-          "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-          "dev": true
-        }
       }
     },
     "chardet": {
@@ -1922,18 +2058,24 @@
       }
     },
     "chromedriver": {
-      "version": "2.40.0",
-      "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-2.40.0.tgz",
-      "integrity": "sha512-ewvRQ1HMk0vpFSWYCk5hKDoEz5QMPplx5w3C6/Me+03y1imr67l3Hxl9U0jn3mu2N7+c7BoC7JtNW6HzbRAwDQ==",
+      "version": "2.46.0",
+      "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-2.46.0.tgz",
+      "integrity": "sha512-dLtKIJW3y/PuFrPmcw6Mb8Nh+HwSqgVrK1rWgTARXhHfWvV822X2VRkx2meU/tg2+YQL6/nNgT6n5qWwIDHbwg==",
       "dev": true,
       "requires": {
         "del": "^3.0.0",
         "extract-zip": "^1.6.7",
-        "kew": "^0.7.0",
         "mkdirp": "^0.5.1",
-        "request": "^2.87.0"
+        "request": "^2.88.0",
+        "tcp-port-used": "^1.0.1"
       }
     },
+    "ci-info": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+      "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+      "dev": true
+    },
     "circular-json": {
       "version": "0.3.3",
       "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
@@ -1969,12 +2111,6 @@
           "requires": {
             "is-descriptor": "^0.1.0"
           }
-        },
-        "isobject": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
-          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
-          "dev": true
         }
       }
     },
@@ -1988,9 +2124,9 @@
       }
     },
     "cli-width": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
-      "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz",
+      "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==",
       "dev": true
     },
     "cliui": {
@@ -2021,7 +2157,8 @@
     "co": {
       "version": "4.6.0",
       "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
-      "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
+      "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
+      "dev": true
     },
     "coa": {
       "version": "1.0.4",
@@ -2054,18 +2191,18 @@
       }
     },
     "color-convert": {
-      "version": "1.9.2",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz",
-      "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==",
+      "version": "1.9.3",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
       "dev": true,
       "requires": {
-        "color-name": "1.1.1"
+        "color-name": "1.1.3"
       }
     },
     "color-name": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz",
-      "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=",
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
       "dev": true
     },
     "color-string": {
@@ -2121,17 +2258,17 @@
       }
     },
     "combined-stream": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
-      "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
       "requires": {
         "delayed-stream": "~1.0.0"
       }
     },
     "commander": {
-      "version": "2.16.0",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-2.16.0.tgz",
-      "integrity": "sha512-sVXqklSaotK9at437sFlFpyOcJonxe0yST/AG9DkQKUdIE6IqGIMv4SfAQSKaJbSdVEJYItASCrBiVQHq1HQew==",
+      "version": "2.20.3",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+      "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
       "dev": true
     },
     "commondir": {
@@ -2158,12 +2295,6 @@
         "readable-stream": "~1.0.26"
       },
       "dependencies": {
-        "node-int64": {
-          "version": "0.3.3",
-          "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.3.3.tgz",
-          "integrity": "sha1-LW5rLs5d6FiLQ9iNG8QbJs0fqE0=",
-          "dev": true
-        },
         "readable-stream": {
           "version": "1.0.34",
           "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
@@ -2203,9 +2334,9 @@
           "dev": true
         },
         "readable-stream": {
-          "version": "2.3.6",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
-          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "version": "2.3.7",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+          "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
           "dev": true,
           "requires": {
             "core-util-is": "~1.0.0",
@@ -2217,6 +2348,12 @@
             "util-deprecate": "~1.0.1"
           }
         },
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+          "dev": true
+        },
         "string_decoder": {
           "version": "1.1.1",
           "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@@ -2229,9 +2366,9 @@
       }
     },
     "config-chain": {
-      "version": "1.1.11",
-      "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.11.tgz",
-      "integrity": "sha1-q6CXR9++TD5w52am5BWG4YWfxvI=",
+      "version": "1.1.12",
+      "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz",
+      "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==",
       "dev": true,
       "requires": {
         "ini": "^1.3.4",
@@ -2239,13 +2376,10 @@
       }
     },
     "console-browserify": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz",
-      "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=",
-      "dev": true,
-      "requires": {
-        "date-now": "^0.1.4"
-      }
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz",
+      "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==",
+      "dev": true
     },
     "consolidate": {
       "version": "0.14.5",
@@ -2262,12 +2396,29 @@
       "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=",
       "dev": true
     },
-    "convert-source-map": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz",
-      "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=",
+    "content-disposition": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
+      "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=",
       "dev": true
     },
+    "convert-source-map": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
+      "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "~5.1.1"
+      },
+      "dependencies": {
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+          "dev": true
+        }
+      }
+    },
     "copy-descriptor": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
@@ -2285,9 +2436,9 @@
       }
     },
     "core-js": {
-      "version": "2.5.7",
-      "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz",
-      "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw=="
+      "version": "2.6.12",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz",
+      "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ=="
     },
     "core-util-is": {
       "version": "1.0.2",
@@ -2315,10 +2466,10 @@
         "require-from-string": "^1.1.0"
       },
       "dependencies": {
-        "minimist": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
-          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+        "require-from-string": {
+          "version": "1.2.1",
+          "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz",
+          "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=",
           "dev": true
         }
       }
@@ -2364,12 +2515,23 @@
       "dev": true
     },
     "cryptiles": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
-      "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
+      "version": "3.1.4",
+      "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.4.tgz",
+      "integrity": "sha512-8I1sgZHfVwcSOY6mSGpVU3lw/GSIZvusg8dD2+OGehCJpOhQRLNcH0qb9upQnOH4XhgxxFJSg6E2kx95deb1Tw==",
       "dev": true,
       "requires": {
-        "boom": "2.x.x"
+        "boom": "5.x.x"
+      },
+      "dependencies": {
+        "boom": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz",
+          "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==",
+          "dev": true,
+          "requires": {
+            "hoek": "4.x.x"
+          }
+        }
       }
     },
     "crypto-browserify": {
@@ -2385,25 +2547,22 @@
       }
     },
     "css": {
-      "version": "2.2.3",
-      "resolved": "https://registry.npmjs.org/css/-/css-2.2.3.tgz",
-      "integrity": "sha512-0W171WccAjQGGTKLhw4m2nnl0zPHUlTO/I8td4XzJgIB8Hg3ZZx71qT4G4eX8OVsSiaAKiUMy73E3nsbPlg2DQ==",
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz",
+      "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==",
       "dev": true,
       "requires": {
-        "inherits": "^2.0.1",
-        "source-map": "^0.1.38",
-        "source-map-resolve": "^0.5.1",
+        "inherits": "^2.0.3",
+        "source-map": "^0.6.1",
+        "source-map-resolve": "^0.5.2",
         "urix": "^0.1.0"
       },
       "dependencies": {
         "source-map": {
-          "version": "0.1.43",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz",
-          "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=",
-          "dev": true,
-          "requires": {
-            "amdefine": ">=0.0.4"
-          }
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
         }
       }
     },
@@ -2433,47 +2592,54 @@
         "source-list-map": "^0.1.7"
       },
       "dependencies": {
-        "loader-utils": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz",
-          "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=",
+        "big.js": {
+          "version": "5.2.2",
+          "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
+          "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+          "dev": true
+        },
+        "emojis-list": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
+          "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
+          "dev": true
+        },
+        "json5": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+          "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
           "dev": true,
           "requires": {
-            "big.js": "^3.1.3",
-            "emojis-list": "^2.0.0",
-            "json5": "^0.5.0"
+            "minimist": "^1.2.0"
+          }
+        },
+        "loader-utils": {
+          "version": "1.4.0",
+          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
+          "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
+          "dev": true,
+          "requires": {
+            "big.js": "^5.2.2",
+            "emojis-list": "^3.0.0",
+            "json5": "^1.0.1"
           }
         }
       }
     },
     "css-selector-tokenizer": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz",
-      "integrity": "sha1-5piEdK6MlTR3v15+/s/OzNnPTIY=",
+      "version": "0.7.3",
+      "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.3.tgz",
+      "integrity": "sha512-jWQv3oCEL5kMErj4wRnK/OPoBi0D+P1FR2cDCKYPaMeD2eW3/mttav8HT4hT1CKopiJI/psEULjkClhvJo4Lvg==",
       "dev": true,
       "requires": {
-        "cssesc": "^0.1.0",
-        "fastparse": "^1.1.1",
-        "regexpu-core": "^1.0.0"
-      },
-      "dependencies": {
-        "regexpu-core": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz",
-          "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=",
-          "dev": true,
-          "requires": {
-            "regenerate": "^1.2.1",
-            "regjsgen": "^0.2.0",
-            "regjsparser": "^0.1.4"
-          }
-        }
+        "cssesc": "^3.0.0",
+        "fastparse": "^1.1.2"
       }
     },
     "cssesc": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz",
-      "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+      "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
       "dev": true
     },
     "cssnano": {
@@ -2526,20 +2692,14 @@
         "source-map": "^0.5.3"
       }
     },
-    "ctype": {
-      "version": "0.5.3",
-      "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz",
-      "integrity": "sha1-gsGMJGH3QRTvFsE1IkrQuRRMoS8=",
-      "dev": true
-    },
     "danger": {
-      "version": "9.2.2",
-      "resolved": "https://registry.npmjs.org/danger/-/danger-9.2.2.tgz",
-      "integrity": "sha512-tDLIFYa1KzU7HJIvn6FEurFWqn36cFPVBLvKrUqbRxJOCPONWNvpRRbHKj3HmNPEQf5bVls78V/FZz8iRs4Qlg==",
+      "version": "9.4.0",
+      "resolved": "https://registry.npmjs.org/danger/-/danger-9.4.0.tgz",
+      "integrity": "sha512-VTuq6ZN2eZYXSTAlze8AZnEvnzghBM6fzQh+2JM04ZivN315wAQbHGoyhOOzMizpUI4FaRKlZFVMZnGQlrGaLA==",
       "dev": true,
       "requires": {
         "@babel/polyfill": "^7.2.5",
-        "@octokit/rest": "^16.14.1",
+        "@octokit/rest": "^16.43.1",
         "async-retry": "1.2.3",
         "chalk": "^2.3.0",
         "commander": "^2.18.0",
@@ -2564,7 +2724,7 @@
         "node-fetch": "^2.3.0",
         "override-require": "^1.1.1",
         "p-limit": "^2.1.0",
-        "parse-diff": "^0.5.1",
+        "parse-diff": "^0.7.0",
         "parse-git-config": "^2.0.3",
         "parse-github-url": "^1.0.2",
         "parse-link-header": "^1.0.1",
@@ -2576,15 +2736,6 @@
         "supports-hyperlinks": "^1.0.1"
       },
       "dependencies": {
-        "agent-base": {
-          "version": "4.3.0",
-          "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz",
-          "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==",
-          "dev": true,
-          "requires": {
-            "es6-promisify": "^5.0.0"
-          }
-        },
         "ansi-styles": {
           "version": "3.2.1",
           "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
@@ -2594,47 +2745,6 @@
             "color-convert": "^1.9.0"
           }
         },
-        "arr-diff": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
-          "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
-          "dev": true
-        },
-        "array-unique": {
-          "version": "0.3.2",
-          "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
-          "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
-          "dev": true
-        },
-        "braces": {
-          "version": "2.3.2",
-          "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
-          "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
-          "dev": true,
-          "requires": {
-            "arr-flatten": "^1.1.0",
-            "array-unique": "^0.3.2",
-            "extend-shallow": "^2.0.1",
-            "fill-range": "^4.0.0",
-            "isobject": "^3.0.1",
-            "repeat-element": "^1.1.2",
-            "snapdragon": "^0.8.1",
-            "snapdragon-node": "^2.0.1",
-            "split-string": "^3.0.2",
-            "to-regex": "^3.0.1"
-          },
-          "dependencies": {
-            "extend-shallow": {
-              "version": "2.0.1",
-              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
-              "dev": true,
-              "requires": {
-                "is-extendable": "^0.1.0"
-              }
-            }
-          }
-        },
         "chalk": {
           "version": "2.4.2",
           "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
@@ -2646,185 +2756,13 @@
             "supports-color": "^5.3.0"
           }
         },
-        "commander": {
-          "version": "2.20.3",
-          "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
-          "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
-          "dev": true
-        },
         "debug": {
-          "version": "4.1.1",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
-          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "version": "4.3.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+          "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
           "dev": true,
           "requires": {
-            "ms": "^2.1.1"
-          }
-        },
-        "expand-brackets": {
-          "version": "2.1.4",
-          "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
-          "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
-          "dev": true,
-          "requires": {
-            "debug": "^2.3.3",
-            "define-property": "^0.2.5",
-            "extend-shallow": "^2.0.1",
-            "posix-character-classes": "^0.1.0",
-            "regex-not": "^1.0.0",
-            "snapdragon": "^0.8.1",
-            "to-regex": "^3.0.1"
-          },
-          "dependencies": {
-            "debug": {
-              "version": "2.6.9",
-              "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-              "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-              "dev": true,
-              "requires": {
-                "ms": "2.0.0"
-              }
-            },
-            "define-property": {
-              "version": "0.2.5",
-              "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
-              "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
-              "dev": true,
-              "requires": {
-                "is-descriptor": "^0.1.0"
-              }
-            },
-            "extend-shallow": {
-              "version": "2.0.1",
-              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
-              "dev": true,
-              "requires": {
-                "is-extendable": "^0.1.0"
-              }
-            },
-            "is-accessor-descriptor": {
-              "version": "0.1.6",
-              "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
-              "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
-              "dev": true,
-              "requires": {
-                "kind-of": "^3.0.2"
-              },
-              "dependencies": {
-                "kind-of": {
-                  "version": "3.2.2",
-                  "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-                  "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-                  "dev": true,
-                  "requires": {
-                    "is-buffer": "^1.1.5"
-                  }
-                }
-              }
-            },
-            "is-data-descriptor": {
-              "version": "0.1.4",
-              "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
-              "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
-              "dev": true,
-              "requires": {
-                "kind-of": "^3.0.2"
-              },
-              "dependencies": {
-                "kind-of": {
-                  "version": "3.2.2",
-                  "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-                  "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-                  "dev": true,
-                  "requires": {
-                    "is-buffer": "^1.1.5"
-                  }
-                }
-              }
-            },
-            "is-descriptor": {
-              "version": "0.1.6",
-              "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
-              "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
-              "dev": true,
-              "requires": {
-                "is-accessor-descriptor": "^0.1.6",
-                "is-data-descriptor": "^0.1.4",
-                "kind-of": "^5.0.0"
-              }
-            },
-            "kind-of": {
-              "version": "5.1.0",
-              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
-              "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
-              "dev": true
-            },
-            "ms": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-              "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-              "dev": true
-            }
-          }
-        },
-        "extglob": {
-          "version": "2.0.4",
-          "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
-          "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
-          "dev": true,
-          "requires": {
-            "array-unique": "^0.3.2",
-            "define-property": "^1.0.0",
-            "expand-brackets": "^2.1.4",
-            "extend-shallow": "^2.0.1",
-            "fragment-cache": "^0.2.1",
-            "regex-not": "^1.0.0",
-            "snapdragon": "^0.8.1",
-            "to-regex": "^3.0.1"
-          },
-          "dependencies": {
-            "define-property": {
-              "version": "1.0.0",
-              "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
-              "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
-              "dev": true,
-              "requires": {
-                "is-descriptor": "^1.0.0"
-              }
-            },
-            "extend-shallow": {
-              "version": "2.0.1",
-              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
-              "dev": true,
-              "requires": {
-                "is-extendable": "^0.1.0"
-              }
-            }
-          }
-        },
-        "fill-range": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
-          "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
-          "dev": true,
-          "requires": {
-            "extend-shallow": "^2.0.1",
-            "is-number": "^3.0.0",
-            "repeat-string": "^1.6.1",
-            "to-regex-range": "^2.1.0"
-          },
-          "dependencies": {
-            "extend-shallow": {
-              "version": "2.0.1",
-              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
-              "dev": true,
-              "requires": {
-                "is-extendable": "^0.1.0"
-              }
-            }
+            "ms": "2.1.2"
           }
         },
         "has-flag": {
@@ -2833,146 +2771,25 @@
           "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
           "dev": true
         },
-        "https-proxy-agent": {
-          "version": "2.2.4",
-          "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz",
-          "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==",
-          "dev": true,
-          "requires": {
-            "agent-base": "^4.3.0",
-            "debug": "^3.1.0"
-          },
-          "dependencies": {
-            "debug": {
-              "version": "3.2.6",
-              "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
-              "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
-              "dev": true,
-              "requires": {
-                "ms": "^2.1.1"
-              }
-            }
-          }
-        },
-        "is-accessor-descriptor": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
-          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
-          "dev": true,
-          "requires": {
-            "kind-of": "^6.0.0"
-          }
-        },
-        "is-data-descriptor": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
-          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
-          "dev": true,
-          "requires": {
-            "kind-of": "^6.0.0"
-          }
-        },
-        "is-descriptor": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
-          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
-          "dev": true,
-          "requires": {
-            "is-accessor-descriptor": "^1.0.0",
-            "is-data-descriptor": "^1.0.0",
-            "kind-of": "^6.0.2"
-          }
-        },
-        "is-number": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
-          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
-          "dev": true,
-          "requires": {
-            "kind-of": "^3.0.2"
-          },
-          "dependencies": {
-            "kind-of": {
-              "version": "3.2.2",
-              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-              "dev": true,
-              "requires": {
-                "is-buffer": "^1.1.5"
-              }
-            }
-          }
-        },
-        "isobject": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
-          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
-          "dev": true
-        },
         "json5": {
-          "version": "2.1.1",
-          "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz",
-          "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==",
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
+          "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
           "dev": true,
           "requires": {
-            "minimist": "^1.2.0"
+            "minimist": "^1.2.5"
           }
         },
-        "kind-of": {
-          "version": "6.0.2",
-          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
-          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
-          "dev": true
-        },
-        "micromatch": {
-          "version": "3.1.10",
-          "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
-          "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
-          "dev": true,
-          "requires": {
-            "arr-diff": "^4.0.0",
-            "array-unique": "^0.3.2",
-            "braces": "^2.3.1",
-            "define-property": "^2.0.2",
-            "extend-shallow": "^3.0.2",
-            "extglob": "^2.0.4",
-            "fragment-cache": "^0.2.1",
-            "kind-of": "^6.0.2",
-            "nanomatch": "^1.2.9",
-            "object.pick": "^1.3.0",
-            "regex-not": "^1.0.0",
-            "snapdragon": "^0.8.1",
-            "to-regex": "^3.0.2"
-          }
-        },
-        "minimist": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
-          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
-          "dev": true
-        },
         "ms": {
           "version": "2.1.2",
           "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
           "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
           "dev": true
         },
-        "node-fetch": {
-          "version": "2.6.0",
-          "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
-          "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==",
-          "dev": true
-        },
         "parse-diff": {
-          "version": "0.5.1",
-          "resolved": "https://registry.npmjs.org/parse-diff/-/parse-diff-0.5.1.tgz",
-          "integrity": "sha512-/qXjo9x/pFa5bVk/ZXaJD0yr3Tf3Yp6MWWMr4vnUmumDrE0yoE6YDH2A8vmcCD/Ko3tW2o0X+zGYh2zMLXshsg==",
-          "dev": true
-        },
-        "require-from-string": {
-          "version": "2.0.2",
-          "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
-          "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+          "version": "0.7.1",
+          "resolved": "https://registry.npmjs.org/parse-diff/-/parse-diff-0.7.1.tgz",
+          "integrity": "sha512-1j3l8IKcy4yRK2W4o9EYvJLSzpAVwz4DXqCewYyx2vEwk2gcf3DBPqc8Fj4XV3K33OYJ08A8fWwyu/ykD/HUSg==",
           "dev": true
         },
         "supports-color": {
@@ -2986,6 +2803,12 @@
         }
       }
     },
+    "dash-ast": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz",
+      "integrity": "sha512-Vy4dx7gquTeMcQR/hDkYLGUnwVil6vk4FOOct+djUnHOUWt+zJPJAaRIXaAFkPXtJjvlY7o3rfRu0/3hpnwoUA==",
+      "dev": true
+    },
     "dashdash": {
       "version": "1.14.1",
       "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
@@ -2995,9 +2818,9 @@
       }
     },
     "datahub-nodejs-sdk": {
-      "version": "1.0.10",
-      "resolved": "https://registry.npmjs.org/datahub-nodejs-sdk/-/datahub-nodejs-sdk-1.0.10.tgz",
-      "integrity": "sha512-yaK3ztQYUJTZMfsafPYy1QQnSP4rUEfCCptrbn2UMELt7gK2rJzd7agHog7cohjpj/FnJFMCYnNnNlw3AM2YGw==",
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/datahub-nodejs-sdk/-/datahub-nodejs-sdk-1.1.0.tgz",
+      "integrity": "sha512-OYPLVfPT3Lb5ChsocHcn5FQYvz6zPV4ThEKKs+JWN0ERMmfIaHgivKv4Ps8taUJm0v5b5hHiYw3u+QbRxS1eZQ==",
       "dev": true,
       "requires": {
         "isomorphic-fetch": "2"
@@ -3008,12 +2831,6 @@
       "resolved": "https://registry.npmjs.org/date-format/-/date-format-0.0.0.tgz",
       "integrity": "sha1-CSBoY6sHDrRZrOpVQsvYVrEZZrM="
     },
-    "date-now": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
-      "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=",
-      "dev": true
-    },
     "dateformat": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz",
@@ -3113,18 +2930,6 @@
             "is-data-descriptor": "^1.0.0",
             "kind-of": "^6.0.2"
           }
-        },
-        "isobject": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
-          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
-          "dev": true
-        },
-        "kind-of": {
-          "version": "6.0.2",
-          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
-          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
-          "dev": true
         }
       }
     },
@@ -3160,13 +2965,13 @@
       "dev": true
     },
     "deps-sort": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz",
-      "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=",
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.1.tgz",
+      "integrity": "sha512-1orqXQr5po+3KI6kQb9A4jnXT1PBwggGl2d7Sq2xsnOeI9GPcE/tGcF9UiSZtZBM7MukY4cAh7MemS6tZYipfw==",
       "dev": true,
       "requires": {
         "JSONStream": "^1.0.3",
-        "shasum": "^1.0.0",
+        "shasum-object": "^1.0.0",
         "subarg": "^1.0.0",
         "through2": "^2.0.0"
       }
@@ -3181,9 +2986,9 @@
       }
     },
     "detect-port": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.2.3.tgz",
-      "integrity": "sha512-IDbrX6PxqnYy8jV4wSHBaJlErYKTJvW8OQb9F7xivl1iQLqiUYHGa+nZ61Do6+N5uuOn/pReXKNqI9rUn04vug==",
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.3.0.tgz",
+      "integrity": "sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ==",
       "dev": true,
       "requires": {
         "address": "^1.0.1",
@@ -3198,20 +3003,12 @@
       "requires": {
         "acorn": "^5.2.1",
         "defined": "^1.0.0"
-      },
-      "dependencies": {
-        "acorn": {
-          "version": "5.7.1",
-          "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz",
-          "integrity": "sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ==",
-          "dev": true
-        }
       }
     },
     "diff": {
-      "version": "3.5.0",
-      "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
-      "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz",
+      "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=",
       "dev": true
     },
     "doctrine": {
@@ -3269,9 +3066,9 @@
           "dev": true
         },
         "readable-stream": {
-          "version": "2.3.6",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
-          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "version": "2.3.7",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+          "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
           "dev": true,
           "requires": {
             "core-util-is": "~1.0.0",
@@ -3283,6 +3080,12 @@
             "util-deprecate": "~1.0.1"
           }
         },
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+          "dev": true
+        },
         "string_decoder": {
           "version": "1.1.1",
           "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@@ -3295,12 +3098,12 @@
       }
     },
     "ecc-jsbn": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
-      "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
-      "optional": true,
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+      "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
       "requires": {
-        "jsbn": "~0.1.0"
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.1.0"
       }
     },
     "ecdsa-sig-formatter": {
@@ -3322,44 +3125,24 @@
         "mime": "^1.2.11",
         "minimist": "^1.1.0",
         "url-join": "^1.0.0"
-      },
-      "dependencies": {
-        "minimist": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
-          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
-          "dev": true
-        }
       }
     },
     "editorconfig": {
-      "version": "0.13.3",
-      "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.13.3.tgz",
-      "integrity": "sha512-WkjsUNVCu+ITKDj73QDvi0trvpdDWdkDyHybDGSXPfekLCqwmpD7CP7iPbvBgosNuLcI96XTDwNa75JyFl7tEQ==",
+      "version": "0.15.3",
+      "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz",
+      "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==",
       "dev": true,
       "requires": {
-        "bluebird": "^3.0.5",
-        "commander": "^2.9.0",
-        "lru-cache": "^3.2.0",
-        "semver": "^5.1.0",
+        "commander": "^2.19.0",
+        "lru-cache": "^4.1.5",
+        "semver": "^5.6.0",
         "sigmund": "^1.0.1"
-      },
-      "dependencies": {
-        "lru-cache": {
-          "version": "3.2.0",
-          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-3.2.0.tgz",
-          "integrity": "sha1-cXibO39Tmb7IVl3aOKow0qCX7+4=",
-          "dev": true,
-          "requires": {
-            "pseudomap": "^1.0.1"
-          }
-        }
       }
     },
     "electron-to-chromium": {
-      "version": "1.3.52",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.52.tgz",
-      "integrity": "sha1-0tnxJwuko7lnuDHEDvcftNmrXOA=",
+      "version": "1.3.727",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.727.tgz",
+      "integrity": "sha512-Mfz4FIB4FSvEwBpDfdipRIrwd6uo8gUDoRDF4QEYb4h4tSuI3ov594OrjU6on042UlFHouIJpClDODGkPcBSbg==",
       "dev": true
     },
     "emojis-list": {
@@ -3369,18 +3152,29 @@
       "dev": true
     },
     "encoding": {
-      "version": "0.1.12",
-      "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
-      "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
+      "version": "0.1.13",
+      "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
+      "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
       "dev": true,
       "requires": {
-        "iconv-lite": "~0.4.13"
+        "iconv-lite": "^0.6.2"
+      },
+      "dependencies": {
+        "iconv-lite": {
+          "version": "0.6.2",
+          "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz",
+          "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==",
+          "dev": true,
+          "requires": {
+            "safer-buffer": ">= 2.1.2 < 3.0.0"
+          }
+        }
       }
     },
     "end-of-stream": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
-      "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
+      "version": "1.4.4",
+      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+      "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
       "dev": true,
       "requires": {
         "once": "^1.4.0"
@@ -3406,9 +3200,9 @@
       }
     },
     "errno": {
-      "version": "0.1.7",
-      "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
-      "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
+      "version": "0.1.8",
+      "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
+      "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
       "dev": true,
       "requires": {
         "prr": "~1.0.1"
@@ -3424,9 +3218,9 @@
       }
     },
     "es6-promise": {
-      "version": "4.2.4",
-      "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz",
-      "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==",
+      "version": "4.2.8",
+      "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
+      "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==",
       "dev": true
     },
     "es6-promisify": {
@@ -3470,9 +3264,9 @@
       }
     },
     "eslint": {
-      "version": "4.18.2",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.18.2.tgz",
-      "integrity": "sha512-qy4i3wODqKMYfz9LUI8N2qYDkHkoieTbiHpMrYUI/WbjhXJQr7lI4VngixTgaG+yHX+NBCv7nW4hA0ShbvaNKw==",
+      "version": "4.19.1",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz",
+      "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==",
       "dev": true,
       "requires": {
         "ajv": "^5.3.0",
@@ -3484,7 +3278,7 @@
         "doctrine": "^2.1.0",
         "eslint-scope": "^3.7.1",
         "eslint-visitor-keys": "^1.0.0",
-        "espree": "^3.5.2",
+        "espree": "^3.5.4",
         "esquery": "^1.0.0",
         "esutils": "^2.0.2",
         "file-entry-cache": "^2.0.0",
@@ -3506,6 +3300,7 @@
         "path-is-inside": "^1.0.2",
         "pluralize": "^7.0.0",
         "progress": "^2.0.0",
+        "regexpp": "^1.0.1",
         "require-uncached": "^1.0.3",
         "semver": "^5.3.0",
         "strip-ansi": "^4.0.0",
@@ -3514,6 +3309,18 @@
         "text-table": "~0.2.0"
       },
       "dependencies": {
+        "ajv": {
+          "version": "5.5.2",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
+          "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
+          "dev": true,
+          "requires": {
+            "co": "^4.6.0",
+            "fast-deep-equal": "^1.0.0",
+            "fast-json-stable-stringify": "^2.0.0",
+            "json-schema-traverse": "^0.3.0"
+          }
+        },
         "ansi-regex": {
           "version": "3.0.0",
           "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
@@ -3552,18 +3359,24 @@
           }
         },
         "debug": {
-          "version": "3.2.6",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
-          "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+          "version": "3.2.7",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+          "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
           "dev": true,
           "requires": {
             "ms": "^2.1.1"
           }
         },
+        "fast-deep-equal": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
+          "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=",
+          "dev": true
+        },
         "glob": {
-          "version": "7.1.5",
-          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz",
-          "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==",
+          "version": "7.1.7",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
+          "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
           "dev": true,
           "requires": {
             "fs.realpath": "^1.0.0",
@@ -3586,16 +3399,16 @@
           "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
           "dev": true
         },
-        "ms": {
-          "version": "2.1.2",
-          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+        "json-schema-traverse": {
+          "version": "0.3.1",
+          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
+          "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
           "dev": true
         },
-        "progress": {
-          "version": "2.0.3",
-          "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
-          "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+        "ms": {
+          "version": "2.1.3",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+          "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
           "dev": true
         },
         "strip-ansi": {
@@ -3619,9 +3432,9 @@
       }
     },
     "eslint-plugin-flowtype": {
-      "version": "2.50.0",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.50.0.tgz",
-      "integrity": "sha512-10FnBXCp8odYcpUFXGAh+Zko7py0hUWutTd3BN/R9riukH360qNPLYPR3/xV9eu9K7OJDjJrsflBnL6RwxFnlw==",
+      "version": "2.50.3",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.50.3.tgz",
+      "integrity": "sha512-X+AoKVOr7Re0ko/yEXyM5SSZ0tazc6ffdIOocp2fFUlWoDt7DV0Bz99mngOkAFLOAWjqRA5jPwqUCbrx13XoxQ==",
       "dev": true,
       "requires": {
         "lodash": "^4.17.10"
@@ -3638,17 +3451,17 @@
       },
       "dependencies": {
         "estraverse": {
-          "version": "4.2.0",
-          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
-          "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
+          "version": "4.3.0",
+          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+          "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
           "dev": true
         }
       }
     },
     "eslint-visitor-keys": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
-      "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==",
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
+      "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
       "dev": true
     },
     "espree": {
@@ -3659,14 +3472,6 @@
       "requires": {
         "acorn": "^5.5.0",
         "acorn-jsx": "^3.0.0"
-      },
-      "dependencies": {
-        "acorn": {
-          "version": "5.7.1",
-          "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz",
-          "integrity": "sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ==",
-          "dev": true
-        }
       }
     },
     "esprima": {
@@ -3676,35 +3481,35 @@
       "dev": true
     },
     "esquery": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz",
-      "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==",
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
+      "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
       "dev": true,
       "requires": {
-        "estraverse": "^4.0.0"
+        "estraverse": "^5.1.0"
       },
       "dependencies": {
         "estraverse": {
-          "version": "4.2.0",
-          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
-          "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+          "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
           "dev": true
         }
       }
     },
     "esrecurse": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
-      "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+      "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
       "dev": true,
       "requires": {
-        "estraverse": "^4.1.0"
+        "estraverse": "^5.2.0"
       },
       "dependencies": {
         "estraverse": {
-          "version": "4.2.0",
-          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
-          "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+          "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
           "dev": true
         }
       }
@@ -3716,15 +3521,15 @@
       "dev": true
     },
     "estree-walker": {
-      "version": "0.5.2",
-      "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.5.2.tgz",
-      "integrity": "sha512-XpCnW/AE10ws/kDAs37cngSkvgIR8aN3G0MS85m7dUpuK2EREo9VJ00uvw6Dg/hXEpfsE1I1TvJOJr+Z+TL+ig==",
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz",
+      "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==",
       "dev": true
     },
     "esutils": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
-      "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
       "dev": true
     },
     "event-target-shim": {
@@ -3733,9 +3538,9 @@
       "integrity": "sha1-psB/snNJWjeJ4QW0n8w8sKMI+rQ="
     },
     "eventemitter3": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz",
-      "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==",
+      "version": "4.0.7",
+      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
+      "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
       "dev": true
     },
     "events": {
@@ -3775,12 +3580,38 @@
       }
     },
     "expand-brackets": {
-      "version": "0.1.5",
-      "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
-      "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+      "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
       "dev": true,
       "requires": {
-        "is-posix-bracket": "^0.1.0"
+        "debug": "^2.3.3",
+        "define-property": "^0.2.5",
+        "extend-shallow": "^2.0.1",
+        "posix-character-classes": "^0.1.0",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        },
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
       }
     },
     "expand-range": {
@@ -3790,6 +3621,54 @@
       "dev": true,
       "requires": {
         "fill-range": "^2.1.0"
+      },
+      "dependencies": {
+        "fill-range": {
+          "version": "2.2.4",
+          "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz",
+          "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==",
+          "dev": true,
+          "requires": {
+            "is-number": "^2.1.0",
+            "isobject": "^2.0.0",
+            "randomatic": "^3.0.0",
+            "repeat-element": "^1.1.2",
+            "repeat-string": "^1.5.2"
+          }
+        },
+        "is-number": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
+          "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=",
+          "dev": true,
+          "requires": {
+            "kind-of": "^3.0.2"
+          }
+        },
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "isobject": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+          "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+          "dev": true,
+          "requires": {
+            "isarray": "1.0.0"
+          }
+        },
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
       }
     },
     "expand-tilde": {
@@ -3833,12 +3712,6 @@
           "requires": {
             "isobject": "^3.0.1"
           }
-        },
-        "isobject": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
-          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
-          "dev": true
         }
       }
     },
@@ -3854,24 +3727,80 @@
       }
     },
     "extglob": {
-      "version": "0.3.2",
-      "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
-      "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+      "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
       "dev": true,
       "requires": {
-        "is-extglob": "^1.0.0"
+        "array-unique": "^0.3.2",
+        "define-property": "^1.0.0",
+        "expand-brackets": "^2.1.4",
+        "extend-shallow": "^2.0.1",
+        "fragment-cache": "^0.2.1",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^1.0.0"
+          }
+        },
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
       }
     },
     "extract-zip": {
-      "version": "1.6.7",
-      "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz",
-      "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=",
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz",
+      "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==",
       "dev": true,
       "requires": {
-        "concat-stream": "1.6.2",
-        "debug": "2.6.9",
-        "mkdirp": "0.5.1",
-        "yauzl": "2.4.1"
+        "concat-stream": "^1.6.2",
+        "debug": "^2.6.9",
+        "mkdirp": "^0.5.4",
+        "yauzl": "^2.10.0"
       }
     },
     "extsprintf": {
@@ -3880,14 +3809,14 @@
       "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
     },
     "fast-deep-equal": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
-      "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ="
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
     },
     "fast-json-stable-stringify": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
-      "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
     },
     "fast-levenshtein": {
       "version": "2.0.6",
@@ -3895,6 +3824,12 @@
       "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
       "dev": true
     },
+    "fast-safe-stringify": {
+      "version": "2.0.7",
+      "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz",
+      "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==",
+      "dev": true
+    },
     "fast-url-parser": {
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz",
@@ -3902,18 +3837,26 @@
       "dev": true,
       "requires": {
         "punycode": "^1.3.2"
+      },
+      "dependencies": {
+        "punycode": {
+          "version": "1.4.1",
+          "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+          "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+          "dev": true
+        }
       }
     },
     "fastparse": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.1.tgz",
-      "integrity": "sha1-0eJkOzipTXWDtHkGDmxK/8lAcfg=",
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz",
+      "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==",
       "dev": true
     },
     "fd-slicer": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
-      "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
+      "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
       "dev": true,
       "requires": {
         "pend": "~1.2.0"
@@ -3938,6 +3881,13 @@
         "object-assign": "^4.0.1"
       }
     },
+    "file-uri-to-path": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
+      "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
+      "dev": true,
+      "optional": true
+    },
     "filename-regex": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
@@ -3966,18 +3916,34 @@
       }
     },
     "fill-range": {
-      "version": "2.2.4",
-      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz",
-      "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+      "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
       "dev": true,
       "requires": {
-        "is-number": "^2.1.0",
-        "isobject": "^2.0.0",
-        "randomatic": "^3.0.0",
-        "repeat-element": "^1.1.2",
-        "repeat-string": "^1.5.2"
+        "extend-shallow": "^2.0.1",
+        "is-number": "^3.0.0",
+        "repeat-string": "^1.6.1",
+        "to-regex-range": "^2.1.0"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
       }
     },
+    "filter-obj": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz",
+      "integrity": "sha1-mzERErxsYSehbgFsbF1/GeCAXFs=",
+      "dev": true
+    },
     "find-cache-dir": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-0.1.1.tgz",
@@ -4006,36 +3972,21 @@
       }
     },
     "flat-cache": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz",
-      "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=",
+      "version": "1.3.4",
+      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz",
+      "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==",
       "dev": true,
       "requires": {
         "circular-json": "^0.3.1",
-        "del": "^2.0.2",
         "graceful-fs": "^4.1.2",
+        "rimraf": "~2.6.2",
         "write": "^0.2.1"
       },
       "dependencies": {
-        "del": {
-          "version": "2.2.2",
-          "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz",
-          "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=",
-          "dev": true,
-          "requires": {
-            "globby": "^5.0.0",
-            "is-path-cwd": "^1.0.0",
-            "is-path-in-cwd": "^1.0.0",
-            "object-assign": "^4.0.1",
-            "pify": "^2.0.0",
-            "pinkie-promise": "^2.0.0",
-            "rimraf": "^2.2.8"
-          }
-        },
         "glob": {
-          "version": "7.1.2",
-          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
-          "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+          "version": "7.1.7",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
+          "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
           "dev": true,
           "requires": {
             "fs.realpath": "^1.0.0",
@@ -4046,32 +3997,21 @@
             "path-is-absolute": "^1.0.0"
           }
         },
-        "globby": {
-          "version": "5.0.0",
-          "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
-          "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
+        "rimraf": {
+          "version": "2.6.3",
+          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
+          "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
           "dev": true,
           "requires": {
-            "array-union": "^1.0.1",
-            "arrify": "^1.0.0",
-            "glob": "^7.0.3",
-            "object-assign": "^4.0.1",
-            "pify": "^2.0.0",
-            "pinkie-promise": "^2.0.0"
+            "glob": "^7.1.3"
           }
-        },
-        "pify": {
-          "version": "2.3.0",
-          "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
-          "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
-          "dev": true
         }
       }
     },
     "flatten": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz",
-      "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=",
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz",
+      "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==",
       "dev": true
     },
     "follow-redirects": {
@@ -4105,12 +4045,12 @@
       "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
     },
     "form-data": {
-      "version": "2.3.2",
-      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
-      "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+      "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
       "requires": {
         "asynckit": "^0.4.0",
-        "combined-stream": "1.0.6",
+        "combined-stream": "^1.0.6",
         "mime-types": "^2.1.12"
       }
     },
@@ -4155,617 +4095,14 @@
       "dev": true
     },
     "fsevents": {
-      "version": "1.2.4",
-      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz",
-      "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==",
+      "version": "1.2.13",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
+      "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
       "dev": true,
       "optional": true,
       "requires": {
-        "nan": "^2.9.2",
-        "node-pre-gyp": "^0.10.0"
-      },
-      "dependencies": {
-        "abbrev": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
-          "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
-          "dev": true,
-          "optional": true
-        },
-        "ansi-regex": {
-          "version": "2.1.1",
-          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
-          "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
-          "dev": true,
-          "optional": true
-        },
-        "aproba": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
-          "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
-          "dev": true,
-          "optional": true
-        },
-        "are-we-there-yet": {
-          "version": "1.1.4",
-          "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz",
-          "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "delegates": "^1.0.0",
-            "readable-stream": "^2.0.6"
-          }
-        },
-        "balanced-match": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
-          "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
-          "dev": true,
-          "optional": true
-        },
-        "brace-expansion": {
-          "version": "1.1.11",
-          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
-          "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "balanced-match": "^1.0.0",
-            "concat-map": "0.0.1"
-          }
-        },
-        "chownr": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz",
-          "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=",
-          "dev": true,
-          "optional": true
-        },
-        "code-point-at": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
-          "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
-          "dev": true,
-          "optional": true
-        },
-        "concat-map": {
-          "version": "0.0.1",
-          "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-          "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
-          "dev": true,
-          "optional": true
-        },
-        "console-control-strings": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
-          "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
-          "dev": true,
-          "optional": true
-        },
-        "core-util-is": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
-          "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
-          "dev": true,
-          "optional": true
-        },
-        "debug": {
-          "version": "2.6.9",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "ms": "2.0.0"
-          }
-        },
-        "deep-extend": {
-          "version": "0.5.1",
-          "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.1.tgz",
-          "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==",
-          "dev": true,
-          "optional": true
-        },
-        "delegates": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
-          "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
-          "dev": true,
-          "optional": true
-        },
-        "detect-libc": {
-          "version": "1.0.3",
-          "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
-          "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=",
-          "dev": true,
-          "optional": true
-        },
-        "fs-minipass": {
-          "version": "1.2.5",
-          "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz",
-          "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "minipass": "^2.2.1"
-          }
-        },
-        "fs.realpath": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-          "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
-          "dev": true,
-          "optional": true
-        },
-        "gauge": {
-          "version": "2.7.4",
-          "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
-          "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "aproba": "^1.0.3",
-            "console-control-strings": "^1.0.0",
-            "has-unicode": "^2.0.0",
-            "object-assign": "^4.1.0",
-            "signal-exit": "^3.0.0",
-            "string-width": "^1.0.1",
-            "strip-ansi": "^3.0.1",
-            "wide-align": "^1.1.0"
-          }
-        },
-        "glob": {
-          "version": "7.1.2",
-          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
-          "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "fs.realpath": "^1.0.0",
-            "inflight": "^1.0.4",
-            "inherits": "2",
-            "minimatch": "^3.0.4",
-            "once": "^1.3.0",
-            "path-is-absolute": "^1.0.0"
-          }
-        },
-        "has-unicode": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
-          "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
-          "dev": true,
-          "optional": true
-        },
-        "iconv-lite": {
-          "version": "0.4.21",
-          "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.21.tgz",
-          "integrity": "sha512-En5V9za5mBt2oUA03WGD3TwDv0MKAruqsuxstbMUZaj9W9k/m1CV/9py3l0L5kw9Bln8fdHQmzHSYtvpvTLpKw==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "safer-buffer": "^2.1.0"
-          }
-        },
-        "ignore-walk": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz",
-          "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "minimatch": "^3.0.4"
-          }
-        },
-        "inflight": {
-          "version": "1.0.6",
-          "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-          "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "once": "^1.3.0",
-            "wrappy": "1"
-          }
-        },
-        "inherits": {
-          "version": "2.0.3",
-          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
-          "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
-          "dev": true,
-          "optional": true
-        },
-        "ini": {
-          "version": "1.3.5",
-          "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
-          "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
-          "dev": true,
-          "optional": true
-        },
-        "is-fullwidth-code-point": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
-          "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "number-is-nan": "^1.0.0"
-          }
-        },
-        "isarray": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-          "dev": true,
-          "optional": true
-        },
-        "minimatch": {
-          "version": "3.0.4",
-          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
-          "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "brace-expansion": "^1.1.7"
-          }
-        },
-        "minimist": {
-          "version": "0.0.8",
-          "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
-          "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
-          "dev": true,
-          "optional": true
-        },
-        "minipass": {
-          "version": "2.2.4",
-          "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.2.4.tgz",
-          "integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "safe-buffer": "^5.1.1",
-            "yallist": "^3.0.0"
-          }
-        },
-        "minizlib": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.1.0.tgz",
-          "integrity": "sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "minipass": "^2.2.1"
-          }
-        },
-        "mkdirp": {
-          "version": "0.5.1",
-          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
-          "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "minimist": "0.0.8"
-          }
-        },
-        "ms": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-          "dev": true,
-          "optional": true
-        },
-        "needle": {
-          "version": "2.2.0",
-          "resolved": "https://registry.npmjs.org/needle/-/needle-2.2.0.tgz",
-          "integrity": "sha512-eFagy6c+TYayorXw/qtAdSvaUpEbBsDwDyxYFgLZ0lTojfH7K+OdBqAF7TAFwDokJaGpubpSGG0wO3iC0XPi8w==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "debug": "^2.1.2",
-            "iconv-lite": "^0.4.4",
-            "sax": "^1.2.4"
-          }
-        },
-        "node-pre-gyp": {
-          "version": "0.10.0",
-          "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.10.0.tgz",
-          "integrity": "sha512-G7kEonQLRbcA/mOoFoxvlMrw6Q6dPf92+t/l0DFSMuSlDoWaI9JWIyPwK0jyE1bph//CUEL65/Fz1m2vJbmjQQ==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "detect-libc": "^1.0.2",
-            "mkdirp": "^0.5.1",
-            "needle": "^2.2.0",
-            "nopt": "^4.0.1",
-            "npm-packlist": "^1.1.6",
-            "npmlog": "^4.0.2",
-            "rc": "^1.1.7",
-            "rimraf": "^2.6.1",
-            "semver": "^5.3.0",
-            "tar": "^4"
-          }
-        },
-        "nopt": {
-          "version": "4.0.1",
-          "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz",
-          "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "abbrev": "1",
-            "osenv": "^0.1.4"
-          }
-        },
-        "npm-bundled": {
-          "version": "1.0.3",
-          "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.3.tgz",
-          "integrity": "sha512-ByQ3oJ/5ETLyglU2+8dBObvhfWXX8dtPZDMePCahptliFX2iIuhyEszyFk401PZUNQH20vvdW5MLjJxkwU80Ow==",
-          "dev": true,
-          "optional": true
-        },
-        "npm-packlist": {
-          "version": "1.1.10",
-          "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.1.10.tgz",
-          "integrity": "sha512-AQC0Dyhzn4EiYEfIUjCdMl0JJ61I2ER9ukf/sLxJUcZHfo+VyEfz2rMJgLZSS1v30OxPQe1cN0LZA1xbcaVfWA==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "ignore-walk": "^3.0.1",
-            "npm-bundled": "^1.0.1"
-          }
-        },
-        "npmlog": {
-          "version": "4.1.2",
-          "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
-          "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "are-we-there-yet": "~1.1.2",
-            "console-control-strings": "~1.1.0",
-            "gauge": "~2.7.3",
-            "set-blocking": "~2.0.0"
-          }
-        },
-        "number-is-nan": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
-          "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
-          "dev": true,
-          "optional": true
-        },
-        "object-assign": {
-          "version": "4.1.1",
-          "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
-          "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
-          "dev": true,
-          "optional": true
-        },
-        "once": {
-          "version": "1.4.0",
-          "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
-          "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "wrappy": "1"
-          }
-        },
-        "os-homedir": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
-          "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
-          "dev": true,
-          "optional": true
-        },
-        "os-tmpdir": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
-          "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
-          "dev": true,
-          "optional": true
-        },
-        "osenv": {
-          "version": "0.1.5",
-          "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
-          "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "os-homedir": "^1.0.0",
-            "os-tmpdir": "^1.0.0"
-          }
-        },
-        "path-is-absolute": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
-          "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
-          "dev": true,
-          "optional": true
-        },
-        "process-nextick-args": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
-          "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
-          "dev": true,
-          "optional": true
-        },
-        "rc": {
-          "version": "1.2.7",
-          "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.7.tgz",
-          "integrity": "sha512-LdLD8xD4zzLsAT5xyushXDNscEjB7+2ulnl8+r1pnESlYtlJtVSoCMBGr30eDRJ3+2Gq89jK9P9e4tCEH1+ywA==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "deep-extend": "^0.5.1",
-            "ini": "~1.3.0",
-            "minimist": "^1.2.0",
-            "strip-json-comments": "~2.0.1"
-          },
-          "dependencies": {
-            "minimist": {
-              "version": "1.2.0",
-              "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
-              "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
-              "dev": true,
-              "optional": true
-            }
-          }
-        },
-        "readable-stream": {
-          "version": "2.3.6",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
-          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "core-util-is": "~1.0.0",
-            "inherits": "~2.0.3",
-            "isarray": "~1.0.0",
-            "process-nextick-args": "~2.0.0",
-            "safe-buffer": "~5.1.1",
-            "string_decoder": "~1.1.1",
-            "util-deprecate": "~1.0.1"
-          }
-        },
-        "rimraf": {
-          "version": "2.6.2",
-          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
-          "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "glob": "^7.0.5"
-          }
-        },
-        "safe-buffer": {
-          "version": "5.1.1",
-          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
-          "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
-          "dev": true,
-          "optional": true
-        },
-        "safer-buffer": {
-          "version": "2.1.2",
-          "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
-          "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
-          "dev": true,
-          "optional": true
-        },
-        "sax": {
-          "version": "1.2.4",
-          "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
-          "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
-          "dev": true,
-          "optional": true
-        },
-        "semver": {
-          "version": "5.5.0",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
-          "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
-          "dev": true,
-          "optional": true
-        },
-        "set-blocking": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
-          "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
-          "dev": true,
-          "optional": true
-        },
-        "signal-exit": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
-          "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
-          "dev": true,
-          "optional": true
-        },
-        "string-width": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
-          "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "code-point-at": "^1.0.0",
-            "is-fullwidth-code-point": "^1.0.0",
-            "strip-ansi": "^3.0.0"
-          }
-        },
-        "string_decoder": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
-          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "safe-buffer": "~5.1.0"
-          }
-        },
-        "strip-ansi": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
-          "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "ansi-regex": "^2.0.0"
-          }
-        },
-        "strip-json-comments": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
-          "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
-          "dev": true,
-          "optional": true
-        },
-        "tar": {
-          "version": "4.4.1",
-          "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.1.tgz",
-          "integrity": "sha512-O+v1r9yN4tOsvl90p5HAP4AEqbYhx4036AGMm075fH9F8Qwi3oJ+v4u50FkT/KkvywNGtwkk0zRI+8eYm1X/xg==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "chownr": "^1.0.1",
-            "fs-minipass": "^1.2.5",
-            "minipass": "^2.2.4",
-            "minizlib": "^1.1.0",
-            "mkdirp": "^0.5.0",
-            "safe-buffer": "^5.1.1",
-            "yallist": "^3.0.2"
-          }
-        },
-        "util-deprecate": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
-          "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
-          "dev": true,
-          "optional": true
-        },
-        "wide-align": {
-          "version": "1.1.2",
-          "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz",
-          "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "string-width": "^1.0.2"
-          }
-        },
-        "wrappy": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
-          "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
-          "dev": true,
-          "optional": true
-        },
-        "yallist": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz",
-          "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=",
-          "dev": true,
-          "optional": true
-        }
+        "bindings": "^1.5.0",
+        "nan": "^2.12.1"
       }
     },
     "function-bind": {
@@ -4780,21 +4117,6 @@
       "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
       "dev": true
     },
-    "generate-function": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz",
-      "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=",
-      "dev": true
-    },
-    "generate-object-property": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz",
-      "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=",
-      "dev": true,
-      "requires": {
-        "is-property": "^1.0.0"
-      }
-    },
     "get-assigned-identifiers": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz",
@@ -4868,6 +4190,35 @@
         "https-proxy-agent": "^1.0.0",
         "mime": "^1.2.11",
         "netrc": "^0.1.4"
+      },
+      "dependencies": {
+        "agent-base": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz",
+          "integrity": "sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=",
+          "dev": true,
+          "requires": {
+            "extend": "~3.0.0",
+            "semver": "~5.0.1"
+          }
+        },
+        "https-proxy-agent": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz",
+          "integrity": "sha1-NffabEjOTdv6JkiRrFk+5f+GceY=",
+          "dev": true,
+          "requires": {
+            "agent-base": "2",
+            "debug": "2",
+            "extend": "3"
+          }
+        },
+        "semver": {
+          "version": "5.0.3",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz",
+          "integrity": "sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no=",
+          "dev": true
+        }
       }
     },
     "gitlab": {
@@ -4897,12 +4248,13 @@
           }
         },
         "query-string": {
-          "version": "6.8.3",
-          "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.8.3.tgz",
-          "integrity": "sha512-llcxWccnyaWlODe7A9hRjkvdCKamEKTh+wH8ITdTc3OhchaqUZteiSCX/2ablWHVrkVIe04dntnaZJ7BdyW0lQ==",
+          "version": "6.14.1",
+          "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.14.1.tgz",
+          "integrity": "sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw==",
           "dev": true,
           "requires": {
             "decode-uri-component": "^0.2.0",
+            "filter-obj": "^1.1.0",
             "split-on-first": "^1.0.0",
             "strict-uri-encode": "^2.0.0"
           }
@@ -4995,9 +4347,9 @@
       },
       "dependencies": {
         "glob": {
-          "version": "7.1.2",
-          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
-          "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+          "version": "7.1.7",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
+          "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
           "dev": true,
           "requires": {
             "fs.realpath": "^1.0.0",
@@ -5017,9 +4369,9 @@
       }
     },
     "graceful-fs": {
-      "version": "4.1.11",
-      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
-      "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+      "version": "4.2.6",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
+      "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
       "dev": true
     },
     "graceful-readlink": {
@@ -5055,19 +4407,6 @@
             "lodash": "^4.17.14"
           }
         },
-        "commander": {
-          "version": "2.20.3",
-          "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
-          "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
-          "dev": true,
-          "optional": true
-        },
-        "lodash": {
-          "version": "4.17.15",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
-          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
-          "dev": true
-        },
         "source-map": {
           "version": "0.6.1",
           "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -5075,15 +4414,11 @@
           "dev": true
         },
         "uglify-js": {
-          "version": "3.6.5",
-          "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.5.tgz",
-          "integrity": "sha512-7L3W+Npia1OCr5Blp4/Vw83tK1mu5gnoIURtT1fUVfQ3Kf8WStWV6NJz0fdoBJZls0KlweruRTLVe6XLafmy5g==",
+          "version": "3.13.6",
+          "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.6.tgz",
+          "integrity": "sha512-rRprLwl8RVaS+Qvx3Wh5hPfPBn9++G6xkGlUupya0s5aDmNjI7z3lnRLB3u7sN4OmbB0pWgzhM9BEJyiWAwtAA==",
           "dev": true,
-          "optional": true,
-          "requires": {
-            "commander": "~2.20.3",
-            "source-map": "~0.6.1"
-          }
+          "optional": true
         }
       }
     },
@@ -5093,11 +4428,11 @@
       "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
     },
     "har-validator": {
-      "version": "5.0.3",
-      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
-      "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
+      "version": "5.1.5",
+      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
+      "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
       "requires": {
-        "ajv": "^5.1.0",
+        "ajv": "^6.12.3",
         "har-schema": "^2.0.0"
       }
     },
@@ -5134,14 +4469,6 @@
         "get-value": "^2.0.6",
         "has-values": "^1.0.0",
         "isobject": "^3.0.0"
-      },
-      "dependencies": {
-        "isobject": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
-          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
-          "dev": true
-        }
       }
     },
     "has-values": {
@@ -5154,26 +4481,6 @@
         "kind-of": "^4.0.0"
       },
       "dependencies": {
-        "is-number": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
-          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
-          "dev": true,
-          "requires": {
-            "kind-of": "^3.0.2"
-          },
-          "dependencies": {
-            "kind-of": {
-              "version": "3.2.2",
-              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-              "dev": true,
-              "requires": {
-                "is-buffer": "^1.1.5"
-              }
-            }
-          }
-        },
         "kind-of": {
           "version": "4.0.0",
           "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
@@ -5208,15 +4515,15 @@
       "dev": true
     },
     "hawk": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/hawk/-/hawk-2.3.1.tgz",
-      "integrity": "sha1-HnMc45RH+h0PbXB/e87r7A/R7B8=",
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz",
+      "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==",
       "dev": true,
       "requires": {
-        "boom": "2.x.x",
-        "cryptiles": "2.x.x",
-        "hoek": "2.x.x",
-        "sntp": "1.x.x"
+        "boom": "4.x.x",
+        "cryptiles": "3.x.x",
+        "hoek": "4.x.x",
+        "sntp": "2.x.x"
       }
     },
     "he": {
@@ -5226,9 +4533,9 @@
       "dev": true
     },
     "hoek": {
-      "version": "2.16.3",
-      "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
-      "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz",
+      "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==",
       "dev": true
     },
     "home-or-tmp": {
@@ -5251,9 +4558,9 @@
       }
     },
     "html-comment-regex": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.1.tgz",
-      "integrity": "sha1-ZouTd26q5V696POtRkswekljYl4=",
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz",
+      "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==",
       "dev": true
     },
     "htmlescape": {
@@ -5263,33 +4570,21 @@
       "dev": true
     },
     "http-proxy": {
-      "version": "1.17.0",
-      "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz",
-      "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==",
+      "version": "1.18.1",
+      "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
+      "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
       "dev": true,
       "requires": {
-        "eventemitter3": "^3.0.0",
+        "eventemitter3": "^4.0.0",
         "follow-redirects": "^1.0.0",
         "requires-port": "^1.0.0"
       },
       "dependencies": {
-        "debug": {
-          "version": "3.1.0",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
-          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
-          "dev": true,
-          "requires": {
-            "ms": "2.0.0"
-          }
-        },
         "follow-redirects": {
-          "version": "1.5.1",
-          "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.1.tgz",
-          "integrity": "sha512-v9GI1hpaqq1ZZR6pBD1+kI7O24PhDvNGNodjS3MdcEqyrahCp8zbtpv+2B/krUnSmUH80lbAS7MrdeK5IylgKg==",
-          "dev": true,
-          "requires": {
-            "debug": "^3.1.0"
-          }
+          "version": "1.14.1",
+          "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz",
+          "integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==",
+          "dev": true
         }
       }
     },
@@ -5303,15 +4598,6 @@
         "debug": "3.1.0"
       },
       "dependencies": {
-        "agent-base": {
-          "version": "4.3.0",
-          "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz",
-          "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==",
-          "dev": true,
-          "requires": {
-            "es6-promisify": "^5.0.0"
-          }
-        },
         "debug": {
           "version": "3.1.0",
           "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
@@ -5364,14 +4650,30 @@
       "dev": true
     },
     "https-proxy-agent": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz",
-      "integrity": "sha1-NffabEjOTdv6JkiRrFk+5f+GceY=",
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz",
+      "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==",
       "dev": true,
       "requires": {
-        "agent-base": "2",
-        "debug": "2",
-        "extend": "3"
+        "agent-base": "^4.3.0",
+        "debug": "^3.1.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.2.7",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+          "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "ms": {
+          "version": "2.1.3",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+          "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+          "dev": true
+        }
       }
     },
     "humps": {
@@ -5387,9 +4689,9 @@
       "dev": true
     },
     "iconv-lite": {
-      "version": "0.4.23",
-      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
-      "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==",
+      "version": "0.4.24",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
       "requires": {
         "safer-buffer": ">= 2.1.2 < 3"
       }
@@ -5401,9 +4703,9 @@
       "dev": true
     },
     "ieee754": {
-      "version": "1.1.12",
-      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz",
-      "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==",
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
       "dev": true
     },
     "ignore": {
@@ -5441,14 +4743,14 @@
       }
     },
     "inherits": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
-      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
     },
     "ini": {
-      "version": "1.3.5",
-      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
-      "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
+      "version": "1.3.8",
+      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+      "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
       "dev": true
     },
     "inline-source-map": {
@@ -5514,12 +4816,6 @@
           "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
           "dev": true
         },
-        "rx-lite": {
-          "version": "4.0.8",
-          "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
-          "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=",
-          "dev": true
-        },
         "strip-ansi": {
           "version": "4.0.0",
           "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
@@ -5541,9 +4837,9 @@
       }
     },
     "insert-module-globals": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.0.tgz",
-      "integrity": "sha512-VE6NlW+WGn2/AeOMd496AHFYmE7eLKkUY6Ty31k4og5vmA3Fjuwe9v6ifH6Xx/Hz27QvdoMoviw1/pqWRB09Sw==",
+      "version": "7.2.1",
+      "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.1.tgz",
+      "integrity": "sha512-ufS5Qq9RZN+Bu899eA9QCAYThY+gGW7oRkmb0vC93Vlyu/CFGcH0OYPEjVkDXA5FEbTt1+VWzdoOD3Ny9N+8tg==",
       "dev": true,
       "requires": {
         "JSONStream": "^1.0.3",
@@ -5559,9 +4855,9 @@
       }
     },
     "interpret": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz",
-      "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=",
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
+      "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
       "dev": true
     },
     "invariant": {
@@ -5573,6 +4869,12 @@
         "loose-envify": "^1.0.0"
       }
     },
+    "ip-regex": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz",
+      "integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==",
+      "dev": true
+    },
     "ipv4": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/ipv4/-/ipv4-1.0.4.tgz",
@@ -5603,6 +4905,17 @@
       "dev": true,
       "requires": {
         "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
       }
     },
     "is-arrayish": {
@@ -5626,6 +4939,24 @@
       "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
       "dev": true
     },
+    "is-ci": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
+      "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+      "dev": true,
+      "requires": {
+        "ci-info": "^2.0.0"
+      }
+    },
+    "is-core-module": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz",
+      "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==",
+      "dev": true,
+      "requires": {
+        "has": "^1.0.3"
+      }
+    },
     "is-data-descriptor": {
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
@@ -5633,6 +4964,17 @@
       "dev": true,
       "requires": {
         "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
       }
     },
     "is-descriptor": {
@@ -5688,13 +5030,10 @@
       "dev": true
     },
     "is-finite": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
-      "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
-      "dev": true,
-      "requires": {
-        "number-is-nan": "^1.0.0"
-      }
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz",
+      "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==",
+      "dev": true
     },
     "is-fullwidth-code-point": {
       "version": "2.0.0",
@@ -5717,32 +5056,24 @@
       "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=",
       "dev": true
     },
-    "is-my-ip-valid": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz",
-      "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==",
-      "dev": true
-    },
-    "is-my-json-valid": {
-      "version": "2.17.2",
-      "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.17.2.tgz",
-      "integrity": "sha512-IBhBslgngMQN8DDSppmgDv7RNrlFotuuDsKcrCP3+HbFaVivIBU7u9oiiErw8sH4ynx3+gOGQ3q2otkgiSi6kg==",
-      "dev": true,
-      "requires": {
-        "generate-function": "^2.0.0",
-        "generate-object-property": "^1.1.0",
-        "is-my-ip-valid": "^1.0.0",
-        "jsonpointer": "^4.0.0",
-        "xtend": "^4.0.0"
-      }
-    },
     "is-number": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
-      "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+      "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
       "dev": true,
       "requires": {
         "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
       }
     },
     "is-path-cwd": {
@@ -5776,21 +5107,10 @@
       "dev": true
     },
     "is-plain-object": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz",
-      "integrity": "sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==",
-      "dev": true,
-      "requires": {
-        "isobject": "^4.0.0"
-      },
-      "dependencies": {
-        "isobject": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz",
-          "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==",
-          "dev": true
-        }
-      }
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
+      "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
+      "dev": true
     },
     "is-posix-bracket": {
       "version": "0.1.1",
@@ -5804,18 +5124,6 @@
       "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=",
       "dev": true
     },
-    "is-promise": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
-      "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
-      "dev": true
-    },
-    "is-property": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
-      "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=",
-      "dev": true
-    },
     "is-resolvable": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
@@ -5842,6 +5150,12 @@
       "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
       "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
     },
+    "is-url": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz",
+      "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==",
+      "dev": true
+    },
     "is-windows": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
@@ -5854,6 +5168,17 @@
       "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=",
       "dev": true
     },
+    "is2": {
+      "version": "2.0.7",
+      "resolved": "https://registry.npmjs.org/is2/-/is2-2.0.7.tgz",
+      "integrity": "sha512-4vBQoURAXC6hnLFxD4VW7uc04XiwTTl/8ydYJxKvPwkWQrSjInkuM5VZVg6BGr1/natq69zDuvO9lGpLClJqvA==",
+      "dev": true,
+      "requires": {
+        "deep-is": "^0.1.3",
+        "ip-regex": "^4.1.0",
+        "is-url": "^1.2.4"
+      }
+    },
     "isarray": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
@@ -5866,21 +5191,10 @@
       "dev": true
     },
     "isobject": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
-      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
-      "dev": true,
-      "requires": {
-        "isarray": "1.0.0"
-      },
-      "dependencies": {
-        "isarray": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-          "dev": true
-        }
-      }
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+      "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+      "dev": true
     },
     "isomorphic-fetch": {
       "version": "2.2.1",
@@ -5890,6 +5204,18 @@
       "requires": {
         "node-fetch": "^1.0.1",
         "whatwg-fetch": ">=0.10.0"
+      },
+      "dependencies": {
+        "node-fetch": {
+          "version": "1.7.3",
+          "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
+          "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
+          "dev": true,
+          "requires": {
+            "encoding": "^0.1.11",
+            "is-stream": "^1.0.1"
+          }
+        }
       }
     },
     "isstream": {
@@ -5922,21 +5248,53 @@
       }
     },
     "js-base64": {
-      "version": "2.4.8",
-      "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.8.tgz",
-      "integrity": "sha512-hm2nYpDrwoO/OzBhdcqs/XGT6XjSuSSCVEpia+Kl2J6x4CYt5hISlVL/AYU1khoDXv0AQVgxtdJySb9gjAn56Q==",
+      "version": "2.6.4",
+      "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz",
+      "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==",
       "dev": true
     },
     "js-beautify": {
-      "version": "1.7.5",
-      "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.7.5.tgz",
-      "integrity": "sha512-9OhfAqGOrD7hoQBLJMTA+BKuKmoEtTJXzZ7WDF/9gvjtey1koVLuZqIY6c51aPDjbNdNtIXAkiWKVhziawE9Og==",
+      "version": "1.13.13",
+      "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.13.13.tgz",
+      "integrity": "sha512-oH+nc0U5mOAqX8M5JO1J0Pw/7Q35sAdOsM5W3i87pir9Ntx6P/5Gx1xLNoK+MGyvHk4rqqRCE4Oq58H6xl2W7A==",
       "dev": true,
       "requires": {
-        "config-chain": "~1.1.5",
-        "editorconfig": "^0.13.2",
-        "mkdirp": "~0.5.0",
-        "nopt": "~3.0.1"
+        "config-chain": "^1.1.12",
+        "editorconfig": "^0.15.3",
+        "glob": "^7.1.3",
+        "mkdirp": "^1.0.4",
+        "nopt": "^5.0.0"
+      },
+      "dependencies": {
+        "glob": {
+          "version": "7.1.7",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
+          "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
+          "dev": true,
+          "requires": {
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^3.0.4",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
+          }
+        },
+        "mkdirp": {
+          "version": "1.0.4",
+          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+          "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+          "dev": true
+        },
+        "nopt": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
+          "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
+          "dev": true,
+          "requires": {
+            "abbrev": "1"
+          }
+        }
       }
     },
     "js-tokens": {
@@ -5946,9 +5304,9 @@
       "dev": true
     },
     "js-yaml": {
-      "version": "3.12.0",
-      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz",
-      "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==",
+      "version": "3.14.1",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+      "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
       "dev": true,
       "requires": {
         "argparse": "^1.0.7",
@@ -5966,8 +5324,7 @@
     "jsbn": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
-      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
-      "optional": true
+      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
     },
     "jsesc": {
       "version": "1.3.0",
@@ -5987,9 +5344,18 @@
       "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
     },
     "json-schema-traverse": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
-      "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A="
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
+    },
+    "json-stable-stringify": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz",
+      "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=",
+      "dev": true,
+      "requires": {
+        "jsonify": "~0.0.0"
+      }
     },
     "json-stable-stringify-without-jsonify": {
       "version": "1.0.1",
@@ -6039,9 +5405,9 @@
       "dev": true
     },
     "jsonpointer": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz",
-      "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=",
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.1.0.tgz",
+      "integrity": "sha512-CXcRvMyTlnR53xMcKnuMzfCA5i/nfblTnnr74CZb6C4vG39eu6w51t7nKmU5MfLfbTgGItliNyjO/ciNPDqClg==",
       "dev": true
     },
     "jsonwebtoken": {
@@ -6063,15 +5429,9 @@
       },
       "dependencies": {
         "ms": {
-          "version": "2.1.2",
-          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
-          "dev": true
-        },
-        "semver": {
-          "version": "5.7.1",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+          "version": "2.1.3",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+          "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
           "dev": true
         }
       }
@@ -6115,13 +5475,10 @@
       "dev": true
     },
     "kind-of": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-      "dev": true,
-      "requires": {
-        "is-buffer": "^1.1.5"
-      }
+      "version": "6.0.3",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+      "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+      "dev": true
     },
     "klaw": {
       "version": "1.3.1",
@@ -6146,33 +5503,16 @@
       "requires": {
         "abort-controller": "^3.0.0",
         "node-fetch": "^2.6.0"
-      },
-      "dependencies": {
-        "node-fetch": {
-          "version": "2.6.0",
-          "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
-          "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==",
-          "dev": true
-        }
       }
     },
     "labeled-stream-splicer": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.1.tgz",
-      "integrity": "sha512-MC94mHZRvJ3LfykJlTUipBqenZz1pacOZEMhhQ8dMGcDHs0SBE5GbsavUXV7YtP3icBW17W0Zy1I0lfASmo9Pg==",
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.2.tgz",
+      "integrity": "sha512-Ca4LSXFFZUjPScRaqOcFxneA0VpKZr4MMYCljyQr4LIewTLb3Y0IUTIsnBBsVubIeEfxeSZpSjSsRM8APEQaAw==",
       "dev": true,
       "requires": {
         "inherits": "^2.0.1",
-        "isarray": "^2.0.4",
         "stream-splicer": "^2.0.0"
-      },
-      "dependencies": {
-        "isarray": {
-          "version": "2.0.4",
-          "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.4.tgz",
-          "integrity": "sha512-GMxXOiUirWg1xTKRipM0Ek07rX+ubx4nNVElTJdNLYmNO/2YrDkgJGw9CljXn+r4EWiDQg/8lsRdHyg2PJuUaA==",
-          "dev": true
-        }
       }
     },
     "lazy-cache": {
@@ -6233,9 +5573,9 @@
       }
     },
     "lodash": {
-      "version": "4.17.10",
-      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
-      "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==",
+      "version": "4.17.21",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
       "dev": true
     },
     "lodash._objecttypes": {
@@ -6378,32 +5718,79 @@
       }
     },
     "lru-cache": {
-      "version": "4.1.3",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz",
-      "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==",
+      "version": "4.1.5",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+      "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
       "dev": true,
       "requires": {
         "pseudomap": "^1.0.2",
         "yallist": "^2.1.2"
       }
     },
+    "macaca-circular-json": {
+      "version": "0.5.10",
+      "resolved": "https://registry.npmjs.org/macaca-circular-json/-/macaca-circular-json-0.5.10.tgz",
+      "integrity": "sha512-d5/X9RFTo9rp7nbQtj+OaVFRqG8zKWsflsNJ2YOj+aJTgPIcOMJt/mU90J7UmdsalbyLxIft0vWmZt+WelJK0Q==",
+      "dev": true
+    },
     "macaca-coverage": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/macaca-coverage/-/macaca-coverage-1.0.3.tgz",
-      "integrity": "sha512-WeHJDk8WaAwWrKOqlt1GpVSjUF9j2C3/+KIEyJ8ra54jgN1bqpglbjbDIK3iO8CZAl4vkLuNY2gLktF5DSFyyQ==",
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/macaca-coverage/-/macaca-coverage-1.0.7.tgz",
+      "integrity": "sha512-uaFeoLJjbwe1s+Qcgq7ToOJp5+xXdtTjPwI2hHLQEcf1CYcTADYZ20ulYXqg/vaW8iagGHZXvaazy1mp8PONRQ==",
       "dev": true,
       "requires": {
-        "macaca-istanbul": "^1.0.2",
+        "chalk": "^4.1.0",
+        "commander": "^6.2.0",
+        "macaca-istanbul": "^1.0.18",
         "shelljs": "^0.8.1",
         "xlogger": "^1.0.6",
-        "xml2map": "^1.0.2",
-        "xutil": "^1.0.10"
+        "xml2map": "^1.0.2"
       },
       "dependencies": {
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+          "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "commander": {
+          "version": "6.2.1",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
+          "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
+          "dev": true
+        },
         "glob": {
-          "version": "7.1.2",
-          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
-          "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+          "version": "7.1.7",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
+          "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
           "dev": true,
           "requires": {
             "fs.realpath": "^1.0.0",
@@ -6414,23 +5801,38 @@
             "path-is-absolute": "^1.0.0"
           }
         },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
         "shelljs": {
-          "version": "0.8.2",
-          "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.2.tgz",
-          "integrity": "sha512-pRXeNrCA2Wd9itwhvLp5LZQvPJ0wU6bcjaTMywHHGX5XWhVN2nzSu7WV0q+oUY7mGK3mgSkDDzP3MgjqdyIgbQ==",
+          "version": "0.8.4",
+          "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz",
+          "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==",
           "dev": true,
           "requires": {
             "glob": "^7.0.0",
             "interpret": "^1.0.0",
             "rechoir": "^0.6.2"
           }
+        },
+        "supports-color": {
+          "version": "7.2.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
         }
       }
     },
     "macaca-istanbul": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/macaca-istanbul/-/macaca-istanbul-1.0.5.tgz",
-      "integrity": "sha512-YvGkg0M0Sa5C7Q+9dWeicvrFPMSRDWe9Ebw5y296YivxuECo2COLPe5a8wLW6oalVuOMK0a0aRsFyXb6xgGU/g==",
+      "version": "1.0.20",
+      "resolved": "https://registry.npmjs.org/macaca-istanbul/-/macaca-istanbul-1.0.20.tgz",
+      "integrity": "sha512-8/FZe4Ll1Q5GmQvSvL6htLobdBNOwKLcD8LJJ1SRl+M4yR+kIpSCUzTJajasJUFU+sFIeVvalVy9Vfu6E0cnxg==",
       "dev": true,
       "requires": {
         "abbrev": "1.0.x",
@@ -6447,27 +5849,36 @@
         "supports-color": "^3.1.0",
         "which": "^1.1.1",
         "wordwrap": "^1.0.0"
+      },
+      "dependencies": {
+        "supports-color": {
+          "version": "3.2.3",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+          "dev": true,
+          "requires": {
+            "has-flag": "^1.0.0"
+          }
+        }
       }
     },
     "macaca-reporter": {
-      "version": "1.1.7",
-      "resolved": "https://registry.npmjs.org/macaca-reporter/-/macaca-reporter-1.1.7.tgz",
-      "integrity": "sha512-hsEOlkGhsQqR4MRlg+FTxmuG3ByvUWMCvFkyeUEY3c3fsdwCk6UgH8JZ/M+omGVrnUYZBBn0uM7uw7LRY9xnCA==",
+      "version": "1.3.33",
+      "resolved": "https://registry.npmjs.org/macaca-reporter/-/macaca-reporter-1.3.33.tgz",
+      "integrity": "sha512-TBG32umF4cuxJwfdDFZrvaPkLX+uWiS9ZMxIDiEb48DOZUyS9sHiXA+hslgQ2sdAx4KzQuurVUwfYz7DIe4rAg==",
       "dev": true,
       "requires": {
-        "json-stringify-safe": "^5.0.1",
+        "commander": "^2.19.0",
+        "is-ci": "^2.0.0",
+        "macaca-circular-json": "^0.5.10",
+        "macaca-coverage": "^1.0.3",
         "macaca-utils": "^1.0.0",
         "microtemplate": "^1.0.2",
-        "mocha": "^4.0.1",
+        "mocha": "^5.2.0",
+        "remap-istanbul": "^0.11.0",
         "xlogger": "^1.0.6"
       },
       "dependencies": {
-        "commander": {
-          "version": "2.11.0",
-          "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz",
-          "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==",
-          "dev": true
-        },
         "debug": {
           "version": "3.1.0",
           "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
@@ -6478,9 +5889,9 @@
           }
         },
         "diff": {
-          "version": "3.3.1",
-          "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz",
-          "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==",
+          "version": "3.5.0",
+          "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
+          "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
           "dev": true
         },
         "glob": {
@@ -6498,15 +5909,15 @@
           }
         },
         "growl": {
-          "version": "1.10.3",
-          "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz",
-          "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==",
+          "version": "1.10.5",
+          "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
+          "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
           "dev": true
         },
         "has-flag": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
-          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+          "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
           "dev": true
         },
         "he": {
@@ -6524,31 +5935,55 @@
             "xutil": "^1.0.7"
           }
         },
-        "mocha": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz",
-          "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==",
+        "minimist": {
+          "version": "0.0.8",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+          "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
+          "dev": true
+        },
+        "mkdirp": {
+          "version": "0.5.1",
+          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+          "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
           "dev": true,
           "requires": {
-            "browser-stdout": "1.3.0",
-            "commander": "2.11.0",
+            "minimist": "0.0.8"
+          }
+        },
+        "mocha": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz",
+          "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==",
+          "dev": true,
+          "requires": {
+            "browser-stdout": "1.3.1",
+            "commander": "2.15.1",
             "debug": "3.1.0",
-            "diff": "3.3.1",
+            "diff": "3.5.0",
             "escape-string-regexp": "1.0.5",
             "glob": "7.1.2",
-            "growl": "1.10.3",
+            "growl": "1.10.5",
             "he": "1.1.1",
+            "minimatch": "3.0.4",
             "mkdirp": "0.5.1",
-            "supports-color": "4.4.0"
+            "supports-color": "5.4.0"
+          },
+          "dependencies": {
+            "commander": {
+              "version": "2.15.1",
+              "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
+              "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
+              "dev": true
+            }
           }
         },
         "supports-color": {
-          "version": "4.4.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
-          "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+          "version": "5.4.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+          "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
           "dev": true,
           "requires": {
-            "has-flag": "^2.0.0"
+            "has-flag": "^3.0.0"
           }
         }
       }
@@ -6563,23 +5998,23 @@
       }
     },
     "macaca-wd": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/macaca-wd/-/macaca-wd-1.1.4.tgz",
-      "integrity": "sha512-RUIBX+NPqPG2GlkWoNJWLt0v3pwqnWU2fneFdtCW9HyfpLHekD3X7vs4okCR0syzDPTnqWxzB1ge0oj2xq4amA==",
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/macaca-wd/-/macaca-wd-1.1.6.tgz",
+      "integrity": "sha512-0uzL7BLxPCQXgDKyirkbgitss3urAQt15crbovw0D6lsJ0Iz8WZtYQpx/wTQ2hYTWv1DSCGxykYm55V8pK8wWA==",
       "dev": true,
       "requires": {
         "archiver": "~0.14.0",
         "async": "~1.0.0",
         "bluebird": "^3.5.1",
         "chai": "^4.1.2",
-        "datahub-nodejs-sdk": "^1.0.6",
+        "datahub-nodejs-sdk": "^1.1.0",
         "lodash": "~3.9.3",
         "macaca-coverage": "^1.0.2",
         "macaca-reporter": "^1.1.3",
         "mkdirp": "^0.5.1",
         "q": "~1.4.1",
         "remap-istanbul": "^0.11.0",
-        "request": "~2.55.0",
+        "request": "~2.85.0",
         "underscore.string": "~3.0.3",
         "vargs": "~0.1.0",
         "webdriver-keycode": "^1.0.0",
@@ -6587,17 +6022,17 @@
         "xutil": "^1.0.11"
       },
       "dependencies": {
-        "asn1": {
-          "version": "0.1.11",
-          "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz",
-          "integrity": "sha1-VZvhg3bQik7E2+gId9J4GGObLfc=",
-          "dev": true
-        },
-        "assert-plus": {
-          "version": "0.1.5",
-          "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz",
-          "integrity": "sha1-7nQAlBMALYTOxyGcasgRgS5yMWA=",
-          "dev": true
+        "ajv": {
+          "version": "5.5.2",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
+          "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
+          "dev": true,
+          "requires": {
+            "co": "^4.6.0",
+            "fast-deep-equal": "^1.0.0",
+            "fast-json-stable-stringify": "^2.0.0",
+            "json-schema-traverse": "^0.3.0"
+          }
         },
         "async": {
           "version": "1.0.0",
@@ -6605,39 +6040,18 @@
           "integrity": "sha1-+PwEyjoTeErenhZBr5hXjPvWR6k=",
           "dev": true
         },
-        "aws-sign2": {
-          "version": "0.5.0",
-          "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz",
-          "integrity": "sha1-xXED96F/wDfwLXwuZLYC6iI/fWM=",
-          "dev": true
-        },
-        "caseless": {
-          "version": "0.9.0",
-          "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.9.0.tgz",
-          "integrity": "sha1-t7Zc5r8UE4hlOc/VM/CzDv+pz4g=",
-          "dev": true
-        },
         "chai": {
-          "version": "4.1.2",
-          "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz",
-          "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=",
+          "version": "4.3.4",
+          "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz",
+          "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==",
           "dev": true,
           "requires": {
-            "assertion-error": "^1.0.1",
-            "check-error": "^1.0.1",
-            "deep-eql": "^3.0.0",
+            "assertion-error": "^1.1.0",
+            "check-error": "^1.0.2",
+            "deep-eql": "^3.0.1",
             "get-func-name": "^2.0.0",
-            "pathval": "^1.0.0",
-            "type-detect": "^4.0.0"
-          }
-        },
-        "combined-stream": {
-          "version": "0.0.7",
-          "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz",
-          "integrity": "sha1-ATfmV7qlp1QcV6w3rF/AfXO03B8=",
-          "dev": true,
-          "requires": {
-            "delayed-stream": "0.0.5"
+            "pathval": "^1.1.1",
+            "type-detect": "^4.0.5"
           }
         },
         "deep-eql": {
@@ -6649,61 +6063,27 @@
             "type-detect": "^4.0.0"
           }
         },
-        "delayed-stream": {
-          "version": "0.0.5",
-          "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz",
-          "integrity": "sha1-1LH0OpPoKW3+AmlPRoC8N6MTxz8=",
+        "fast-deep-equal": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
+          "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=",
           "dev": true
         },
-        "form-data": {
-          "version": "0.2.0",
-          "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.2.0.tgz",
-          "integrity": "sha1-Jvi8JtpkQOKZy9z7aQNcT3em5GY=",
-          "dev": true,
-          "requires": {
-            "async": "~0.9.0",
-            "combined-stream": "~0.0.4",
-            "mime-types": "~2.0.3"
-          },
-          "dependencies": {
-            "async": {
-              "version": "0.9.2",
-              "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
-              "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=",
-              "dev": true
-            }
-          }
-        },
         "har-validator": {
-          "version": "1.8.0",
-          "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-1.8.0.tgz",
-          "integrity": "sha1-2DhCsOtMQ1lgrrEIoGejqpTA7rI=",
+          "version": "5.0.3",
+          "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
+          "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
           "dev": true,
           "requires": {
-            "bluebird": "^2.9.30",
-            "chalk": "^1.0.0",
-            "commander": "^2.8.1",
-            "is-my-json-valid": "^2.12.0"
-          },
-          "dependencies": {
-            "bluebird": {
-              "version": "2.11.0",
-              "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz",
-              "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=",
-              "dev": true
-            }
+            "ajv": "^5.1.0",
+            "har-schema": "^2.0.0"
           }
         },
-        "http-signature": {
-          "version": "0.10.1",
-          "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz",
-          "integrity": "sha1-T72sEyVZqoMjEh5UB3nAoBKyfmY=",
-          "dev": true,
-          "requires": {
-            "asn1": "0.1.11",
-            "assert-plus": "^0.1.5",
-            "ctype": "0.5.3"
-          }
+        "json-schema-traverse": {
+          "version": "0.3.1",
+          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
+          "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
+          "dev": true
         },
         "lodash": {
           "version": "3.9.3",
@@ -6711,31 +6091,16 @@
           "integrity": "sha1-AVnoaDL+/8bWHYUrEqlTuZSWvTI=",
           "dev": true
         },
-        "mime-db": {
-          "version": "1.12.0",
-          "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz",
-          "integrity": "sha1-PQxjGA9FjrENMlqqN9fFiuMS6dc=",
-          "dev": true
-        },
-        "mime-types": {
-          "version": "2.0.14",
-          "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz",
-          "integrity": "sha1-MQ4VnbI+B3+Lsit0jav6SVcUCqY=",
-          "dev": true,
-          "requires": {
-            "mime-db": "~1.12.0"
-          }
-        },
-        "node-uuid": {
-          "version": "1.4.8",
-          "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz",
-          "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=",
-          "dev": true
-        },
         "oauth-sign": {
-          "version": "0.6.0",
-          "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.6.0.tgz",
-          "integrity": "sha1-fb6uRPbKRU4fFoRR1jB0ZzWBPOM=",
+          "version": "0.8.2",
+          "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
+          "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
+          "dev": true
+        },
+        "punycode": {
+          "version": "1.4.1",
+          "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+          "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
           "dev": true
         },
         "q": {
@@ -6744,43 +6109,44 @@
           "integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=",
           "dev": true
         },
-        "qs": {
-          "version": "2.4.2",
-          "resolved": "https://registry.npmjs.org/qs/-/qs-2.4.2.tgz",
-          "integrity": "sha1-9854jld33wtQENp/fE5zujJHD1o=",
-          "dev": true
-        },
         "request": {
-          "version": "2.55.0",
-          "resolved": "https://registry.npmjs.org/request/-/request-2.55.0.tgz",
-          "integrity": "sha1-11wc32eddrsQD5v/4f5VG1wk6T0=",
+          "version": "2.85.0",
+          "resolved": "https://registry.npmjs.org/request/-/request-2.85.0.tgz",
+          "integrity": "sha512-8H7Ehijd4js+s6wuVPLjwORxD4zeuyjYugprdOXlPSqaApmL/QOy+EB/beICHVCHkGMKNh5rvihb5ov+IDw4mg==",
           "dev": true,
           "requires": {
-            "aws-sign2": "~0.5.0",
-            "bl": "~0.9.0",
-            "caseless": "~0.9.0",
-            "combined-stream": "~0.0.5",
-            "forever-agent": "~0.6.0",
-            "form-data": "~0.2.0",
-            "har-validator": "^1.4.0",
-            "hawk": "~2.3.0",
-            "http-signature": "~0.10.0",
-            "isstream": "~0.1.1",
-            "json-stringify-safe": "~5.0.0",
-            "mime-types": "~2.0.1",
-            "node-uuid": "~1.4.0",
-            "oauth-sign": "~0.6.0",
-            "qs": "~2.4.0",
-            "stringstream": "~0.0.4",
-            "tough-cookie": ">=0.12.0",
-            "tunnel-agent": "~0.4.0"
+            "aws-sign2": "~0.7.0",
+            "aws4": "^1.6.0",
+            "caseless": "~0.12.0",
+            "combined-stream": "~1.0.5",
+            "extend": "~3.0.1",
+            "forever-agent": "~0.6.1",
+            "form-data": "~2.3.1",
+            "har-validator": "~5.0.3",
+            "hawk": "~6.0.2",
+            "http-signature": "~1.2.0",
+            "is-typedarray": "~1.0.0",
+            "isstream": "~0.1.2",
+            "json-stringify-safe": "~5.0.1",
+            "mime-types": "~2.1.17",
+            "oauth-sign": "~0.8.2",
+            "performance-now": "^2.1.0",
+            "qs": "~6.5.1",
+            "safe-buffer": "^5.1.1",
+            "stringstream": "~0.0.5",
+            "tough-cookie": "~2.3.3",
+            "tunnel-agent": "^0.6.0",
+            "uuid": "^3.1.0"
           }
         },
-        "tunnel-agent": {
-          "version": "0.4.3",
-          "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz",
-          "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=",
-          "dev": true
+        "tough-cookie": {
+          "version": "2.3.4",
+          "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz",
+          "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==",
+          "dev": true,
+          "requires": {
+            "punycode": "^1.4.1"
+          }
         },
         "type-detect": {
           "version": "4.0.8",
@@ -6791,9 +6157,9 @@
       }
     },
     "macos-release": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz",
-      "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==",
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.4.1.tgz",
+      "integrity": "sha512-H/QHeBIN1fIGJX517pvK8IEK53yQOW7YcEI55oYtgjDdoCQQz7eJS94qt5kNrscReEyuD/JcdFCm2XBEcGOITg==",
       "dev": true
     },
     "magic-string": {
@@ -6821,33 +6187,36 @@
       }
     },
     "math-expression-evaluator": {
-      "version": "1.2.17",
-      "resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz",
-      "integrity": "sha1-3oGf282E3M2PrlnGrreWFbnSZqw=",
+      "version": "1.3.7",
+      "resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.3.7.tgz",
+      "integrity": "sha512-nrbaifCl42w37hYd6oRLvoymFK42tWB+WQTMFtksDGQMi5GvlJwnz/CsS30FFAISFLtX+A0csJ0xLiuuyyec7w==",
       "dev": true
     },
     "math-random": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz",
-      "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=",
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz",
+      "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==",
       "dev": true
     },
     "md5": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz",
-      "integrity": "sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=",
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz",
+      "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==",
       "dev": true,
       "requires": {
-        "charenc": "~0.0.1",
-        "crypt": "~0.0.1",
-        "is-buffer": "~1.1.1"
+        "charenc": "0.0.2",
+        "crypt": "0.0.2",
+        "is-buffer": "~1.1.6"
       }
     },
     "memfs-or-file-map-to-github-branch": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/memfs-or-file-map-to-github-branch/-/memfs-or-file-map-to-github-branch-1.1.2.tgz",
-      "integrity": "sha512-D2JKK2DTuVYQqquBWco3K6UfSVyVwmd58dgNqh+TgxHOZdTmR8I130gjMbVCkemDl/EzqDA62417cJxKL3/FFA==",
-      "dev": true
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/memfs-or-file-map-to-github-branch/-/memfs-or-file-map-to-github-branch-1.2.0.tgz",
+      "integrity": "sha512-PloI9AkRXrLQuBU1s7eYQpl+4hkL0U0h23lddMaJ3ZGUufn8pdNRxd1kCfBqL5gISCFQs78ttXS15e4/f5vcTA==",
+      "dev": true,
+      "requires": {
+        "@octokit/rest": "^16.43.1"
+      }
     },
     "memory-fs": {
       "version": "0.3.0",
@@ -6866,9 +6235,9 @@
           "dev": true
         },
         "readable-stream": {
-          "version": "2.3.6",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
-          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "version": "2.3.7",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+          "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
           "dev": true,
           "requires": {
             "core-util-is": "~1.0.0",
@@ -6880,6 +6249,12 @@
             "util-deprecate": "~1.0.1"
           }
         },
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+          "dev": true
+        },
         "string_decoder": {
           "version": "1.1.1",
           "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@@ -6892,24 +6267,24 @@
       }
     },
     "micromatch": {
-      "version": "2.3.11",
-      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
-      "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
+      "version": "3.1.10",
+      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+      "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
       "dev": true,
       "requires": {
-        "arr-diff": "^2.0.0",
-        "array-unique": "^0.2.1",
-        "braces": "^1.8.2",
-        "expand-brackets": "^0.1.4",
-        "extglob": "^0.3.1",
-        "filename-regex": "^2.0.0",
-        "is-extglob": "^1.0.0",
-        "is-glob": "^2.0.1",
-        "kind-of": "^3.0.2",
-        "normalize-path": "^2.0.1",
-        "object.omit": "^2.0.0",
-        "parse-glob": "^3.0.4",
-        "regex-cache": "^0.4.2"
+        "arr-diff": "^4.0.0",
+        "array-unique": "^0.3.2",
+        "braces": "^2.3.1",
+        "define-property": "^2.0.2",
+        "extend-shallow": "^3.0.2",
+        "extglob": "^2.0.4",
+        "fragment-cache": "^0.2.1",
+        "kind-of": "^6.0.2",
+        "nanomatch": "^1.2.9",
+        "object.pick": "^1.3.0",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.2"
       }
     },
     "microtemplate": {
@@ -6925,16 +6300,16 @@
       "dev": true
     },
     "mime-db": {
-      "version": "1.35.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.35.0.tgz",
-      "integrity": "sha512-JWT/IcCTsB0Io3AhWUMjRqucrHSPsSf2xKLaRldJVULioggvkJvggZ3VXNNSRkCddE6D+BUI4HEIZIA2OjwIvg=="
+      "version": "1.47.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz",
+      "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw=="
     },
     "mime-types": {
-      "version": "2.1.19",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.19.tgz",
-      "integrity": "sha512-P1tKYHVSZ6uFo26mtnve4HQFE3koh1UWVkp8YUC+ESBHe945xWSoXuHHiGarDqcEZ+whpCDnlNw5LON0kLo+sw==",
+      "version": "2.1.30",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz",
+      "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==",
       "requires": {
-        "mime-db": "~1.35.0"
+        "mime-db": "1.47.0"
       }
     },
     "mimic-fn": {
@@ -6953,9 +6328,9 @@
       }
     },
     "minimist": {
-      "version": "0.0.8",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
-      "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
+      "version": "1.2.5",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
     },
     "mixin-deep": {
       "version": "1.3.2",
@@ -6984,21 +6359,15 @@
           "requires": {
             "isobject": "^3.0.1"
           }
-        },
-        "isobject": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
-          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
-          "dev": true
         }
       }
     },
     "mkdirp": {
-      "version": "0.5.1",
-      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
-      "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+      "version": "0.5.5",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
+      "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
       "requires": {
-        "minimist": "0.0.8"
+        "minimist": "^1.2.5"
       }
     },
     "mocha": {
@@ -7034,12 +6403,6 @@
             "ms": "0.7.1"
           }
         },
-        "diff": {
-          "version": "1.4.0",
-          "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz",
-          "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=",
-          "dev": true
-        },
         "escape-string-regexp": {
           "version": "1.0.2",
           "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz",
@@ -7072,6 +6435,21 @@
             "sigmund": "~1.0.0"
           }
         },
+        "minimist": {
+          "version": "0.0.8",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+          "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
+          "dev": true
+        },
+        "mkdirp": {
+          "version": "0.5.1",
+          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+          "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+          "dev": true,
+          "requires": {
+            "minimist": "0.0.8"
+          }
+        },
         "ms": {
           "version": "0.7.1",
           "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
@@ -7158,9 +6536,9 @@
           "dev": true
         },
         "readable-stream": {
-          "version": "2.3.6",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
-          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "version": "2.3.7",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+          "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
           "dev": true,
           "requires": {
             "core-util-is": "~1.0.0",
@@ -7173,9 +6551,9 @@
           },
           "dependencies": {
             "process-nextick-args": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
-              "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+              "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
               "dev": true
             },
             "string_decoder": {
@@ -7188,9 +6566,21 @@
               }
             }
           }
+        },
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+          "dev": true
         }
       }
     },
+    "moment": {
+      "version": "2.24.0",
+      "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
+      "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==",
+      "dev": true
+    },
     "ms": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
@@ -7203,9 +6593,9 @@
       "dev": true
     },
     "nan": {
-      "version": "2.10.0",
-      "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz",
-      "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==",
+      "version": "2.14.2",
+      "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
+      "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==",
       "dev": true,
       "optional": true
     },
@@ -7226,26 +6616,6 @@
         "regex-not": "^1.0.0",
         "snapdragon": "^0.8.1",
         "to-regex": "^3.0.1"
-      },
-      "dependencies": {
-        "arr-diff": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
-          "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
-          "dev": true
-        },
-        "array-unique": {
-          "version": "0.3.2",
-          "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
-          "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
-          "dev": true
-        },
-        "kind-of": {
-          "version": "6.0.2",
-          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
-          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
-          "dev": true
-        }
       }
     },
     "native-promise-only": {
@@ -7279,14 +6649,16 @@
       "dev": true
     },
     "node-fetch": {
-      "version": "1.7.3",
-      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
-      "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
-      "dev": true,
-      "requires": {
-        "encoding": "^0.1.11",
-        "is-stream": "^1.0.1"
-      }
+      "version": "2.6.1",
+      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
+      "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
+      "dev": true
+    },
+    "node-int64": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.3.3.tgz",
+      "integrity": "sha1-LW5rLs5d6FiLQ9iNG8QbJs0fqE0=",
+      "dev": true
     },
     "node-libs-browser": {
       "version": "0.7.0",
@@ -7325,10 +6697,16 @@
           "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
           "dev": true
         },
+        "punycode": {
+          "version": "1.4.1",
+          "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+          "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+          "dev": true
+        },
         "readable-stream": {
-          "version": "2.3.6",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
-          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "version": "2.3.7",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+          "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
           "dev": true,
           "requires": {
             "core-util-is": "~1.0.0",
@@ -7350,6 +6728,12 @@
               }
             }
           }
+        },
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+          "dev": true
         }
       }
     },
@@ -7404,16 +6788,10 @@
       "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=",
       "dev": true
     },
-    "number-is-nan": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
-      "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
-      "dev": true
-    },
     "oauth-sign": {
-      "version": "0.8.2",
-      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
-      "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM="
+      "version": "0.9.0",
+      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+      "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
     },
     "object-assign": {
       "version": "4.1.1",
@@ -7440,6 +6818,15 @@
           "requires": {
             "is-descriptor": "^0.1.0"
           }
+        },
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
         }
       }
     },
@@ -7450,14 +6837,6 @@
       "dev": true,
       "requires": {
         "isobject": "^3.0.0"
-      },
-      "dependencies": {
-        "isobject": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
-          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
-          "dev": true
-        }
       }
     },
     "object.omit": {
@@ -7477,14 +6856,6 @@
       "dev": true,
       "requires": {
         "isobject": "^3.0.1"
-      },
-      "dependencies": {
-        "isobject": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
-          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
-          "dev": true
-        }
       }
     },
     "octokit-pagination-methods": {
@@ -7518,9 +6889,9 @@
       "dev": true
     },
     "opn": {
-      "version": "5.3.0",
-      "resolved": "https://registry.npmjs.org/opn/-/opn-5.3.0.tgz",
-      "integrity": "sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==",
+      "version": "5.5.0",
+      "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz",
+      "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==",
       "dev": true,
       "requires": {
         "is-wsl": "^1.1.0"
@@ -7536,6 +6907,12 @@
         "wordwrap": "~0.0.2"
       },
       "dependencies": {
+        "minimist": {
+          "version": "0.0.10",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
+          "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=",
+          "dev": true
+        },
         "wordwrap": {
           "version": "0.0.3",
           "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
@@ -7545,17 +6922,17 @@
       }
     },
     "optionator": {
-      "version": "0.8.2",
-      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
-      "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
+      "version": "0.8.3",
+      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
+      "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
       "dev": true,
       "requires": {
         "deep-is": "~0.1.3",
-        "fast-levenshtein": "~2.0.4",
+        "fast-levenshtein": "~2.0.6",
         "levn": "~0.3.0",
         "prelude-ls": "~1.1.2",
         "type-check": "~0.3.2",
-        "wordwrap": "~1.0.0"
+        "word-wrap": "~1.2.3"
       }
     },
     "os-browserify": {
@@ -7599,9 +6976,9 @@
       "dev": true
     },
     "p-limit": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz",
-      "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==",
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
       "dev": true,
       "requires": {
         "p-try": "^2.0.0"
@@ -7698,6 +7075,12 @@
       "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
       "dev": true
     },
+    "parse5": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/parse5/-/parse5-2.2.3.tgz",
+      "integrity": "sha1-DE/EHBAAxea5PUiwP4CDg3g06fY=",
+      "dev": true
+    },
     "pascalcase": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
@@ -7738,9 +7121,9 @@
       "dev": true
     },
     "path-parse": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz",
-      "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=",
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
+      "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
       "dev": true
     },
     "path-platform": {
@@ -7750,18 +7133,15 @@
       "dev": true
     },
     "path-to-regexp": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz",
-      "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=",
-      "dev": true,
-      "requires": {
-        "isarray": "0.0.1"
-      }
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz",
+      "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==",
+      "dev": true
     },
     "pathval": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz",
-      "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=",
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz",
+      "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==",
       "dev": true
     },
     "pbkdf2-compat": {
@@ -7808,6 +7188,12 @@
             "jsonfile": "^2.1.0",
             "klaw": "^1.0.0"
           }
+        },
+        "progress": {
+          "version": "1.1.8",
+          "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
+          "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=",
+          "dev": true
         }
       }
     },
@@ -7960,6 +7346,17 @@
         "js-base64": "^2.1.9",
         "source-map": "^0.5.6",
         "supports-color": "^3.2.3"
+      },
+      "dependencies": {
+        "supports-color": {
+          "version": "3.2.3",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+          "dev": true,
+          "requires": {
+            "has-flag": "^1.0.0"
+          }
+        }
       }
     },
     "postcss-calc": {
@@ -8166,9 +7563,9 @@
       }
     },
     "postcss-modules-extract-imports": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.1.0.tgz",
-      "integrity": "sha1-thTJcgvmgW6u41+zpfqh26agXds=",
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.1.tgz",
+      "integrity": "sha512-6jt9XZwUhwmRUhb/CkyJY020PYaPJsCyt3UjbaWo6XEbH/94Hmv6MP7fG2C5NDU/BcHzyGYxNtHvM+LTf9HrYw==",
       "dev": true,
       "requires": {
         "postcss": "^6.0.1"
@@ -8184,9 +7581,9 @@
           }
         },
         "chalk": {
-          "version": "2.4.1",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
-          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
           "dev": true,
           "requires": {
             "ansi-styles": "^3.2.1",
@@ -8218,9 +7615,9 @@
           "dev": true
         },
         "supports-color": {
-          "version": "5.4.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
-          "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
           "dev": true,
           "requires": {
             "has-flag": "^3.0.0"
@@ -8248,9 +7645,9 @@
           }
         },
         "chalk": {
-          "version": "2.4.1",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
-          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
           "dev": true,
           "requires": {
             "ansi-styles": "^3.2.1",
@@ -8282,9 +7679,9 @@
           "dev": true
         },
         "supports-color": {
-          "version": "5.4.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
-          "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
           "dev": true,
           "requires": {
             "has-flag": "^3.0.0"
@@ -8312,9 +7709,9 @@
           }
         },
         "chalk": {
-          "version": "2.4.1",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
-          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
           "dev": true,
           "requires": {
             "ansi-styles": "^3.2.1",
@@ -8346,9 +7743,9 @@
           "dev": true
         },
         "supports-color": {
-          "version": "5.4.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
-          "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
           "dev": true,
           "requires": {
             "has-flag": "^3.0.0"
@@ -8376,9 +7773,9 @@
           }
         },
         "chalk": {
-          "version": "2.4.1",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
-          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
           "dev": true,
           "requires": {
             "ansi-styles": "^3.2.1",
@@ -8410,9 +7807,9 @@
           "dev": true
         },
         "supports-color": {
-          "version": "5.4.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
-          "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
           "dev": true,
           "requires": {
             "has-flag": "^3.0.0"
@@ -8516,9 +7913,9 @@
       }
     },
     "postcss-value-parser": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz",
-      "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=",
+      "version": "3.3.1",
+      "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+      "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
       "dev": true
     },
     "postcss-zindex": {
@@ -8577,14 +7974,6 @@
       "requires": {
         "colors": "^1.1.2",
         "minimist": "^1.2.0"
-      },
-      "dependencies": {
-        "minimist": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
-          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
-          "dev": true
-        }
       }
     },
     "printf": {
@@ -8606,15 +7995,15 @@
       "dev": true
     },
     "process-nextick-args": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
-      "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+      "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
       "dev": true
     },
     "progress": {
-      "version": "1.1.8",
-      "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
-      "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=",
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+      "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
       "dev": true
     },
     "promise": {
@@ -8643,6 +8032,11 @@
       "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
       "dev": true
     },
+    "psl": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
+      "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ=="
+    },
     "pump": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
@@ -8654,9 +8048,9 @@
       }
     },
     "punycode": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
-      "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
     },
     "q": {
       "version": "1.5.1",
@@ -8692,9 +8086,9 @@
       "dev": true
     },
     "randomatic": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.0.0.tgz",
-      "integrity": "sha512-VdxFOIEY3mNO5PtSRkkle/hPJDHvQhK21oa73K4yAc9qmp6N429gAyF1gZMOTMeS0/AYzaV/2Trcef+NaIonSA==",
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz",
+      "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==",
       "dev": true,
       "requires": {
         "is-number": "^4.0.0",
@@ -8707,12 +8101,6 @@
           "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
           "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
           "dev": true
-        },
-        "kind-of": {
-          "version": "6.0.2",
-          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
-          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
-          "dev": true
         }
       }
     },
@@ -8738,14 +8126,6 @@
         "ini": "~1.3.0",
         "minimist": "^1.2.0",
         "strip-json-comments": "~2.0.1"
-      },
-      "dependencies": {
-        "minimist": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
-          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
-          "dev": true
-        }
       }
     },
     "read-only-stream": {
@@ -8764,9 +8144,9 @@
           "dev": true
         },
         "readable-stream": {
-          "version": "2.3.6",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
-          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "version": "2.3.7",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+          "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
           "dev": true,
           "requires": {
             "core-util-is": "~1.0.0",
@@ -8778,6 +8158,12 @@
             "util-deprecate": "~1.0.1"
           }
         },
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+          "dev": true
+        },
         "string_decoder": {
           "version": "1.1.1",
           "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@@ -8801,15 +8187,14 @@
       }
     },
     "readdirp": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz",
-      "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=",
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
+      "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
       "dev": true,
       "requires": {
-        "graceful-fs": "^4.1.2",
-        "minimatch": "^3.0.2",
-        "readable-stream": "^2.0.2",
-        "set-immediate-shim": "^1.0.1"
+        "graceful-fs": "^4.1.11",
+        "micromatch": "^3.1.10",
+        "readable-stream": "^2.0.2"
       },
       "dependencies": {
         "isarray": {
@@ -8819,9 +8204,9 @@
           "dev": true
         },
         "readable-stream": {
-          "version": "2.3.6",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
-          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "version": "2.3.7",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+          "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
           "dev": true,
           "requires": {
             "core-util-is": "~1.0.0",
@@ -8833,6 +8218,12 @@
             "util-deprecate": "~1.0.1"
           }
         },
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+          "dev": true
+        },
         "string_decoder": {
           "version": "1.1.1",
           "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@@ -8879,26 +8270,18 @@
       }
     },
     "reduce-function-call": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.2.tgz",
-      "integrity": "sha1-WiAL+S4ON3UXUv5FsKszD9S2vpk=",
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.3.tgz",
+      "integrity": "sha512-Hl/tuV2VDgWgCSEeWMLwxLZqX7OK59eU1guxXsRKTAyeYimivsKdtcV4fu3r710tpG5GmDKDhQ0HSZLExnNmyQ==",
       "dev": true,
       "requires": {
-        "balanced-match": "^0.4.2"
-      },
-      "dependencies": {
-        "balanced-match": {
-          "version": "0.4.2",
-          "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
-          "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=",
-          "dev": true
-        }
+        "balanced-match": "^1.0.0"
       }
     },
     "regenerate": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz",
-      "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==",
+      "version": "1.4.2",
+      "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
+      "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==",
       "dev": true
     },
     "regenerator-runtime": {
@@ -9084,6 +8467,15 @@
           "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
           "dev": true
         },
+        "supports-color": {
+          "version": "3.2.3",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+          "dev": true,
+          "requires": {
+            "has-flag": "^1.0.0"
+          }
+        },
         "through2": {
           "version": "2.0.1",
           "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.1.tgz",
@@ -9103,9 +8495,9 @@
       "dev": true
     },
     "repeat-element": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz",
-      "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=",
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz",
+      "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==",
       "dev": true
     },
     "repeat-string": {
@@ -9124,30 +8516,30 @@
       }
     },
     "request": {
-      "version": "2.87.0",
-      "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz",
-      "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==",
+      "version": "2.88.2",
+      "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
+      "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
       "requires": {
         "aws-sign2": "~0.7.0",
-        "aws4": "^1.6.0",
+        "aws4": "^1.8.0",
         "caseless": "~0.12.0",
-        "combined-stream": "~1.0.5",
-        "extend": "~3.0.1",
+        "combined-stream": "~1.0.6",
+        "extend": "~3.0.2",
         "forever-agent": "~0.6.1",
-        "form-data": "~2.3.1",
-        "har-validator": "~5.0.3",
+        "form-data": "~2.3.2",
+        "har-validator": "~5.1.3",
         "http-signature": "~1.2.0",
         "is-typedarray": "~1.0.0",
         "isstream": "~0.1.2",
         "json-stringify-safe": "~5.0.1",
-        "mime-types": "~2.1.17",
-        "oauth-sign": "~0.8.2",
+        "mime-types": "~2.1.19",
+        "oauth-sign": "~0.9.0",
         "performance-now": "^2.1.0",
-        "qs": "~6.5.1",
-        "safe-buffer": "^5.1.1",
-        "tough-cookie": "~2.3.3",
+        "qs": "~6.5.2",
+        "safe-buffer": "^5.1.2",
+        "tough-cookie": "~2.5.0",
         "tunnel-agent": "^0.6.0",
-        "uuid": "^3.1.0"
+        "uuid": "^3.3.2"
       }
     },
     "request-progress": {
@@ -9160,9 +8552,9 @@
       }
     },
     "require-from-string": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz",
-      "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=",
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+      "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
       "dev": true
     },
     "require-uncached": {
@@ -9231,9 +8623,9 @@
       "dev": true
     },
     "rfc6902": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/rfc6902/-/rfc6902-3.0.4.tgz",
-      "integrity": "sha512-OnzreaZXrwT5w2ikKXWr5QcuI7NZpL+J3hIkAwozjOnKVUL7fPsB8Vcmu8YBiiou1/r3V0Jc0T1uQDyfAPvLzA==",
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/rfc6902/-/rfc6902-3.1.1.tgz",
+      "integrity": "sha512-aHiEm2S4mQSyyIaK7NVotfmVkgOOn1K9iuuSCIKJ8eIAte/8o06Vp06Z2NcLrmMahDmA+2F6oHx33P4NOQ1JnQ==",
       "dev": true
     },
     "right-align": {
@@ -9246,18 +8638,18 @@
       }
     },
     "rimraf": {
-      "version": "2.6.2",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
-      "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
+      "version": "2.7.1",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+      "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
       "dev": true,
       "requires": {
-        "glob": "^7.0.5"
+        "glob": "^7.1.3"
       },
       "dependencies": {
         "glob": {
-          "version": "7.1.2",
-          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
-          "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+          "version": "7.1.7",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
+          "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
           "dev": true,
           "requires": {
             "fs.realpath": "^1.0.0",
@@ -9305,10 +8697,10 @@
         "rollup-pluginutils": "^2.0.1"
       },
       "dependencies": {
-        "acorn": {
-          "version": "5.7.1",
-          "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz",
-          "integrity": "sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ==",
+        "estree-walker": {
+          "version": "0.5.2",
+          "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.5.2.tgz",
+          "integrity": "sha512-XpCnW/AE10ws/kDAs37cngSkvgIR8aN3G0MS85m7dUpuK2EREo9VJ00uvw6Dg/hXEpfsE1I1TvJOJr+Z+TL+ig==",
           "dev": true
         },
         "magic-string": {
@@ -9321,12 +8713,13 @@
           }
         },
         "resolve": {
-          "version": "1.8.1",
-          "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz",
-          "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==",
+          "version": "1.20.0",
+          "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
+          "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
           "dev": true,
           "requires": {
-            "path-parse": "^1.0.5"
+            "is-core-module": "^2.2.0",
+            "path-parse": "^1.0.6"
           }
         }
       }
@@ -9339,312 +8732,6 @@
       "requires": {
         "eslint": "^4.1.1",
         "rollup-pluginutils": "^2.0.1"
-      },
-      "dependencies": {
-        "ajv-keywords": {
-          "version": "2.1.1",
-          "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz",
-          "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=",
-          "dev": true
-        },
-        "ansi-escapes": {
-          "version": "3.1.0",
-          "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz",
-          "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==",
-          "dev": true
-        },
-        "ansi-regex": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
-          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
-          "dev": true
-        },
-        "ansi-styles": {
-          "version": "3.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
-          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
-          "dev": true,
-          "requires": {
-            "color-convert": "^1.9.0"
-          }
-        },
-        "chalk": {
-          "version": "2.4.1",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
-          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^3.2.1",
-            "escape-string-regexp": "^1.0.5",
-            "supports-color": "^5.3.0"
-          }
-        },
-        "cli-cursor": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
-          "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
-          "dev": true,
-          "requires": {
-            "restore-cursor": "^2.0.0"
-          }
-        },
-        "cross-spawn": {
-          "version": "5.1.0",
-          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
-          "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
-          "dev": true,
-          "requires": {
-            "lru-cache": "^4.0.1",
-            "shebang-command": "^1.2.0",
-            "which": "^1.2.9"
-          }
-        },
-        "debug": {
-          "version": "3.1.0",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
-          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
-          "dev": true,
-          "requires": {
-            "ms": "2.0.0"
-          }
-        },
-        "doctrine": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
-          "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
-          "dev": true,
-          "requires": {
-            "esutils": "^2.0.2"
-          }
-        },
-        "eslint": {
-          "version": "4.19.1",
-          "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz",
-          "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==",
-          "dev": true,
-          "requires": {
-            "ajv": "^5.3.0",
-            "babel-code-frame": "^6.22.0",
-            "chalk": "^2.1.0",
-            "concat-stream": "^1.6.0",
-            "cross-spawn": "^5.1.0",
-            "debug": "^3.1.0",
-            "doctrine": "^2.1.0",
-            "eslint-scope": "^3.7.1",
-            "eslint-visitor-keys": "^1.0.0",
-            "espree": "^3.5.4",
-            "esquery": "^1.0.0",
-            "esutils": "^2.0.2",
-            "file-entry-cache": "^2.0.0",
-            "functional-red-black-tree": "^1.0.1",
-            "glob": "^7.1.2",
-            "globals": "^11.0.1",
-            "ignore": "^3.3.3",
-            "imurmurhash": "^0.1.4",
-            "inquirer": "^3.0.6",
-            "is-resolvable": "^1.0.0",
-            "js-yaml": "^3.9.1",
-            "json-stable-stringify-without-jsonify": "^1.0.1",
-            "levn": "^0.3.0",
-            "lodash": "^4.17.4",
-            "minimatch": "^3.0.2",
-            "mkdirp": "^0.5.1",
-            "natural-compare": "^1.4.0",
-            "optionator": "^0.8.2",
-            "path-is-inside": "^1.0.2",
-            "pluralize": "^7.0.0",
-            "progress": "^2.0.0",
-            "regexpp": "^1.0.1",
-            "require-uncached": "^1.0.3",
-            "semver": "^5.3.0",
-            "strip-ansi": "^4.0.0",
-            "strip-json-comments": "~2.0.1",
-            "table": "4.0.2",
-            "text-table": "~0.2.0"
-          }
-        },
-        "figures": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
-          "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
-          "dev": true,
-          "requires": {
-            "escape-string-regexp": "^1.0.5"
-          }
-        },
-        "file-entry-cache": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
-          "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=",
-          "dev": true,
-          "requires": {
-            "flat-cache": "^1.2.1",
-            "object-assign": "^4.0.1"
-          }
-        },
-        "glob": {
-          "version": "7.1.2",
-          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
-          "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
-          "dev": true,
-          "requires": {
-            "fs.realpath": "^1.0.0",
-            "inflight": "^1.0.4",
-            "inherits": "2",
-            "minimatch": "^3.0.4",
-            "once": "^1.3.0",
-            "path-is-absolute": "^1.0.0"
-          }
-        },
-        "globals": {
-          "version": "11.7.0",
-          "resolved": "https://registry.npmjs.org/globals/-/globals-11.7.0.tgz",
-          "integrity": "sha512-K8BNSPySfeShBQXsahYB/AbbWruVOTyVpgoIDnl8odPpeSfP2J5QO2oLFFdl2j7GfDCtZj2bMKar2T49itTPCg==",
-          "dev": true
-        },
-        "has-flag": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-          "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
-          "dev": true
-        },
-        "inquirer": {
-          "version": "3.3.0",
-          "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz",
-          "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==",
-          "dev": true,
-          "requires": {
-            "ansi-escapes": "^3.0.0",
-            "chalk": "^2.0.0",
-            "cli-cursor": "^2.1.0",
-            "cli-width": "^2.0.0",
-            "external-editor": "^2.0.4",
-            "figures": "^2.0.0",
-            "lodash": "^4.3.0",
-            "mute-stream": "0.0.7",
-            "run-async": "^2.2.0",
-            "rx-lite": "^4.0.8",
-            "rx-lite-aggregates": "^4.0.8",
-            "string-width": "^2.1.0",
-            "strip-ansi": "^4.0.0",
-            "through": "^2.3.6"
-          }
-        },
-        "is-fullwidth-code-point": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
-          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
-          "dev": true
-        },
-        "mute-stream": {
-          "version": "0.0.7",
-          "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
-          "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
-          "dev": true
-        },
-        "onetime": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
-          "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
-          "dev": true,
-          "requires": {
-            "mimic-fn": "^1.0.0"
-          }
-        },
-        "pluralize": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz",
-          "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==",
-          "dev": true
-        },
-        "progress": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz",
-          "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=",
-          "dev": true
-        },
-        "restore-cursor": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
-          "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
-          "dev": true,
-          "requires": {
-            "onetime": "^2.0.0",
-            "signal-exit": "^3.0.2"
-          }
-        },
-        "run-async": {
-          "version": "2.3.0",
-          "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
-          "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
-          "dev": true,
-          "requires": {
-            "is-promise": "^2.1.0"
-          }
-        },
-        "rx-lite": {
-          "version": "4.0.8",
-          "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
-          "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=",
-          "dev": true
-        },
-        "slice-ansi": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz",
-          "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==",
-          "dev": true,
-          "requires": {
-            "is-fullwidth-code-point": "^2.0.0"
-          }
-        },
-        "string-width": {
-          "version": "2.1.1",
-          "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
-          "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
-          "dev": true,
-          "requires": {
-            "is-fullwidth-code-point": "^2.0.0",
-            "strip-ansi": "^4.0.0"
-          }
-        },
-        "strip-ansi": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
-          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
-          "dev": true,
-          "requires": {
-            "ansi-regex": "^3.0.0"
-          }
-        },
-        "strip-json-comments": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
-          "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "5.4.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
-          "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
-          "dev": true,
-          "requires": {
-            "has-flag": "^3.0.0"
-          }
-        },
-        "table": {
-          "version": "4.0.2",
-          "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz",
-          "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==",
-          "dev": true,
-          "requires": {
-            "ajv": "^5.2.3",
-            "ajv-keywords": "^2.1.0",
-            "chalk": "^2.1.0",
-            "lodash": "^4.17.4",
-            "slice-ansi": "1.0.0",
-            "string-width": "^2.1.1"
-          }
-        }
       }
     },
     "rollup-plugin-json": {
@@ -9657,42 +8744,33 @@
       }
     },
     "rollup-plugin-node-resolve": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-3.3.0.tgz",
-      "integrity": "sha512-9zHGr3oUJq6G+X0oRMYlzid9fXicBdiydhwGChdyeNRGPcN/majtegApRKHLR5drboUvEWU+QeUmGTyEZQs3WA==",
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-3.4.0.tgz",
+      "integrity": "sha512-PJcd85dxfSBWih84ozRtBkB731OjXk0KnzN0oGp7WOWcarAFkVa71cV5hTJg2qpVsV2U8EUwrzHP3tvy9vS3qg==",
       "dev": true,
       "requires": {
         "builtin-modules": "^2.0.0",
         "is-module": "^1.0.0",
         "resolve": "^1.1.6"
-      },
-      "dependencies": {
-        "builtin-modules": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-2.0.0.tgz",
-          "integrity": "sha512-3U5kUA5VPsRUA3nofm/BXX7GVHKfxz0hOBAPxXrIvHzlDRkQVqEn6yi8QJegxl4LzOHLdvb7XF5dVawa/VVYBg==",
-          "dev": true
-        }
       }
     },
     "rollup-plugin-replace": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/rollup-plugin-replace/-/rollup-plugin-replace-2.0.0.tgz",
-      "integrity": "sha512-pK9mTd/FNrhtBxcTBXoh0YOwRIShV0gGhv9qvUtNcXHxIMRZMXqfiZKVBmCRGp8/2DJRy62z2JUE7/5tP6WxOQ==",
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/rollup-plugin-replace/-/rollup-plugin-replace-2.2.0.tgz",
+      "integrity": "sha512-/5bxtUPkDHyBJAKketb4NfaeZjL5yLZdeUihSfbF2PQMz+rSTEb8ARKoOl3UBT4m7/X+QOXJo3sLTcq+yMMYTA==",
       "dev": true,
       "requires": {
-        "magic-string": "^0.22.4",
-        "minimatch": "^3.0.2",
-        "rollup-pluginutils": "^2.0.1"
+        "magic-string": "^0.25.2",
+        "rollup-pluginutils": "^2.6.0"
       },
       "dependencies": {
         "magic-string": {
-          "version": "0.22.5",
-          "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz",
-          "integrity": "sha512-oreip9rJZkzvA8Qzk9HFs8fZGF/u7H/gtrE8EN6RjKJ9kh2HlC+yQ2QezifqTZfGyiuAV0dRv5a+y/8gBb1m9w==",
+          "version": "0.25.7",
+          "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
+          "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==",
           "dev": true,
           "requires": {
-            "vlq": "^0.2.2"
+            "sourcemap-codec": "^1.4.4"
           }
         }
       }
@@ -9706,42 +8784,28 @@
         "uglify-js": "^3.0.9"
       },
       "dependencies": {
-        "source-map": {
-          "version": "0.6.1",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-          "dev": true
-        },
         "uglify-js": {
-          "version": "3.4.5",
-          "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.5.tgz",
-          "integrity": "sha512-Fm52gLqJqFBnT+Sn411NPDnsgaWiYeRLw42x7Va/mS8TKgaepwoGY7JLXHSEef3d3PmdFXSz1Zx7KMLL89E2QA==",
-          "dev": true,
-          "requires": {
-            "commander": "~2.16.0",
-            "source-map": "~0.6.1"
-          }
+          "version": "3.13.6",
+          "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.6.tgz",
+          "integrity": "sha512-rRprLwl8RVaS+Qvx3Wh5hPfPBn9++G6xkGlUupya0s5aDmNjI7z3lnRLB3u7sN4OmbB0pWgzhM9BEJyiWAwtAA==",
+          "dev": true
         }
       }
     },
     "rollup-pluginutils": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.3.0.tgz",
-      "integrity": "sha512-xB6hsRsjdJdIYWEyYUJy/3ki5g69wrf0luHPGNK3ZSocV6HLNfio59l3dZ3TL4xUwEKgROhFi9jOCt6c5gfUWw==",
+      "version": "2.8.2",
+      "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz",
+      "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==",
       "dev": true,
       "requires": {
-        "estree-walker": "^0.5.2",
-        "micromatch": "^2.3.11"
+        "estree-walker": "^0.6.1"
       }
     },
     "run-async": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
-      "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
-      "dev": true,
-      "requires": {
-        "is-promise": "^2.1.0"
-      }
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
+      "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==",
+      "dev": true
     },
     "runtime-shared": {
       "version": "0.4.20",
@@ -9749,9 +8813,9 @@
       "integrity": "sha1-sWpp5G3xcHxTuiyv2GbPo49H4Hg="
     },
     "rx-lite": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz",
-      "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=",
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
+      "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=",
       "dev": true
     },
     "rx-lite-aggregates": {
@@ -9764,9 +8828,9 @@
       }
     },
     "safe-buffer": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
-      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
     },
     "safe-regex": {
       "version": "1.1.0",
@@ -9801,21 +8865,21 @@
       "dev": true
     },
     "semver": {
-      "version": "5.5.0",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
-      "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA=="
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
     },
     "serve": {
-      "version": "7.1.3",
-      "resolved": "https://registry.npmjs.org/serve/-/serve-7.1.3.tgz",
-      "integrity": "sha512-XNDcJbtFWn6dc6U46/kq6LkXFuk33MqA+FZZdWJ/Y4ttEV1P7oD+mVNcKS9DYuXQEnKgqLH36Qv88mSvLxQPcw==",
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/serve/-/serve-7.2.0.tgz",
+      "integrity": "sha512-ckRZfFrMcIWECMKKPJuvO9vLDrukCk57l9Ydo3clxQ2jeTFF06V6UzAfKmVI3cMNkI0gnzby9ES+shixTQP0fA==",
       "dev": true,
       "requires": {
         "@zeit/schemas": "1.1.2",
         "ajv": "6.5.0",
         "arg": "2.0.0",
         "chalk": "2.4.1",
-        "serve-handler": "2.3.15",
+        "serve-handler": "2.4.0",
         "update-check": "1.5.2"
       },
       "dependencies": {
@@ -9863,6 +8927,12 @@
           "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
           "dev": true
         },
+        "json-schema-traverse": {
+          "version": "0.3.1",
+          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
+          "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
+          "dev": true
+        },
         "supports-color": {
           "version": "5.5.0",
           "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
@@ -9875,40 +8945,38 @@
       }
     },
     "serve-handler": {
-      "version": "2.3.15",
-      "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-2.3.15.tgz",
-      "integrity": "sha512-GBJtA2DPAJzo+6bdYeXdM7Wwt676kh1s64yi9k+jxlNTbezC7MZJa3csInGOG9VRFKr9r3+xZwyCLNcd8my33Q==",
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-2.4.0.tgz",
+      "integrity": "sha512-FmvWnIkK0K0syBXcNzJ6evwHwvazb8EMDZKUXFN9Cs+ENBUGUBwA2tQopDrLJWusw3KCsAufx7hpWJT81bNSiw==",
       "dev": true,
       "requires": {
         "bytes": "3.0.0",
+        "content-disposition": "0.5.2",
         "fast-url-parser": "1.1.3",
         "glob-slasher": "1.0.1",
-        "mime": "2.3.1",
+        "mime-types": "2.1.18",
         "minimatch": "3.0.4",
         "path-is-inside": "1.0.2",
         "path-to-regexp": "2.2.1"
       },
       "dependencies": {
-        "mime": {
-          "version": "2.3.1",
-          "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz",
-          "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==",
+        "mime-db": {
+          "version": "1.33.0",
+          "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
+          "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==",
           "dev": true
         },
-        "path-to-regexp": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz",
-          "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==",
-          "dev": true
+        "mime-types": {
+          "version": "2.1.18",
+          "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
+          "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
+          "dev": true,
+          "requires": {
+            "mime-db": "~1.33.0"
+          }
         }
       }
     },
-    "set-immediate-shim": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
-      "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=",
-      "dev": true
-    },
     "set-value": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
@@ -9938,12 +9006,6 @@
           "requires": {
             "isobject": "^3.0.1"
           }
-        },
-        "isobject": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
-          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
-          "dev": true
         }
       }
     },
@@ -9969,15 +9031,6 @@
         "sha.js": "~2.4.4"
       },
       "dependencies": {
-        "json-stable-stringify": {
-          "version": "0.0.1",
-          "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz",
-          "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=",
-          "dev": true,
-          "requires": {
-            "jsonify": "~0.0.0"
-          }
-        },
         "sha.js": {
           "version": "2.4.11",
           "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
@@ -9990,6 +9043,15 @@
         }
       }
     },
+    "shasum-object": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/shasum-object/-/shasum-object-1.0.0.tgz",
+      "integrity": "sha512-Iqo5rp/3xVi6M4YheapzZhhGPVs0yZwHj7wvwQ1B9z8H6zk+FEnI7y3Teq7qwnekfEhu8WmG2z0z4iWZaxLWVg==",
+      "dev": true,
+      "requires": {
+        "fast-safe-stringify": "^2.0.7"
+      }
+    },
     "shebang-command": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
@@ -10006,16 +9068,10 @@
       "dev": true
     },
     "shell-quote": {
-      "version": "1.6.1",
-      "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz",
-      "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=",
-      "dev": true,
-      "requires": {
-        "array-filter": "~0.0.0",
-        "array-map": "~0.0.0",
-        "array-reduce": "~0.0.0",
-        "jsonify": "~0.0.0"
-      }
+      "version": "1.7.2",
+      "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz",
+      "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==",
+      "dev": true
     },
     "shelljs": {
       "version": "0.7.8",
@@ -10029,9 +9085,9 @@
       },
       "dependencies": {
         "glob": {
-          "version": "7.1.2",
-          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
-          "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+          "version": "7.1.7",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
+          "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
           "dev": true,
           "requires": {
             "fs.realpath": "^1.0.0",
@@ -10051,15 +9107,15 @@
       "dev": true
     },
     "signal-exit": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
-      "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
+      "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
       "dev": true
     },
     "simple-concat": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz",
-      "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=",
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
+      "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
       "dev": true
     },
     "sinon": {
@@ -10078,6 +9134,21 @@
         "type-detect": "^4.0.0"
       },
       "dependencies": {
+        "diff": {
+          "version": "3.5.0",
+          "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
+          "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
+          "dev": true
+        },
+        "path-to-regexp": {
+          "version": "1.8.0",
+          "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
+          "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
+          "dev": true,
+          "requires": {
+            "isarray": "0.0.1"
+          }
+        },
         "type-detect": {
           "version": "4.0.8",
           "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
@@ -10191,18 +9262,6 @@
             "is-data-descriptor": "^1.0.0",
             "kind-of": "^6.0.2"
           }
-        },
-        "isobject": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
-          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
-          "dev": true
-        },
-        "kind-of": {
-          "version": "6.0.2",
-          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
-          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
-          "dev": true
         }
       }
     },
@@ -10213,15 +9272,26 @@
       "dev": true,
       "requires": {
         "kind-of": "^3.2.0"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
       }
     },
     "sntp": {
-      "version": "1.0.9",
-      "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
-      "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz",
+      "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==",
       "dev": true,
       "requires": {
-        "hoek": "2.x.x"
+        "hoek": "4.x.x"
       }
     },
     "sort-keys": {
@@ -10246,12 +9316,12 @@
       "dev": true
     },
     "source-map-resolve": {
-      "version": "0.5.2",
-      "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
-      "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==",
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
+      "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
       "dev": true,
       "requires": {
-        "atob": "^2.1.1",
+        "atob": "^2.1.2",
         "decode-uri-component": "^0.2.0",
         "resolve-url": "^0.2.1",
         "source-map-url": "^0.4.0",
@@ -10268,9 +9338,15 @@
       }
     },
     "source-map-url": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
-      "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz",
+      "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==",
+      "dev": true
+    },
+    "sourcemap-codec": {
+      "version": "1.4.8",
+      "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
+      "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
       "dev": true
     },
     "split-on-first": {
@@ -10295,9 +9371,9 @@
       "dev": true
     },
     "sshpk": {
-      "version": "1.14.2",
-      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz",
-      "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=",
+      "version": "1.16.1",
+      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
+      "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
       "requires": {
         "asn1": "~0.2.3",
         "assert-plus": "^1.0.0",
@@ -10332,9 +9408,9 @@
       }
     },
     "stream-browserify": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz",
-      "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=",
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz",
+      "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==",
       "dev": true,
       "requires": {
         "inherits": "~2.0.1",
@@ -10348,9 +9424,9 @@
           "dev": true
         },
         "readable-stream": {
-          "version": "2.3.6",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
-          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "version": "2.3.7",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+          "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
           "dev": true,
           "requires": {
             "core-util-is": "~1.0.0",
@@ -10362,6 +9438,12 @@
             "util-deprecate": "~1.0.1"
           }
         },
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+          "dev": true
+        },
         "string_decoder": {
           "version": "1.1.1",
           "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@@ -10395,9 +9477,9 @@
           "dev": true
         },
         "readable-stream": {
-          "version": "2.3.6",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
-          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "version": "2.3.7",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+          "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
           "dev": true,
           "requires": {
             "core-util-is": "~1.0.0",
@@ -10409,6 +9491,12 @@
             "util-deprecate": "~1.0.1"
           }
         },
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+          "dev": true
+        },
         "string_decoder": {
           "version": "1.1.1",
           "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@@ -10446,9 +9534,9 @@
           "dev": true
         },
         "readable-stream": {
-          "version": "2.3.6",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
-          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "version": "2.3.7",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+          "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
           "dev": true,
           "requires": {
             "core-util-is": "~1.0.0",
@@ -10460,6 +9548,12 @@
             "util-deprecate": "~1.0.1"
           }
         },
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+          "dev": true
+        },
         "string_decoder": {
           "version": "1.1.1",
           "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@@ -10472,9 +9566,9 @@
       }
     },
     "stream-splicer": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.0.tgz",
-      "integrity": "sha1-G2O+Q4oTPktnHMGTUZdgAXWRDYM=",
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.1.tgz",
+      "integrity": "sha512-Xizh4/NPuYSyAXyT7g8IvdJ9HJpxIGL9PjyhtywCZvvP0OPIdqyrr4dMikeuvY8xahpdKEBlBTySe583totajg==",
       "dev": true,
       "requires": {
         "inherits": "^2.0.1",
@@ -10488,9 +9582,9 @@
           "dev": true
         },
         "readable-stream": {
-          "version": "2.3.6",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
-          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "version": "2.3.7",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+          "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
           "dev": true,
           "requires": {
             "core-util-is": "~1.0.0",
@@ -10502,6 +9596,12 @@
             "util-deprecate": "~1.0.1"
           }
         },
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+          "dev": true
+        },
         "string_decoder": {
           "version": "1.1.1",
           "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@@ -10608,24 +9708,13 @@
       "dev": true,
       "requires": {
         "minimist": "^1.1.0"
-      },
-      "dependencies": {
-        "minimist": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
-          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
-          "dev": true
-        }
       }
     },
     "supports-color": {
-      "version": "3.2.3",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-      "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
-      "dev": true,
-      "requires": {
-        "has-flag": "^1.0.0"
-      }
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+      "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+      "dev": true
     },
     "supports-hyperlinks": {
       "version": "1.0.1",
@@ -10719,6 +9808,18 @@
         "string-width": "^2.1.1"
       },
       "dependencies": {
+        "ajv": {
+          "version": "5.5.2",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
+          "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
+          "dev": true,
+          "requires": {
+            "co": "^4.6.0",
+            "fast-deep-equal": "^1.0.0",
+            "fast-json-stable-stringify": "^2.0.0",
+            "json-schema-traverse": "^0.3.0"
+          }
+        },
         "ansi-styles": {
           "version": "3.2.1",
           "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
@@ -10739,12 +9840,24 @@
             "supports-color": "^5.3.0"
           }
         },
+        "fast-deep-equal": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
+          "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=",
+          "dev": true
+        },
         "has-flag": {
           "version": "3.0.0",
           "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
           "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
           "dev": true
         },
+        "json-schema-traverse": {
+          "version": "0.3.1",
+          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
+          "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
+          "dev": true
+        },
         "supports-color": {
           "version": "5.5.0",
           "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
@@ -10788,6 +9901,33 @@
         }
       }
     },
+    "tcp-port-used": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/tcp-port-used/-/tcp-port-used-1.0.2.tgz",
+      "integrity": "sha512-l7ar8lLUD3XS1V2lfoJlCBaeoaWo/2xfYt81hM7VlvR4RrMVFqfmzfhLVk40hAb368uitje5gPtBRL1m/DGvLA==",
+      "dev": true,
+      "requires": {
+        "debug": "4.3.1",
+        "is2": "^2.0.6"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "4.3.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+          "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+          "dev": true,
+          "requires": {
+            "ms": "2.1.2"
+          }
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        }
+      }
+    },
     "text-encoding": {
       "version": "0.6.4",
       "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz",
@@ -10813,12 +9953,12 @@
       "dev": true
     },
     "through2": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
-      "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
+      "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
       "dev": true,
       "requires": {
-        "readable-stream": "^2.1.5",
+        "readable-stream": "~2.3.6",
         "xtend": "~4.0.1"
       },
       "dependencies": {
@@ -10829,9 +9969,9 @@
           "dev": true
         },
         "readable-stream": {
-          "version": "2.3.6",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
-          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "version": "2.3.7",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+          "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
           "dev": true,
           "requires": {
             "core-util-is": "~1.0.0",
@@ -10843,6 +9983,12 @@
             "util-deprecate": "~1.0.1"
           }
         },
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+          "dev": true
+        },
         "string_decoder": {
           "version": "1.1.1",
           "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@@ -10855,9 +10001,9 @@
       }
     },
     "timers-browserify": {
-      "version": "2.0.10",
-      "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz",
-      "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==",
+      "version": "2.0.12",
+      "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz",
+      "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==",
       "dev": true,
       "requires": {
         "setimmediate": "^1.0.4"
@@ -10897,6 +10043,17 @@
       "dev": true,
       "requires": {
         "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
       }
     },
     "to-regex": {
@@ -10919,25 +10076,15 @@
       "requires": {
         "is-number": "^3.0.0",
         "repeat-string": "^1.6.1"
-      },
-      "dependencies": {
-        "is-number": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
-          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
-          "dev": true,
-          "requires": {
-            "kind-of": "^3.0.2"
-          }
-        }
       }
     },
     "tough-cookie": {
-      "version": "2.3.4",
-      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz",
-      "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==",
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
+      "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
       "requires": {
-        "punycode": "^1.4.1"
+        "psl": "^1.1.28",
+        "punycode": "^2.1.1"
       }
     },
     "toxic": {
@@ -10956,14 +10103,6 @@
       "dev": true,
       "requires": {
         "punycode": "^2.1.0"
-      },
-      "dependencies": {
-        "punycode": {
-          "version": "2.1.1",
-          "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
-          "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
-          "dev": true
-        }
       }
     },
     "trim-right": {
@@ -10989,8 +10128,7 @@
     "tweetnacl": {
       "version": "0.14.5",
       "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
-      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
-      "optional": true
+      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
     },
     "type-check": {
       "version": "0.3.2",
@@ -11061,12 +10199,13 @@
       "dev": true
     },
     "undeclared-identifiers": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.2.tgz",
-      "integrity": "sha512-13EaeocO4edF/3JKime9rD7oB6QI8llAGhgn5fKOPyfkJbRb6NFv9pYV6dFEmpa4uRjKeBqLZP8GpuzqHlKDMQ==",
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.3.tgz",
+      "integrity": "sha512-pJOW4nxjlmfwKApE4zvxLScM/njmwj/DiUBv7EabwE4O8kRUy+HIwxQtZLBPll/jx1LJyBcqNfB3/cpv9EZwOw==",
       "dev": true,
       "requires": {
         "acorn-node": "^1.3.0",
+        "dash-ast": "^1.0.0",
         "get-assigned-identifiers": "^1.2.0",
         "simple-concat": "^1.0.0",
         "xtend": "^4.0.1"
@@ -11140,9 +10279,9 @@
       }
     },
     "universal-user-agent": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-4.0.0.tgz",
-      "integrity": "sha512-eM8knLpev67iBDizr/YtqkJsF3GK8gzDc6st/WKzrTuPtcsOKW/0IdL4cnMBsU69pOx0otavLWBDGTwg+dB0aA==",
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-4.0.1.tgz",
+      "integrity": "sha512-LnST3ebHwVL2aNe4mejI9IQh2HfZ1RLo8Io2HugSif8ekzD1TlWpHpColOB/eh8JHMLkGH3Akqf040I+4ylNxg==",
       "dev": true,
       "requires": {
         "os-name": "^3.1.0"
@@ -11191,12 +10330,6 @@
           "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
           "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
           "dev": true
-        },
-        "isobject": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
-          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
-          "dev": true
         }
       }
     },
@@ -11211,20 +10344,11 @@
       }
     },
     "uri-js": {
-      "version": "4.2.2",
-      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
-      "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
-      "dev": true,
+      "version": "4.4.1",
+      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+      "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
       "requires": {
         "punycode": "^2.1.0"
-      },
-      "dependencies": {
-        "punycode": {
-          "version": "2.1.1",
-          "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
-          "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
-          "dev": true
-        }
       }
     },
     "urix": {
@@ -11270,6 +10394,14 @@
       "dev": true,
       "requires": {
         "inherits": "2.0.3"
+      },
+      "dependencies": {
+        "inherits": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+          "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+          "dev": true
+        }
       }
     },
     "util-deprecate": {
@@ -11279,9 +10411,9 @@
       "dev": true
     },
     "uuid": {
-      "version": "3.3.2",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
-      "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+      "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
     },
     "vargs": {
       "version": "0.1.0",
@@ -11290,9 +10422,9 @@
       "dev": true
     },
     "vendors": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.2.tgz",
-      "integrity": "sha512-w/hry/368nO21AN9QljsaIhb9ZiZtZARoVH5f3CsFbawdLdayCgKRPup7CggujvySMxx0I91NOyxdVENohprLQ==",
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz",
+      "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==",
       "dev": true
     },
     "verror": {
@@ -11327,9 +10459,9 @@
       "dev": true
     },
     "vue-hot-reload-api": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.0.tgz",
-      "integrity": "sha512-2j/t+wIbyVMP5NvctQoSUvLkYKoWAAk2QlQiilrM2a6/ulzFgdcLUJfTvs4XQ/3eZhHiBmmEojbjmM4AzZj8JA==",
+      "version": "2.3.4",
+      "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz",
+      "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==",
       "dev": true
     },
     "vue-loader": {
@@ -11353,24 +10485,46 @@
         "vue-template-es2015-compiler": "^1.2.2"
       },
       "dependencies": {
-        "loader-utils": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz",
-          "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=",
+        "big.js": {
+          "version": "5.2.2",
+          "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
+          "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+          "dev": true
+        },
+        "emojis-list": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
+          "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
+          "dev": true
+        },
+        "json5": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+          "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
           "dev": true,
           "requires": {
-            "big.js": "^3.1.3",
-            "emojis-list": "^2.0.0",
-            "json5": "^0.5.0"
+            "minimist": "^1.2.0"
+          }
+        },
+        "loader-utils": {
+          "version": "1.4.0",
+          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
+          "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
+          "dev": true,
+          "requires": {
+            "big.js": "^5.2.2",
+            "emojis-list": "^3.0.0",
+            "json5": "^1.0.1"
           }
         },
         "resolve": {
-          "version": "1.8.1",
-          "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz",
-          "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==",
+          "version": "1.20.0",
+          "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
+          "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
           "dev": true,
           "requires": {
-            "path-parse": "^1.0.5"
+            "is-core-module": "^2.2.0",
+            "path-parse": "^1.0.6"
           }
         }
       }
@@ -11385,15 +10539,36 @@
         "loader-utils": "^1.0.2"
       },
       "dependencies": {
-        "loader-utils": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz",
-          "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=",
+        "big.js": {
+          "version": "5.2.2",
+          "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
+          "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+          "dev": true
+        },
+        "emojis-list": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
+          "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
+          "dev": true
+        },
+        "json5": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+          "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
           "dev": true,
           "requires": {
-            "big.js": "^3.1.3",
-            "emojis-list": "^2.0.0",
-            "json5": "^0.5.0"
+            "minimist": "^1.2.0"
+          }
+        },
+        "loader-utils": {
+          "version": "1.4.0",
+          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
+          "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
+          "dev": true,
+          "requires": {
+            "big.js": "^5.2.2",
+            "emojis-list": "^3.0.0",
+            "json5": "^1.0.1"
           }
         }
       }
@@ -11409,17 +10584,17 @@
       },
       "dependencies": {
         "he": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
-          "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+          "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
           "dev": true
         }
       }
     },
     "vue-template-es2015-compiler": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.6.0.tgz",
-      "integrity": "sha512-x3LV3wdmmERhVCYy3quqA57NJW7F3i6faas++pJQWtknWT+n7k30F4TVdHvCLn48peTJFRvCpxs3UuFPqgeELg==",
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz",
+      "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
       "dev": true
     },
     "watchpack": {
@@ -11499,6 +10674,15 @@
           "integrity": "sha1-/s16GOfOXKar+5U+H4YhOknxYls=",
           "dev": true
         },
+        "supports-color": {
+          "version": "3.2.3",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+          "dev": true,
+          "requires": {
+            "has-flag": "^1.0.0"
+          }
+        },
         "uglify-js": {
           "version": "2.7.5",
           "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.7.5.tgz",
@@ -11574,14 +10758,6 @@
         "weex-templater": "^0.3.5",
         "weex-transformer": "^0.4.5",
         "weex-vue-loader": "^0.4.1"
-      },
-      "dependencies": {
-        "parse5": {
-          "version": "2.2.3",
-          "resolved": "https://registry.npmjs.org/parse5/-/parse5-2.2.3.tgz",
-          "integrity": "sha1-DE/EHBAAxea5PUiwP4CDg3g06fY=",
-          "dev": true
-        }
       }
     },
     "weex-rax-framework": {
@@ -11706,9 +10882,9 @@
       },
       "dependencies": {
         "he": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
-          "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+          "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
           "dev": true
         }
       }
@@ -11847,9 +11023,9 @@
           }
         },
         "chalk": {
-          "version": "2.4.1",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
-          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
           "dev": true,
           "requires": {
             "ansi-styles": "^3.2.1",
@@ -11864,9 +11040,9 @@
           "dev": true
         },
         "he": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
-          "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+          "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
           "dev": true
         },
         "postcss": {
@@ -11889,9 +11065,9 @@
           }
         },
         "supports-color": {
-          "version": "5.4.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
-          "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
           "dev": true,
           "requires": {
             "has-flag": "^3.0.0"
@@ -11900,9 +11076,9 @@
       }
     },
     "weex-vue-render": {
-      "version": "1.0.33",
-      "resolved": "https://registry.npmjs.org/weex-vue-render/-/weex-vue-render-1.0.33.tgz",
-      "integrity": "sha512-z+61V3NPbaHQHaJva9Bihjr2nZjR9dgvanrHc9j7ALsSATGwcGu1mLTsKz7xIbu+Doxzrj23r3X9ti6MvB3UQg==",
+      "version": "1.0.36",
+      "resolved": "https://registry.npmjs.org/weex-vue-render/-/weex-vue-render-1.0.36.tgz",
+      "integrity": "sha512-1EAI3ls+ky9LOUHJ9hvbLBMn89F7uWu4MLSCHkm3/F7TnX3kdgF+JIafrRvx4OXQhFE8xFzVXdWyRnBZyv/xRA==",
       "dev": true
     },
     "weex-wd": {
@@ -11916,9 +11092,9 @@
       }
     },
     "whatwg-fetch": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz",
-      "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==",
+      "version": "3.6.2",
+      "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz",
+      "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==",
       "dev": true
     },
     "whatwg-url": {
@@ -11954,14 +11130,20 @@
       "dev": true
     },
     "windows-release": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz",
-      "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==",
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.3.3.tgz",
+      "integrity": "sha512-OSOGH1QYiW5yVor9TtmXKQvt2vjQqbYS+DqmsZw+r7xDwLXEeT3JGW0ZppFmHx4diyXmxt238KFR3N9jzevBRg==",
       "dev": true,
       "requires": {
         "execa": "^1.0.0"
       }
     },
+    "word-wrap": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+      "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+      "dev": true
+    },
     "wordwrap": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
@@ -12024,21 +11206,21 @@
       }
     },
     "xmldom": {
-      "version": "0.1.27",
-      "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz",
-      "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=",
+      "version": "0.1.31",
+      "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz",
+      "integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ==",
       "dev": true
     },
     "xtend": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
-      "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
       "dev": true
     },
     "xutil": {
-      "version": "1.0.11",
-      "resolved": "https://registry.npmjs.org/xutil/-/xutil-1.0.11.tgz",
-      "integrity": "sha512-gGPrnfcP64684kJbxdHCH0g/I+4dfyeJJL+wJR1jKJyMSJCSP1qaMcjFlymY0PV9uPUEApnTw+Ys7ueM9HLUNQ==",
+      "version": "1.0.12",
+      "resolved": "https://registry.npmjs.org/xutil/-/xutil-1.0.12.tgz",
+      "integrity": "sha512-W7UKJeSPM6vYOT8wL3Y42c9Pnuwvjg1+QhhrD33n78o3u2vEX3piKgcSSXMg1BhqhqQWN3H6ejjAGtvaIuzgNg==",
       "dev": true,
       "requires": {
         "chalk": "^2.3.0",
@@ -12046,11 +11228,11 @@
         "ipv4": "^1.0.2",
         "lodash": "^4.17.4",
         "mkdirp": "~0.5.1",
-        "moment": "~2.18.1",
+        "moment": "~2.24.0",
         "opn": "^5.1.0",
         "rimraf": "^2.5.4",
         "semver": "^5.4.1",
-        "shelljs": "^0.7.8",
+        "shelljs": "^0.8.4",
         "uuid": "^3.1.0"
       },
       "dependencies": {
@@ -12064,9 +11246,9 @@
           }
         },
         "chalk": {
-          "version": "2.4.1",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
-          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
           "dev": true,
           "requires": {
             "ansi-styles": "^3.2.1",
@@ -12074,22 +11256,41 @@
             "supports-color": "^5.3.0"
           }
         },
+        "glob": {
+          "version": "7.1.7",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
+          "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
+          "dev": true,
+          "requires": {
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^3.0.4",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
+          }
+        },
         "has-flag": {
           "version": "3.0.0",
           "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
           "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
           "dev": true
         },
-        "moment": {
-          "version": "2.18.1",
-          "resolved": "https://registry.npmjs.org/moment/-/moment-2.18.1.tgz",
-          "integrity": "sha1-w2GT3Tzhwu7SrbfIAtu8d6gbHA8=",
-          "dev": true
+        "shelljs": {
+          "version": "0.8.4",
+          "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz",
+          "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==",
+          "dev": true,
+          "requires": {
+            "glob": "^7.0.0",
+            "interpret": "^1.0.0",
+            "rechoir": "^0.6.2"
+          }
         },
         "supports-color": {
-          "version": "5.4.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
-          "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
           "dev": true,
           "requires": {
             "has-flag": "^3.0.0"
@@ -12116,12 +11317,13 @@
       }
     },
     "yauzl": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz",
-      "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=",
+      "version": "2.10.0",
+      "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
+      "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
       "dev": true,
       "requires": {
-        "fd-slicer": "~1.0.1"
+        "buffer-crc32": "~0.2.3",
+        "fd-slicer": "~1.1.0"
       }
     },
     "zip-stream": {
diff --git a/package.json b/package.json
index 9c0de09..7c8dd41 100644
--- a/package.json
+++ b/package.json
@@ -42,13 +42,8 @@
     "build:vue": "node build/build.js vue",
     "build:rax": "node build/build.js rax",
     "build:runtime": "node build/build.js runtime",
-    "build:legacy": "node build/build.js legacy",
-    "build:vanilla": "node build/build.js vanilla",
     "install:buildtools": "npm i webpack@^1.0 rollup rollup-watch rollup-plugin-buble rollup-plugin-json rollup-plugin-eslint rollup-plugin-commonjs rollup-plugin-postcss rollup-plugin-replace rollup-plugin-uglify rollup-plugin-node-resolve babel-core babel-eslint babel-istanbul babel-loader babel-plugin-coverage babel-preset-es2015 babel-runtime uglify-es eslint-plugin-flowtype eslint",
     "build:source": "npm run build:native",
-    "build:examples": "npm run build:examples:native && npm run build:examples:web",
-    "build:examples:native": "webpack --config build/webpack.examples.config.js",
-    "build:examples:web": "webpack --config build/webpack.examples.web.config.js",
     "build:test": "webpack --config build/webpack.test.config.js",
     "build:ci:web": "webpack --watch --config build/webpack.ci.web.config.js",
     "build:ci:native": "webpack --watch --config build/webpack.ci.config.js",
@@ -56,10 +51,6 @@
     "build": "npm run build:env && npm run build:jsfm && npm run build:vue && npm run build:rax",
     "dev:jsfm": "node build/build.js jsfm --watch",
     "dev:runtime": "node build/build.js runtime --watch",
-    "dev:legacy": "node build/build.js legacy --watch",
-    "dev:vanilla": "node build/build.js vanilla --watch",
-    "dev:examples": "webpack --watch --config build/webpack.examples.config.js",
-    "dev:examples:web": "webpack --watch --config build/webpack.examples.web.config.js",
     "dev:test": "webpack --watch --config build/webpack.test.config.js",
     "lint": "eslint runtime",
     "test:case": "mocha --require reify test/js-framework/case/tester.js",
@@ -69,13 +60,10 @@
     "test:cover": "babel-istanbul cover --report text node_modules/mocha/bin/_mocha -- --require reify --reporter dot html5/test/unit/",
     "serve": "serve ./ -p 12580",
     "serve:no-port": "serve ./",
-    "clean:examples": "echo \"\\033[36;1m[Clean]\\033[0m \\033[33mexamples\\033[0m\" && rm -vrf examples/build/*",
     "clean:test": "echo \"\\033[36;1m[Clean]\\033[0m \\033[33mtest\\033[0m\" && rm -vrf test/build/*",
-    "clean": "npm run clean:examples && npm run clean:test",
+    "clean": "npm run clean:test",
     "copy:js": "cp -vf ./packages/weex-js-framework/index.js ./pre-build/native-bundle-main.js",
-    "copy:examples": "rm -rf ./android/playground/app/src/main/assets/* && cp -vrf ./examples/build/* ./android/playground/app/src/main/assets/",
-    "copy": "npm run copy:js && npm run copy:examples",
-    "danger": "danger"
+    "copy": "npm run copy:js"
   },
   "dependencies": {
     "@weex-project/downgrade": "^1.0.3",
diff --git a/packages/weex-legacy-framework/.npmignore b/packages/weex-legacy-framework/.npmignore
deleted file mode 100644
index 1cb6dac..0000000
--- a/packages/weex-legacy-framework/.npmignore
+++ /dev/null
@@ -1,4 +0,0 @@
-node_modules
-package-lock.json
-*.log
-*.gz
diff --git a/packages/weex-legacy-framework/index.js b/packages/weex-legacy-framework/index.js
deleted file mode 100644
index b25b72e..0000000
--- a/packages/weex-legacy-framework/index.js
+++ /dev/null
@@ -1,5777 +0,0 @@
-/* Weex Legacy Framework 0.21.6, Build 2017-08-08 12:03. */
-
-(function (global, factory) {
-	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
-	typeof define === 'function' && define.amd ? define(['exports'], factory) :
-	(factory((global.WeexLegacyFramework = global.WeexLegacyFramework || {})));
-}(this, (function (exports) { 'use strict';
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-/**
- * @fileOverview The api for invoking with "$" prefix
- */
-
-/**
- * @deprecated use $vm instead
- * find the vm by id
- * Note: there is only one id in whole component
- * @param  {string} id
- * @return {Vm}
- */
-function $ (id) {
-  console.warn('[JS Framework] Vm#$ is deprecated, please use Vm#$vm instead');
-  var info = this._ids[id];
-  if (info) {
-    return info.vm
-  }
-}
-
-/**
- * find the element by id
- * Note: there is only one id in whole component
- * @param  {string} id
- * @return {Element}
- */
-function $el (id) {
-  var info = this._ids[id];
-  if (info) {
-    return info.el
-  }
-}
-
-/**
- * find the vm of the custom component by id
- * Note: there is only one id in whole component
- * @param  {string} id
- * @return {Vm}
- */
-function $vm (id) {
-  var info = this._ids[id];
-  if (info) {
-    return info.vm
-  }
-}
-
-/**
- * Fire when differ rendering finished
- *
- * @param  {Function} fn
- */
-function $renderThen (fn) {
-  var app = this._app;
-  var differ = app.differ;
-  return differ.then(function () {
-    fn();
-  })
-}
-
-/**
- * scroll an element specified by id into view,
- * moreover specify a number of offset optionally
- * @param  {string} id
- * @param  {number} offset
- */
-function $scrollTo (id, offset) {
-  console.warn('[JS Framework] Vm#$scrollTo is deprecated, ' +
-          'please use "require(\'@weex-module/dom\')' +
-          '.scrollTo(el, options)" instead');
-  var el = this.$el(id);
-  if (el) {
-    var dom = this._app.requireModule('dom');
-    dom.scrollToElement(el.ref, { offset: offset });
-  }
-}
-
-/**
- * perform transition animation on an element specified by id
- * @param  {string}   id
- * @param  {object}   options
- * @param  {object}   options.styles
- * @param  {object}   options.duration(ms)
- * @param  {object}   [options.timingFunction]
- * @param  {object}   [options.delay=0(ms)]
- * @param  {Function} callback
- */
-function $transition (id, options, callback) {
-  var this$1 = this;
-
-  var el = this.$el(id);
-  if (el && options && options.styles) {
-    var animation = this._app.requireModule('animation');
-    animation.transition(el.ref, options, function () {
-      var args = [], len = arguments.length;
-      while ( len-- ) args[ len ] = arguments[ len ];
-
-      this$1._setStyle(el, options.styles);
-      callback && callback.apply(void 0, args);
-    });
-  }
-}
-
-/**
- * get some config
- * @return {object} some config for app instance
- * @property {string} bundleUrl
- * @property {boolean} debug
- * @property {object} env
- * @property {string} env.weexVersion(ex. 1.0.0)
- * @property {string} env.appName(ex. TB/TM)
- * @property {string} env.appVersion(ex. 5.0.0)
- * @property {string} env.platform(ex. iOS/Android)
- * @property {string} env.osVersion(ex. 7.0.0)
- * @property {string} env.deviceModel **native only**
- * @property {number} env.[deviceWidth=750]
- * @property {number} env.deviceHeight
- */
-function $getConfig (callback) {
-  var config = this._app.options;
-  if (typeof callback === 'function') {
-    console.warn('[JS Framework] the callback of Vm#$getConfig(callback) is deprecated, ' +
-      'this api now can directly RETURN config info.');
-    callback(config);
-  }
-  return config
-}
-
-/**
- * @deprecated
- * request network via http protocol
- * @param  {object}   params
- * @param  {Function} callback
- */
-function $sendHttp (params, callback) {
-  console.warn('[JS Framework] Vm#$sendHttp is deprecated, ' +
-          'please use "require(\'@weex-module/stream\')' +
-          '.sendHttp(params, callback)" instead');
-  var stream = this._app.requireModule('stream');
-  stream.sendHttp(params, callback);
-}
-
-/**
- * @deprecated
- * open a url
- * @param  {string} url
- */
-function $openURL (url) {
-  console.warn('[JS Framework] Vm#$openURL is deprecated, ' +
-          'please use "require(\'@weex-module/event\')' +
-          '.openURL(url)" instead');
-  var event = this._app.requireModule('event');
-  event.openURL(url);
-}
-
-/**
- * @deprecated
- * set a title for page
- * @param  {string} title
- */
-function $setTitle (title) {
-  console.warn('[JS Framework] Vm#$setTitle is deprecated, ' +
-          'please use "require(\'@weex-module/pageInfo\')' +
-          '.setTitle(title)" instead');
-  var pageInfo = this._app.requireModule('pageInfo');
-  pageInfo.setTitle(title);
-}
-
-/**
- * @deprecated use "require('@weex-module/moduleName') instead"
- * invoke a native method by specifing the name of module and method
- * @param  {string} moduleName
- * @param  {string} methodName
- * @param  {...*} the rest arguments
- */
-function $call (moduleName, methodName) {
-  var args = [], len = arguments.length - 2;
-  while ( len-- > 0 ) args[ len ] = arguments[ len + 2 ];
-
-  console.warn('[JS Framework] Vm#$call is deprecated, ' +
-    'please use "require(\'@weex-module/moduleName\')" instead');
-  var module = this._app.requireModule(moduleName);
-  if (module && module[methodName]) {
-    module[methodName].apply(module, args);
-  }
-}
-
-
-var methods = Object.freeze({
-	$: $,
-	$el: $el,
-	$vm: $vm,
-	$renderThen: $renderThen,
-	$scrollTo: $scrollTo,
-	$transition: $transition,
-	$getConfig: $getConfig,
-	$sendHttp: $sendHttp,
-	$openURL: $openURL,
-	$setTitle: $setTitle,
-	$call: $call
-});
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-/**
- * Mix properties into target object.
- *
- * @param {Object} to
- * @param {Object} from
- */
-
-function extend (target) {
-  var src = [], len = arguments.length - 1;
-  while ( len-- > 0 ) src[ len ] = arguments[ len + 1 ];
-
-  /* istanbul ignore else */
-  if (typeof Object.assign === 'function') {
-    Object.assign.apply(Object, [ target ].concat( src ));
-  }
-  else {
-    var first = src.shift();
-    for (var key in first) {
-      target[key] = first[key];
-    }
-    if (src.length) {
-      extend.apply(void 0, [ target ].concat( src ));
-    }
-  }
-  return target
-}
-
-/**
- * Define a property.
- *
- * @param {Object} obj
- * @param {String} key
- * @param {*} val
- * @param {Boolean} [enumerable]
- */
-
-function def (obj, key, val, enumerable) {
-  Object.defineProperty(obj, key, {
-    value: val,
-    enumerable: !!enumerable,
-    writable: true,
-    configurable: true
-  });
-}
-
-/**
- * Remove an item from an array
- *
- * @param {Array} arr
- * @param {*} item
- */
-
-function remove (arr, item) {
-  if (arr.length) {
-    var index = arr.indexOf(item);
-    if (index > -1) {
-      return arr.splice(index, 1)
-    }
-  }
-}
-
-/**
- * Check whether the object has the property.
- *
- * @param {Object} obj
- * @param {String} key
- * @return {Boolean}
- */
-var hasOwnProperty = Object.prototype.hasOwnProperty;
-function hasOwn (obj, key) {
-  return hasOwnProperty.call(obj, key)
-}
-
-/**
- * Simple bind, faster than native
- *
- * @param {Function} fn
- * @param {Object} ctx
- * @return {Function}
- */
-
-function bind (fn, ctx) {
-  return function (a) {
-    var l = arguments.length;
-    return l
-      ? l > 1
-        ? fn.apply(ctx, arguments)
-        : fn.call(ctx, a)
-      : fn.call(ctx)
-  }
-}
-
-/**
- * Quick object check - this is primarily used to tell
- * Objects from primitive values when we know the value
- * is a JSON-compliant type.
- *
- * @param {*} obj
- * @return {Boolean}
- */
-
-function isObject (obj) {
-  return obj !== null && typeof obj === 'object'
-}
-
-/**
- * Strict object type check. Only returns true
- * for plain JavaScript objects.
- *
- * @param {*} obj
- * @return {Boolean}
- */
-
-var toString = Object.prototype.toString;
-var OBJECT_STRING = '[object Object]';
-function isPlainObject (obj) {
-  return toString.call(obj) === OBJECT_STRING
-}
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-/**
- * Check if a string starts with $ or _
- *
- * @param {String} str
- * @return {Boolean}
- */
-
-function isReserved (str) {
-  var c = (str + '').charCodeAt(0);
-  return c === 0x24 || c === 0x5F
-}
-
-// can we use __proto__?
-var hasProto = '__proto__' in {};
-
-var _Set;
-/* istanbul ignore next */
-if (typeof Set !== 'undefined' && Set.toString().match(/native code/)) {
-  // use native Set when available.
-  _Set = Set;
-}
-else {
-  // a non-standard Set polyfill that only works with primitive keys.
-  _Set = function () {
-    this.set = Object.create(null);
-  };
-  _Set.prototype.has = function (key) {
-    return this.set[key] !== undefined
-  };
-  _Set.prototype.add = function (key) {
-    if (key == null || this.set[key]) {
-      return
-    }
-    this.set[key] = 1;
-  };
-  _Set.prototype.clear = function () {
-    this.set = Object.create(null);
-  };
-}
-
-/**
- * Polyfill in iOS7 by native because the JavaScript polyfill has memory problem.
- * @return {object}
- */
-
-function createNewSet () {
-  /* istanbul ignore next */
-  /* eslint-disable */
-  if (typeof nativeSet === 'object') {
-    return nativeSet.create()
-  }
-  /* eslint-enable */
-  return new _Set()
-}
-
-/**
- * Create a cached version of a pure function.
- *
- * @param {Function} fn
- * @return {Function}
- */
-
-
-
-
-
-
-
-function typof (v) {
-  var s = Object.prototype.toString.call(v);
-  return s.substring(8, s.length - 1).toLowerCase()
-}
-
-// weex name rules
-
-var WEEX_COMPONENT_REG = /^@weex-component\//;
-var WEEX_MODULE_REG = /^@weex-module\//;
-var NORMAL_MODULE_REG = /^\.{1,2}\//;
-var JS_SURFIX_REG = /\.js$/;
-
-var isWeexComponent = function (name) { return !!name.match(WEEX_COMPONENT_REG); };
-var isWeexModule = function (name) { return !!name.match(WEEX_MODULE_REG); };
-var isNormalModule = function (name) { return !!name.match(NORMAL_MODULE_REG); };
-var isNpmModule = function (name) { return !isWeexComponent(name) && !isWeexModule(name) && !isNormalModule(name); };
-
-function removeWeexPrefix (str) {
-  var result = str.replace(WEEX_COMPONENT_REG, '').replace(WEEX_MODULE_REG, '');
-  return result
-}
-
-function removeJSSurfix (str) {
-  return str.replace(JS_SURFIX_REG, '')
-}
-
-/* eslint-disable */
-
-
-var uid$1 = 0;
-
-/**
- * A dep is an observable that can have multiple
- * directives subscribing to it.
- *
- * @constructor
- */
-
-function Dep () {
-  this.id = uid$1++;
-  this.subs = [];
-}
-
-// the current target watcher being evaluated.
-// this is globally unique because there could be only one
-// watcher being evaluated at any time.
-Dep.target = null;
-var targetStack = [];
-
-function pushTarget (_target) {
-  if (Dep.target) { targetStack.push(Dep.target); }
-  Dep.target = _target;
-}
-
-function popTarget () {
-  Dep.target = targetStack.pop();
-}
-
-function resetTarget () {
-  Dep.target = null;
-  targetStack = [];
-}
-
-/**
- * Add a directive subscriber.
- *
- * @param {Directive} sub
- */
-
-Dep.prototype.addSub = function (sub) {
-  this.subs.push(sub);
-};
-
-/**
- * Remove a directive subscriber.
- *
- * @param {Directive} sub
- */
-
-Dep.prototype.removeSub = function (sub) {
-  remove(this.subs, sub);
-};
-
-/**
- * Add self as a dependency to the target watcher.
- */
-
-Dep.prototype.depend = function () {
-  if (Dep.target) {
-    Dep.target.addDep(this);
-  }
-};
-
-/**
- * Notify all subscribers of a new value.
- */
-
-Dep.prototype.notify = function () {
-  // stablize the subscriber list first
-  var subs = this.subs.slice();
-  for (var i = 0, l = subs.length; i < l; i++) {
-    subs[i].update();
-  }
-};
-
-/* eslint-disable */
-
-
-// import { pushWatcher } from './batcher'
-var uid = 0;
-
-/**
- * A watcher parses an expression, collects dependencies,
- * and fires callback when the expression value changes.
- * This is used for both the $watch() api and directives.
- *
- * @param {Vue} vm
- * @param {String|Function} expOrFn
- * @param {Function} cb
- * @param {Object} options
- *                 - {Array} filters
- *                 - {Boolean} twoWay
- *                 - {Boolean} deep
- *                 - {Boolean} user
- *                 - {Boolean} sync
- *                 - {Boolean} lazy
- *                 - {Function} [preProcess]
- *                 - {Function} [postProcess]
- * @constructor
- */
-
-function Watcher (vm, expOrFn, cb, options) {
-  // mix in options
-  if (options) {
-    extend(this, options);
-  }
-  var isFn = typeof expOrFn === 'function';
-  this.vm = vm;
-  vm._watchers.push(this);
-  this.expression = expOrFn;
-  this.cb = cb;
-  this.id = ++uid; // uid for batching
-  this.active = true;
-  this.dirty = this.lazy; // for lazy watchers
-  this.deps = [];
-  this.newDeps = [];
-  this.depIds = createNewSet(); // new Set()
-  this.newDepIds = createNewSet(); // new Set()
-  // parse expression for getter
-  if (isFn) {
-    this.getter = expOrFn;
-  }
-  this.value = this.lazy
-    ? undefined
-    : this.get();
-  // state for avoiding false triggers for deep and Array
-  // watchers during vm._digest()
-  this.queued = this.shallow = false;
-}
-
-/**
- * Evaluate the getter, and re-collect dependencies.
- */
-
-Watcher.prototype.get = function () {
-  pushTarget(this);
-  var value = this.getter.call(this.vm, this.vm);
-  // "touch" every property so they are all tracked as
-  // dependencies for deep watching
-  if (this.deep) {
-    traverse(value);
-  }
-  popTarget();
-  this.cleanupDeps();
-  return value
-};
-
-/**
- * Add a dependency to this directive.
- *
- * @param {Dep} dep
- */
-
-Watcher.prototype.addDep = function (dep) {
-  var id = dep.id;
-  if (!this.newDepIds.has(id)) {
-    this.newDepIds.add(id);
-    this.newDeps.push(dep);
-    if (!this.depIds.has(id)) {
-      dep.addSub(this);
-    }
-  }
-};
-
-/**
- * Clean up for dependency collection.
- */
-
-Watcher.prototype.cleanupDeps = function () {
-  var this$1 = this;
-
-  var i = this.deps.length;
-  while (i--) {
-    var dep = this$1.deps[i];
-    if (!this$1.newDepIds.has(dep.id)) {
-      dep.removeSub(this$1);
-    }
-  }
-  var tmp = this.depIds;
-  this.depIds = this.newDepIds;
-  this.newDepIds = tmp;
-  this.newDepIds.clear();
-  tmp = this.deps;
-  this.deps = this.newDeps;
-  this.newDeps = tmp;
-  this.newDeps.length = 0;
-};
-
-/**
- * Subscriber interface.
- * Will be called when a dependency changes.
- *
- * @param {Boolean} shallow
- */
-
-Watcher.prototype.update = function (shallow) {
-  if (this.lazy) {
-    this.dirty = true;
-  } else {
-    this.run();
-  }
-  // } else if (this.sync) {
-  //   this.run()
-  // } else {
-  //   // if queued, only overwrite shallow with non-shallow,
-  //   // but not the other way around.
-  //   this.shallow = this.queued
-  //     ? shallow
-  //       ? this.shallow
-  //       : false
-  //     : !!shallow
-  //   this.queued = true
-  //   pushWatcher(this)
-  // }
-};
-
-/**
- * Batcher job interface.
- * Will be called by the batcher.
- */
-
-Watcher.prototype.run = function () {
-  if (this.active) {
-    var value = this.get();
-    if (
-      value !== this.value ||
-      // Deep watchers and watchers on Object/Arrays should fire even
-      // when the value is the same, because the value may
-      // have mutated; but only do so if this is a
-      // non-shallow update (caused by a vm digest).
-      ((isObject(value) || this.deep) && !this.shallow)
-    ) {
-      // set new value
-      var oldValue = this.value;
-      this.value = value;
-      this.cb.call(this.vm, value, oldValue);
-    }
-    this.queued = this.shallow = false;
-  }
-};
-
-/**
- * Evaluate the value of the watcher.
- * This only gets called for lazy watchers.
- */
-
-Watcher.prototype.evaluate = function () {
-  this.value = this.get();
-  this.dirty = false;
-};
-
-/**
- * Depend on all deps collected by this watcher.
- */
-
-Watcher.prototype.depend = function () {
-  var this$1 = this;
-
-  var i = this.deps.length;
-  while (i--) {
-    this$1.deps[i].depend();
-  }
-};
-
-/**
- * Remove self from all dependencies' subcriber list.
- */
-
-Watcher.prototype.teardown = function () {
-  var this$1 = this;
-
-  if (this.active) {
-    // remove self from vm's watcher list
-    // this is a somewhat expensive operation so we skip it
-    // if the vm is being destroyed or is performing a v-for
-    // re-render (the watcher list is then filtered by v-for).
-    if (!this.vm._isBeingDestroyed && !this.vm._vForRemoving) {
-      remove(this.vm._watchers, this);
-    }
-    var i = this.deps.length;
-    while (i--) {
-      this$1.deps[i].removeSub(this$1);
-    }
-    this.active = false;
-    this.vm = this.cb = this.value = null;
-  }
-};
-
-/**
- * Recrusively traverse an object to evoke all converted
- * getters, so that every nested property inside the object
- * is collected as a "deep" dependency.
- *
- * @param {*} val
- * @param {Set} seen
- */
-
-var seenObjects = createNewSet(); // new Set()
-/* istanbul ignore next */
-function traverse (val, seen) {
-  var i, keys, isA, isO;
-  if (!seen) {
-    seen = seenObjects;
-    seen.clear();
-  }
-  isA = Array.isArray(val);
-  isO = isObject(val);
-  if (isA || isO) {
-    if (val.__ob__) {
-      var depId = val.__ob__.dep.id;
-      if (seen.has(depId)) {
-        return
-      } else {
-        seen.add(depId);
-      }
-    }
-    if (isA) {
-      i = val.length;
-      while (i--) { traverse(val[i], seen); }
-    } else if (isO) {
-      keys = Object.keys(val);
-      i = keys.length;
-      while (i--) { traverse(val[keys[i]], seen); }
-    }
-  }
-}
-
-/* eslint-disable */
-
-
-var arrayProto = Array.prototype;
-var arrayMethods = Object.create(arrayProto);[
-  'push',
-  'pop',
-  'shift',
-  'unshift',
-  'splice',
-  'sort',
-  'reverse'
-]
-.forEach(function (method) {
-  // cache original method
-  var original = arrayProto[method];
-  def(arrayMethods, method, function mutator () {
-    var arguments$1 = arguments;
-
-    // avoid leaking arguments:
-    // http://jsperf.com/closure-with-arguments
-    var i = arguments.length;
-    var args = new Array(i);
-    while (i--) {
-      args[i] = arguments$1[i];
-    }
-    var result = original.apply(this, args);
-    var ob = this.__ob__;
-    var inserted;
-    switch (method) {
-      case 'push':
-        inserted = args;
-        break
-      case 'unshift':
-        inserted = args;
-        break
-      case 'splice':
-        inserted = args.slice(2);
-        break
-    }
-    if (inserted) { ob.observeArray(inserted); }
-    // notify change
-    ob.dep.notify();
-    return result
-  });
-});
-
-/**
- * Swap the element at the given index with a new value
- * and emits corresponding event.
- *
- * @param {Number} index
- * @param {*} val
- * @return {*} - replaced element
- */
-
-def(
-  arrayProto,
-  '$set',
-  function $set (index, val) {
-    console.warn("[JS Framework] \"Array.prototype.$set\" is not a standard API,"
-      + " it will be removed in the next version.");
-    if (index >= this.length) {
-      this.length = index + 1;
-    }
-    return this.splice(index, 1, val)[0]
-  }
-);
-
-/**
- * Convenience method to remove the element at given index.
- *
- * @param {Number} index
- * @param {*} val
- */
-
-def(
-  arrayProto,
-  '$remove',
-  function $remove (index) {
-    console.warn("[JS Framework] \"Array.prototype.$remove\" is not a standard API,"
-      + " it will be removed in the next version.");
-    /* istanbul ignore if */
-    if (!this.length) { return }
-    /* istanbul ignore else */
-    if (typeof index !== 'number') {
-      index = this.indexOf(index);
-    }
-    /* istanbul ignore else */
-    if (index > -1) {
-      this.splice(index, 1);
-    }
-  }
-);
-
-/* eslint-disable */
-
-
-var arrayKeys = Object.getOwnPropertyNames(arrayMethods);
-
-/**
- * Observer class that are attached to each observed
- * object. Once attached, the observer converts target
- * object's property keys into getter/setters that
- * collect dependencies and dispatches updates.
- *
- * @param {Array|Object} value
- * @constructor
- */
-
-function Observer (value) {
-  this.value = value;
-  this.dep = new Dep();
-  def(value, '__ob__', this);
-  if (Array.isArray(value)) {
-    var augment = hasProto
-      ? protoAugment
-      : copyAugment;
-    augment(value, arrayMethods, arrayKeys);
-    this.observeArray(value);
-  } else {
-    this.walk(value);
-  }
-}
-
-// Instance methods
-
-/**
- * Walk through each property and convert them into
- * getter/setters. This method should only be called when
- * value type is Object.
- *
- * @param {Object} obj
- */
-
-Observer.prototype.walk = function (obj) {
-  var this$1 = this;
-
-  for (var key in obj) {
-    this$1.convert(key, obj[key]);
-  }
-};
-
-/**
- * Observe a list of Array items.
- *
- * @param {Array} items
- */
-
-Observer.prototype.observeArray = function (items) {
-  for (var i = 0, l = items.length; i < l; i++) {
-    observe(items[i]);
-  }
-};
-
-/**
- * Convert a property into getter/setter so we can emit
- * the events when the property is accessed/changed.
- *
- * @param {String} key
- * @param {*} val
- */
-
-Observer.prototype.convert = function (key, val) {
-  defineReactive(this.value, key, val);
-};
-
-/**
- * Add an owner vm, so that when $set/$delete mutations
- * happen we can notify owner vms to proxy the keys and
- * digest the watchers. This is only called when the object
- * is observed as an instance's root $data.
- *
- * @param {Vue} vm
- */
-
-Observer.prototype.addVm = function (vm) {
-  (this.vms || (this.vms = [])).push(vm);
-};
-
-/**
- * Remove an owner vm. This is called when the object is
- * swapped out as an instance's $data object.
- *
- * @param {Vue} vm
- */
-
-/* istanbul ignore next */
-Observer.prototype.removeVm = function (vm) {
-  remove(this.vms, vm);
-};
-
-// helpers
-
-/**
- * Augment an target Object or Array by intercepting
- * the prototype chain using __proto__
- *
- * @param {Object|Array} target
- * @param {Object} src
- */
-
-function protoAugment (target, src) {
-  /* eslint-disable no-proto */
-  target.__proto__ = src;
-  /* eslint-enable no-proto */
-}
-
-/**
- * Augment an target Object or Array by defining
- * hidden properties.
- *
- * @param {Object|Array} target
- * @param {Object} proto
- */
-
-/* istanbul ignore next */
-function copyAugment (target, src, keys) {
-  for (var i = 0, l = keys.length; i < l; i++) {
-    var key = keys[i];
-    def(target, key, src[key]);
-  }
-}
-
-/**
- * Attempt to create an observer instance for a value,
- * returns the new observer if successfully observed,
- * or the existing observer if the value already has one.
- *
- * @param {*} value
- * @param {Vue} [vm]
- * @return {Observer|undefined}
- * @static
- */
-
-function observe (value, vm) {
-  if (!isObject(value)) {
-    return
-  }
-  var ob;
-  if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
-    ob = value.__ob__;
-  } else if (
-    (Array.isArray(value) || isPlainObject(value)) &&
-    Object.isExtensible(value) &&
-    !value._isVue
-  ) {
-    ob = new Observer(value);
-  }
-  if (ob && vm) {
-    ob.addVm(vm);
-  }
-  return ob
-}
-
-/**
- * Define a reactive property on an Object.
- *
- * @param {Object} obj
- * @param {String} key
- * @param {*} val
- */
-
-function defineReactive (obj, key, val) {
-  var dep = new Dep();
-
-  var property = Object.getOwnPropertyDescriptor(obj, key);
-  if (property && property.configurable === false) {
-    return
-  }
-
-  // cater for pre-defined getter/setters
-  var getter = property && property.get;
-  var setter = property && property.set;
-
-  var childOb = observe(val);
-  Object.defineProperty(obj, key, {
-    enumerable: true,
-    configurable: true,
-    get: function reactiveGetter () {
-      var value = getter ? getter.call(obj) : val;
-      if (Dep.target) {
-        dep.depend();
-        if (childOb) {
-          childOb.dep.depend();
-        }
-        if (Array.isArray(value)) {
-          for (var e = (void 0), i = 0, l = value.length; i < l; i++) {
-            e = value[i];
-            e && e.__ob__ && e.__ob__.dep.depend();
-          }
-        }
-      }
-      return value
-    },
-    set: function reactiveSetter (newVal) {
-      var value = getter ? getter.call(obj) : val;
-      if (newVal === value) {
-        return
-      }
-      if (setter) {
-        setter.call(obj, newVal);
-      } else {
-        val = newVal;
-      }
-      childOb = observe(newVal);
-      dep.notify();
-    }
-  });
-}
-
-/**
- * Set a property on an object. Adds the new property and
- * triggers change notification if the property doesn't
- * already exist.
- *
- * @param {Object} obj
- * @param {String} key
- * @param {*} val
- * @public
- */
-
-/* istanbul ignore next */
-function set (obj, key, val) {
-  if (Array.isArray(obj)) {
-    return obj.splice(key, 1, val)
-  }
-  if (hasOwn(obj, key)) {
-    obj[key] = val;
-    return
-  }
-  if (obj._isVue) {
-    set(obj._data, key, val);
-    return
-  }
-  var ob = obj.__ob__;
-  if (!ob) {
-    obj[key] = val;
-    return
-  }
-  ob.convert(key, val);
-  ob.dep.notify();
-  if (ob.vms) {
-    var i = ob.vms.length;
-    while (i--) {
-      var vm = ob.vms[i];
-      proxy(vm, key);
-      // vm.$forceUpdate()
-    }
-  }
-  return val
-}
-
-/**
- * Delete a property and trigger change if necessary.
- *
- * @param {Object} obj
- * @param {String} key
- */
-
-/* istanbul ignore next */
-function del (obj, key) {
-  if (!hasOwn(obj, key)) {
-    return
-  }
-  delete obj[key];
-  var ob = obj.__ob__;
-
-  if (!ob) {
-    if (obj._isVue) {
-      delete obj._data[key];
-      // obj.$forceUpdate()
-    }
-    return
-  }
-  ob.dep.notify();
-  if (ob.vms) {
-    var i = ob.vms.length;
-    while (i--) {
-      var vm = ob.vms[i];
-      unproxy(vm, key);
-      // vm.$forceUpdate()
-    }
-  }
-}
-
-var KEY_WORDS = ['$index', '$value', '$event'];
-function proxy (vm, key) {
-  if (KEY_WORDS.indexOf(key) > -1 || !isReserved(key)) {
-    Object.defineProperty(vm, key, {
-      configurable: true,
-      enumerable: true,
-      get: function proxyGetter () {
-        return vm._data[key]
-      },
-      set: function proxySetter (val) {
-        vm._data[key] = val;
-      }
-    });
-  }
-}
-
-/* istanbul ignore next */
-function unproxy (vm, key) {
-  if (!isReserved(key)) {
-    delete vm[key];
-  }
-}
-
-/* eslint-disable */
-
-
-function initState (vm) {
-  vm._watchers = [];
-  initData(vm);
-  initComputed(vm);
-  initMethods(vm);
-}
-
-function initData (vm) {
-  var data = vm._data;
-
-  if (!isPlainObject(data)) {
-    data = {};
-  }
-  // proxy data on instance
-  var keys = Object.keys(data);
-  var i = keys.length;
-  while (i--) {
-    proxy(vm, keys[i]);
-  }
-  // observe data
-  observe(data, vm);
-}
-
-/* istanbul ignore next */
-function noop () {
-}
-
-function initComputed (vm) {
-  var computed = vm._computed;
-  if (computed) {
-    for (var key in computed) {
-      var userDef = computed[key];
-      var def$$1 = {
-        enumerable: true,
-        configurable: true
-      };
-      if (typeof userDef === 'function') {
-        def$$1.get = makeComputedGetter(userDef, vm);
-        def$$1.set = noop;
-      } else {
-        def$$1.get = userDef.get
-          ? userDef.cache !== false
-            ? makeComputedGetter(userDef.get, vm)
-            : bind(userDef.get, vm)
-          : noop;
-        def$$1.set = userDef.set
-          ? bind(userDef.set, vm)
-          : noop;
-      }
-      Object.defineProperty(vm, key, def$$1);
-    }
-  }
-}
-
-function makeComputedGetter (getter, owner) {
-  var watcher = new Watcher(owner, getter, null, {
-    lazy: true
-  });
-  return function computedGetter () {
-    if (watcher.dirty) {
-      watcher.evaluate();
-    }
-    if (Dep.target) {
-      watcher.depend();
-    }
-    return watcher.value
-  }
-}
-
-function initMethods (vm) {
-  var methods = vm._methods;
-  if (methods) {
-    for (var key in methods) {
-      vm[key] = methods[key];
-    }
-  }
-}
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-// @todo: It should be registered by native from `registerComponents()`.
-
-var config = {
-  nativeComponentMap: {
-    text: true,
-    image: true,
-    container: true,
-    slider: {
-      type: 'slider',
-      append: 'tree'
-    },
-    cell: {
-      type: 'cell',
-      append: 'tree'
-    }
-  }
-};
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-/**
- * @fileOverview
- * Directive Parser
- */
-
-var nativeComponentMap = config.nativeComponentMap;
-
-var SETTERS = {
-  attr: 'setAttr',
-  style: 'setStyle',
-  event: 'addEvent'
-};
-
-/**
- * apply the native component's options(specified by template.type)
- * to the template
- */
-function applyNaitveComponentOptions (template) {
-  var type = template.type;
-  var options = nativeComponentMap[type];
-
-  if (typeof options === 'object') {
-    for (var key in options) {
-      if (template[key] == null) {
-        template[key] = options[key];
-      }
-      else if (typof(template[key]) === 'object' &&
-        typof(options[key]) === 'object') {
-        for (var subkey in options[key]) {
-          if (template[key][subkey] == null) {
-            template[key][subkey] = options[key][subkey];
-          }
-        }
-      }
-    }
-  }
-}
-
-/**
- * bind all id, attr, classnames, style, events to an element
- */
-function bindElement (vm, el, template) {
-  setId(vm, el, template.id, vm);
-  setAttr(vm, el, template.attr);
-  setClass(vm, el, template.classList);
-  setStyle(vm, el, template.style);
-  bindEvents(vm, el, template.events);
-}
-
-/**
- * bind all props to sub vm and bind all style, events to the root element
- * of the sub vm if it doesn't have a replaced multi-node fragment
- */
-function bindSubVm (vm, subVm, template, repeatItem) {
-  subVm = subVm || {};
-  template = template || {};
-
-  var options = subVm._options || {};
-
-  // bind props
-  var props = options.props;
-
-  if (Array.isArray(props)) {
-    props = props.reduce(function (result, value) {
-      result[value] = true;
-      return result
-    }, {});
-  }
-
-  mergeProps(repeatItem, props, vm, subVm);
-  mergeProps(template.attr, props, vm, subVm);
-}
-
-/**
- * merge class and styles from vm to sub vm.
- */
-function bindSubVmAfterInitialized (vm, subVm, template, target) {
-  if ( target === void 0 ) target = {};
-
-  mergeClassStyle(template.classList, vm, subVm);
-  mergeStyle(template.style, vm, subVm);
-
-  // bind subVm to the target element
-  if (target.children) {
-    target.children[target.children.length - 1]._vm = subVm;
-  }
-  else {
-    target._vm = subVm;
-  }
-}
-
-/**
- * Bind props from vm to sub vm and watch their updates.
- */
-function mergeProps (target, props, vm, subVm) {
-  if (!target) {
-    return
-  }
-  var loop = function ( key ) {
-    if (!props || props[key]) {
-      var value = target[key];
-      if (typeof value === 'function') {
-        var returnValue = watch(vm, value, function (v) {
-          subVm[key] = v;
-        });
-        subVm[key] = returnValue;
-      }
-      else {
-        subVm[key] = value;
-      }
-    }
-  };
-
-  for (var key in target) loop( key );
-}
-
-/**
- * Bind style from vm to sub vm and watch their updates.
- */
-function mergeStyle (target, vm, subVm) {
-  var loop = function ( key ) {
-    var value = target[key];
-    if (typeof value === 'function') {
-      var returnValue = watch(vm, value, function (v) {
-        if (subVm._rootEl) {
-          subVm._rootEl.setStyle(key, v);
-        }
-      });
-      subVm._rootEl.setStyle(key, returnValue);
-    }
-    else {
-      if (subVm._rootEl) {
-        subVm._rootEl.setStyle(key, value);
-      }
-    }
-  };
-
-  for (var key in target) loop( key );
-}
-
-/**
- * Bind class & style from vm to sub vm and watch their updates.
- */
-function mergeClassStyle (target, vm, subVm) {
-  var css = vm._options && vm._options.style || {};
-
-  /* istanbul ignore if */
-  if (!subVm._rootEl) {
-    return
-  }
-
-  var className = '@originalRootEl';
-  css[className] = subVm._rootEl.classStyle;
-
-  function addClassName (list, name) {
-    if (typof(list) === 'array') {
-      list.unshift(name);
-    }
-  }
-
-  if (typeof target === 'function') {
-    var value = watch(vm, target, function (v) {
-      addClassName(v, className);
-      setClassStyle(subVm._rootEl, css, v);
-    });
-    addClassName(value, className);
-    setClassStyle(subVm._rootEl, css, value);
-  }
-  else if (target != null) {
-    addClassName(target, className);
-    setClassStyle(subVm._rootEl, css, target);
-  }
-}
-
-/**
- * bind id to an element
- * each id is unique in a whole vm
- */
-function setId (vm, el, id, target) {
-  var map = Object.create(null);
-
-  Object.defineProperties(map, {
-    vm: {
-      value: target,
-      writable: false,
-      configurable: false
-    },
-    el: {
-      get: function () { return el || target._rootEl; },
-      configurable: false
-    }
-  });
-
-  if (typeof id === 'function') {
-    var handler = id;
-    id = handler.call(vm);
-    if (id || id === 0) {
-      vm._ids[id] = map;
-    }
-    watch(vm, handler, function (newId) {
-      if (newId) {
-        vm._ids[newId] = map;
-      }
-    });
-  }
-  else if (id && typeof id === 'string') {
-    vm._ids[id] = map;
-  }
-}
-
-/**
- * bind attr to an element
- */
-function setAttr (vm, el, attr) {
-  bindDir(vm, el, 'attr', attr);
-}
-
-function setClassStyle (el, css, classList) {
-  if (typeof classList === 'string') {
-    classList = classList.split(/\s+/);
-  }
-  classList.forEach(function (name, i) {
-    classList.splice.apply(classList, [ i, 1 ].concat( name.split(/\s+/) ));
-  });
-  var classStyle = {};
-  var length = classList.length;
-
-  var loop = function ( i ) {
-    var style = css[classList[i]];
-    if (style) {
-      Object.keys(style).forEach(function (key) {
-        classStyle[key] = style[key];
-      });
-    }
-  };
-
-  for (var i = 0; i < length; i++) loop( i );
-  el.setClassStyle(classStyle);
-}
-
-/**
- * bind classnames to an element
- */
-function setClass (vm, el, classList) {
-  if (typeof classList !== 'function' && !Array.isArray(classList)) {
-    return
-  }
-  if (Array.isArray(classList) && !classList.length) {
-    el.setClassStyle({});
-    return
-  }
-
-  var style = vm._options && vm._options.style || {};
-  if (typeof classList === 'function') {
-    var value = watch(vm, classList, function (v) {
-      setClassStyle(el, style, v);
-    });
-    setClassStyle(el, style, value);
-  }
-  else {
-    setClassStyle(el, style, classList);
-  }
-}
-
-/**
- * bind style to an element
- */
-function setStyle (vm, el, style) {
-  bindDir(vm, el, 'style', style);
-}
-
-/**
- * add an event type and handler to an element and generate a dom update
- */
-function setEvent (vm, el, type, handler) {
-  el.addEvent(type, bind(handler, vm));
-}
-
-/**
- * add all events of an element
- */
-function bindEvents (vm, el, events) {
-  if (!events) {
-    return
-  }
-  var keys = Object.keys(events);
-  var i = keys.length;
-  while (i--) {
-    var key = keys[i];
-    var handler = events[key];
-    if (typeof handler === 'string') {
-      handler = vm[handler];
-      /* istanbul ignore if */
-      if (!handler) {
-        console.warn(("[JS Framework] The event handler \"" + handler + "\" is not defined."));
-      }
-    }
-    setEvent(vm, el, key, handler);
-  }
-}
-
-/**
- * set a series of members as a kind of an element
- * for example: style, attr, ...
- * if the value is a function then bind the data changes
- */
-function bindDir (vm, el, name, data) {
-  if (!data) {
-    return
-  }
-  var keys = Object.keys(data);
-  var i = keys.length;
-  while (i--) {
-    var key = keys[i];
-    var value = data[key];
-    if (typeof value === 'function') {
-      bindKey(vm, el, name, key, value);
-    }
-    else {
-      el[SETTERS[name]](key, value);
-    }
-  }
-}
-
-/**
- * bind data changes to a certain key to a name series in an element
- */
-function bindKey (vm, el, name, key, calc) {
-  var methodName = SETTERS[name];
-  // watch the calc, and returns a value by calc.call()
-  var value = watch(vm, calc, function (value) {
-    function handler () {
-      el[methodName](key, value);
-    }
-    var differ = vm && vm._app && vm._app.differ;
-    if (differ) {
-      differ.append('element', el.depth, el.ref, handler);
-    }
-    else {
-      handler();
-    }
-  });
-
-  el[methodName](key, value);
-}
-
-/**
- * watch a calc function and callback if the calc value changes
- */
-function watch (vm, calc, callback) {
-  if (vm._static) {
-    return calc.call(vm, vm)
-  }
-  var watcher = new Watcher(vm, calc, function (value, oldValue) {
-    /* istanbul ignore if */
-    if (typeof value !== 'object' && value === oldValue) {
-      return
-    }
-    callback(value);
-  });
-
-  return watcher.value
-}
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-/**
- * @fileOverview Document & Element Helpers.
- *
- * required:
- * Document#: createElement, createComment, getRef
- * Element#: appendChild, insertBefore, removeChild, nextSibling
- */
-
-/**
- * Create a body by type
- * Using this._app.doc
- *
- * @param  {string} type
- */
-function createBody (vm, type) {
-  var doc = vm._app.doc;
-  return doc.createBody(type)
-}
-
-/**
- * Create an element by type
- * Using this._app.doc
- *
- * @param  {string} type
- */
-function createElement (vm, type) {
-  var doc = vm._app.doc;
-  return doc.createElement(type)
-}
-
-/**
- * Create and return a frag block for an element.
- * The frag block has a starter, ender and the element itself.
- *
- * @param  {object} element
- */
-function createBlock (vm, element) {
-  var start = createBlockStart(vm);
-  var end = createBlockEnd(vm);
-  var blockId = lastestBlockId++;
-  if (element.element) {
-    var updateMark = element.updateMark;
-    if (updateMark) {
-      if (updateMark.element) {
-        updateMark = updateMark.end;
-      }
-      element.element.insertAfter(end, updateMark);
-      element.element.insertAfter(start, updateMark);
-      element.updateMark = end;
-    }
-    else {
-      element.element.insertBefore(start, element.end);
-      element.element.insertBefore(end, element.end);
-    }
-    element = element.element;
-  }
-  else {
-    element.appendChild(start);
-    element.appendChild(end);
-  }
-  return { start: start, end: end, element: element, blockId: blockId }
-}
-
-var lastestBlockId = 1;
-
-/**
- * Create and return a block starter.
- * Using this._app.doc
- */
-function createBlockStart (vm) {
-  var doc = vm._app.doc;
-  var anchor = doc.createComment('start');
-  return anchor
-}
-
-/**
- * Create and return a block ender.
- * Using this._app.doc
- */
-function createBlockEnd (vm) {
-  var doc = vm._app.doc;
-  var anchor = doc.createComment('end');
-  return anchor
-}
-
-/**
- * Attach target to a certain dest using appendChild by default.
- * If the dest is a frag block then insert before the ender.
- * If the target is a frag block then attach the starter and ender in order.
- *
- * @param  {object} target
- * @param  {object} dest
- */
-function attachTarget (vm, target, dest) {
-  if (dest.element) {
-    var before = dest.end;
-    var after = dest.updateMark;
-    // push new target for watch list update later
-    if (dest.children) {
-      dest.children.push(target);
-    }
-    // for check repeat case
-    if (after) {
-      var signal = moveTarget(vm, target, after);
-      dest.updateMark = target.element ? target.end : target;
-      return signal
-    }
-    else if (target.element) {
-      dest.element.insertBefore(target.start, before);
-      dest.element.insertBefore(target.end, before);
-    }
-    else {
-      return dest.element.insertBefore(target, before)
-    }
-  }
-  else {
-    if (target.element) {
-      dest.appendChild(target.start);
-      dest.appendChild(target.end);
-    }
-    else {
-      return dest.appendChild(target)
-    }
-  }
-}
-
-/**
- * Move target before a certain element. The target maybe block or element.
- *
- * @param  {object} target
- * @param  {object} before
- */
-function moveTarget (vm, target, after) {
-  if (target.element) {
-    return moveBlock(target, after)
-  }
-  return moveElement(target, after)
-}
-
-/**
- * Move element before a certain element.
- *
- * @param  {object} element
- * @param  {object} before
- */
-function moveElement (element, after) {
-  var parent = after.parentNode;
-  if (parent) {
-    return parent.insertAfter(element, after)
-  }
-}
-
-/**
- * Move all elements of the block before a certain element.
- *
- * @param  {object} fragBlock
- * @param  {object} before
- */
-function moveBlock (fragBlock, after) {
-  var parent = after.parentNode;
-
-  if (parent) {
-    var el = fragBlock.start;
-    var signal;
-    var group = [el];
-
-    while (el && el !== fragBlock.end) {
-      el = el.nextSibling;
-      group.push(el);
-    }
-
-    var temp = after;
-    group.every(function (el) {
-      signal = parent.insertAfter(el, temp);
-      temp = el;
-      return signal !== -1
-    });
-
-    return signal
-  }
-}
-
-/**
- * Remove target from DOM tree.
- * If the target is a frag block then call _removeBlock
- *
- * @param  {object} target
- */
-function removeTarget (vm, target, preserveBlock) {
-  if ( preserveBlock === void 0 ) preserveBlock = false;
-
-  if (target.element) {
-    removeBlock(target, preserveBlock);
-  }
-  else {
-    removeElement(target);
-  }
-  if (target._vm) {
-    target._vm.$emit('hook:destroyed');
-  }
-}
-
-/**
- * Remove a certain element.
- * Using this._app.doc
- *
- * @param  {object} target
- */
-function removeElement (target) {
-  var parent = target.parentNode;
-
-  if (parent) {
-    parent.removeChild(target);
-  }
-}
-
-/**
- * Remove a frag block.
- * The second param decides whether the block self should be removed too.
- *
- * @param  {object}  fragBlock
- * @param  {Boolean} preserveBlock=false
- */
-function removeBlock (fragBlock, preserveBlock) {
-  if ( preserveBlock === void 0 ) preserveBlock = false;
-
-  var result = [];
-  var el = fragBlock.start.nextSibling;
-
-  while (el && el !== fragBlock.end) {
-    result.push(el);
-    el = el.nextSibling;
-  }
-
-  if (!preserveBlock) {
-    removeElement(fragBlock.start);
-  }
-  result.forEach(function (el) {
-    removeElement(el);
-  });
-  if (!preserveBlock) {
-    removeElement(fragBlock.end);
-  }
-}
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-/**
- * @fileOverview
- * ViewModel template parser & data-binding process
- */
-
-/**
- * build()
- *   compile(template, parentNode)
- *     if (type is content) create contentNode
- *     else if (dirs have v-for) foreach -> create context
- *       -> compile(templateWithoutFor, parentNode): diff(list) onchange
- *     else if (dirs have v-if) assert
- *       -> compile(templateWithoutIf, parentNode): toggle(shown) onchange
- *     else if (type is dynamic)
- *       -> compile(templateWithoutDynamicType, parentNode): watch(type) onchange
- *     else if (type is custom)
- *       addChildVm(vm, parentVm)
- *       build(externalDirs)
- *       foreach childNodes -> compile(childNode, template)
- *     else if (type is native)
- *       set(dirs): update(id/attr/style/class) onchange
- *       append(template, parentNode)
- *       foreach childNodes -> compile(childNode, template)
- */
-function build (vm) {
-  var opt = vm._options || {};
-  var template = opt.template || {};
-
-  if (opt.replace) {
-    if (template.children && template.children.length === 1) {
-      compile(vm, template.children[0], vm._parentEl);
-    }
-    else {
-      compile(vm, template.children, vm._parentEl);
-    }
-  }
-  else {
-    compile(vm, template, vm._parentEl);
-  }
-
-  console.debug(("[JS Framework] \"ready\" lifecycle in Vm(" + (vm._type) + ")"));
-  vm.$emit('hook:ready');
-  vm._ready = true;
-}
-
-/**
- * Generate elements by child or children and append to parent elements.
- * Root element info would be merged if has. The first argument may be an array
- * if the root element with options.replace has not only one child.
- *
- * @param {object|array} target
- * @param {object}       dest
- * @param {object}       meta
- */
-function compile (vm, target, dest, meta) {
-  var app = vm._app || {};
-
-  if (app.lastSignal === -1) {
-    return
-  }
-
-  if (target.attr && target.attr.hasOwnProperty('static')) {
-    vm._static = true;
-  }
-
-  if (targetIsFragment(target)) {
-    compileFragment(vm, target, dest, meta);
-    return
-  }
-  meta = meta || {};
-  if (targetIsContent(target)) {
-    console.debug('[JS Framework] compile "content" block by', target);
-    vm._content = createBlock(vm, dest);
-    return
-  }
-
-  if (targetNeedCheckRepeat(target, meta)) {
-    console.debug('[JS Framework] compile "repeat" logic by', target);
-    if (dest.type === 'document') {
-      console.warn('[JS Framework] The root element does\'t support `repeat` directive!');
-    }
-    else {
-      compileRepeat(vm, target, dest);
-    }
-    return
-  }
-  if (targetNeedCheckShown(target, meta)) {
-    console.debug('[JS Framework] compile "if" logic by', target);
-    if (dest.type === 'document') {
-      console.warn('[JS Framework] The root element does\'t support `if` directive!');
-    }
-    else {
-      compileShown(vm, target, dest, meta);
-    }
-    return
-  }
-  var typeGetter = meta.type || target.type;
-  if (targetNeedCheckType(typeGetter, meta)) {
-    compileType(vm, target, dest, typeGetter, meta);
-    return
-  }
-  var type = typeGetter;
-  var component = targetIsComposed(vm, target, type);
-  if (component) {
-    console.debug('[JS Framework] compile composed component by', target);
-    compileCustomComponent(vm, component, target, dest, type, meta);
-    return
-  }
-  console.debug('[JS Framework] compile native component by', target);
-  compileNativeComponent(vm, target, dest, type);
-}
-
-/**
- * Check if target is a fragment (an array).
- *
- * @param  {object}  target
- * @return {boolean}
- */
-function targetIsFragment (target) {
-  return Array.isArray(target)
-}
-
-/**
- * Check if target type is content/slot.
- *
- * @param  {object}  target
- * @return {boolean}
- */
-function targetIsContent (target) {
-  return target.type === 'content' || target.type === 'slot'
-}
-
-/**
- * Check if target need to compile by a list.
- *
- * @param  {object}  target
- * @param  {object}  meta
- * @return {boolean}
- */
-function targetNeedCheckRepeat (target, meta) {
-  return !meta.hasOwnProperty('repeat') && target.repeat
-}
-
-/**
- * Check if target need to compile by a boolean value.
- *
- * @param  {object}  target
- * @param  {object}  meta
- * @return {boolean}
- */
-function targetNeedCheckShown (target, meta) {
-  return !meta.hasOwnProperty('shown') && target.shown
-}
-
-/**
- * Check if target need to compile by a dynamic type.
- *
- * @param  {string|function} typeGetter
- * @param  {object}          meta
- * @return {boolean}
- */
-function targetNeedCheckType (typeGetter, meta) {
-  return (typeof typeGetter === 'function') && !meta.hasOwnProperty('type')
-}
-
-/**
- * Check if this kind of component is composed.
- *
- * @param  {string}  type
- * @return {boolean}
- */
-function targetIsComposed (vm, target, type) {
-  var component;
-  if (vm._app && vm._app.customComponentMap) {
-    component = vm._app.customComponentMap[type];
-  }
-  if (vm._options && vm._options.components) {
-    component = vm._options.components[type];
-  }
-  if (target.component) {
-    component = component || {};
-  }
-  return component
-}
-
-/**
- * Compile a list of targets.
- *
- * @param {object} target
- * @param {object} dest
- * @param {object} meta
- */
-function compileFragment (vm, target, dest, meta) {
-  var fragBlock = createBlock(vm, dest);
-  target.forEach(function (child) {
-    compile(vm, child, fragBlock, meta);
-  });
-}
-
-/**
- * Compile a target with repeat directive.
- *
- * @param {object} target
- * @param {object} dest
- */
-function compileRepeat (vm, target, dest) {
-  var repeat = target.repeat;
-  var oldStyle = typeof repeat === 'function';
-  var getter = repeat.getter || repeat.expression || repeat;
-  if (typeof getter !== 'function') {
-    getter = function () { return [] };
-  }
-  var key = repeat.key || '$index';
-  var value = repeat.value || '$value';
-  var trackBy = repeat.trackBy || target.trackBy ||
-    (target.attr && target.attr.trackBy);
-
-  var fragBlock = createBlock(vm, dest);
-  fragBlock.children = [];
-  fragBlock.data = [];
-  fragBlock.vms = [];
-
-  bindRepeat(vm, target, fragBlock, { getter: getter, key: key, value: value, trackBy: trackBy, oldStyle: oldStyle });
-}
-
-/**
- * Compile a target with if directive.
- *
- * @param {object} target
- * @param {object} dest
- * @param {object} meta
- */
-function compileShown (vm, target, dest, meta) {
-  var newMeta = { shown: true };
-  var fragBlock = createBlock(vm, dest);
-
-  if (dest.element && dest.children) {
-    dest.children.push(fragBlock);
-  }
-
-  if (meta.repeat) {
-    newMeta.repeat = meta.repeat;
-  }
-
-  bindShown(vm, target, fragBlock, newMeta);
-}
-
-/**
- * Compile a target with dynamic component type.
- *
- * @param {object}   target
- * @param {object}   dest
- * @param {function} typeGetter
- */
-function compileType (vm, target, dest, typeGetter, meta) {
-  var type = typeGetter.call(vm);
-  var newMeta = extend({ type: type }, meta);
-  var fragBlock = createBlock(vm, dest);
-
-  if (dest.element && dest.children) {
-    dest.children.push(fragBlock);
-  }
-
-  watch(vm, typeGetter, function (value) {
-    var newMeta = extend({ type: value }, meta);
-    removeTarget(vm, fragBlock, true);
-    compile(vm, target, fragBlock, newMeta);
-  });
-
-  compile(vm, target, fragBlock, newMeta);
-}
-
-/**
- * Compile a composed component.
- *
- * @param {object} target
- * @param {object} dest
- * @param {string} type
- */
-function compileCustomComponent (vm, component, target, dest, type, meta) {
-  var Ctor = vm.constructor;
-  var subVm = new Ctor(type, component, vm, dest, undefined, {
-    'hook:init': function () {
-      if (vm._static) {
-        this._static = vm._static;
-      }
-      setId(vm, null, target.id, this);
-      // bind template earlier because of lifecycle issues
-      this._externalBinding = {
-        parent: vm,
-        template: target
-      };
-    },
-    'hook:created': function () {
-      bindSubVm(vm, this, target, meta.repeat);
-    },
-    'hook:ready': function () {
-      if (this._content) {
-        compileChildren(vm, target, this._content);
-      }
-    }
-  });
-  bindSubVmAfterInitialized(vm, subVm, target, dest);
-}
-
-/**
- * Generate element from template and attach to the dest if needed.
- * The time to attach depends on whether the mode status is node or tree.
- *
- * @param {object} template
- * @param {object} dest
- * @param {string} type
- */
-function compileNativeComponent (vm, template, dest, type) {
-  applyNaitveComponentOptions(template);
-
-  var element;
-  if (dest.ref === '_documentElement') {
-    // if its parent is documentElement then it's a body
-    console.debug(("[JS Framework] compile to create body for " + type));
-    element = createBody(vm, type);
-  }
-  else {
-    console.debug(("[JS Framework] compile to create element for " + type));
-    element = createElement(vm, type);
-  }
-
-  if (!vm._rootEl) {
-    vm._rootEl = element;
-    // bind event earlier because of lifecycle issues
-    var binding = vm._externalBinding || {};
-    var target = binding.template;
-    var parentVm = binding.parent;
-    if (target && target.events && parentVm && element) {
-      for (var type$1 in target.events) {
-        var handler = parentVm[target.events[type$1]];
-        if (handler) {
-          element.addEvent(type$1, bind(handler, parentVm));
-        }
-      }
-    }
-  }
-
-  bindElement(vm, element, template);
-
-  if (template.attr && template.attr.append) { // backward, append prop in attr
-    template.append = template.attr.append;
-  }
-
-  if (template.append) { // give the append attribute for ios adaptation
-    element.attr = element.attr || {};
-    element.attr.append = template.append;
-  }
-
-  var treeMode = template.append === 'tree';
-  var app = vm._app || {};
-  if (app.lastSignal !== -1 && !treeMode) {
-    console.debug('[JS Framework] compile to append single node for', element);
-    app.lastSignal = attachTarget(vm, element, dest);
-  }
-  if (app.lastSignal !== -1) {
-    compileChildren(vm, template, element);
-  }
-  if (app.lastSignal !== -1 && treeMode) {
-    console.debug('[JS Framework] compile to append whole tree for', element);
-    app.lastSignal = attachTarget(vm, element, dest);
-  }
-}
-
-/**
- * Set all children to a certain parent element.
- *
- * @param {object} template
- * @param {object} dest
- */
-function compileChildren (vm, template, dest) {
-  var app = vm._app || {};
-  var children = template.children;
-  if (children && children.length) {
-    children.every(function (child) {
-      compile(vm, child, dest);
-      return app.lastSignal !== -1
-    });
-  }
-}
-
-/**
- * Watch the list update and refresh the changes.
- *
- * @param {object} target
- * @param {object} fragBlock {vms, data, children}
- * @param {object} info      {getter, key, value, trackBy, oldStyle}
- */
-function bindRepeat (vm, target, fragBlock, info) {
-  var vms = fragBlock.vms;
-  var children = fragBlock.children;
-  var getter = info.getter;
-  var trackBy = info.trackBy;
-  var oldStyle = info.oldStyle;
-  var keyName = info.key;
-  var valueName = info.value;
-
-  function compileItem (item, index, context) {
-    var mergedData;
-    if (oldStyle) {
-      mergedData = item;
-      if (isObject(item)) {
-        mergedData[keyName] = index;
-        if (!mergedData.hasOwnProperty('INDEX')) {
-          Object.defineProperty(mergedData, 'INDEX', {
-            value: function () {
-              console.warn('[JS Framework] "INDEX" in repeat is deprecated, ' +
-                'please use "$index" instead');
-            }
-          });
-        }
-      }
-      else {
-        console.warn('[JS Framework] Each list item must be an object in old-style repeat, '
-          + 'please use `repeat={{v in list}}` instead.');
-        mergedData = {};
-        mergedData[keyName] = index;
-        mergedData[valueName] = item;
-      }
-    }
-    else {
-      mergedData = {};
-      mergedData[keyName] = index;
-      mergedData[valueName] = item;
-    }
-    var newContext = mergeContext(context, mergedData);
-    vms.push(newContext);
-    compile(newContext, target, fragBlock, { repeat: item });
-  }
-
-  var list = watchBlock(vm, fragBlock, getter, 'repeat',
-    function (data) {
-      console.debug('[JS Framework] the "repeat" item has changed', data);
-      if (!fragBlock || !data) {
-        return
-      }
-
-      var oldChildren = children.slice();
-      var oldVms = vms.slice();
-      var oldData = fragBlock.data.slice();
-      // 1. collect all new refs track by
-      var trackMap = {};
-      var reusedMap = {};
-      data.forEach(function (item, index) {
-        var key = trackBy ? item[trackBy] : (oldStyle ? item[keyName] : index);
-        /* istanbul ignore if */
-        if (key == null || key === '') {
-          return
-        }
-        trackMap[key] = item;
-      });
-
-      // 2. remove unused element foreach old item
-      var reusedList = [];
-      oldData.forEach(function (item, index) {
-        var key = trackBy ? item[trackBy] : (oldStyle ? item[keyName] : index);
-        if (trackMap.hasOwnProperty(key)) {
-          reusedMap[key] = {
-            item: item, index: index, key: key,
-            target: oldChildren[index],
-            vm: oldVms[index]
-          };
-          reusedList.push(item);
-        }
-        else {
-          removeTarget(vm, oldChildren[index]);
-        }
-      });
-
-      // 3. create new element foreach new item
-      children.length = 0;
-      vms.length = 0;
-      fragBlock.data = data.slice();
-      fragBlock.updateMark = fragBlock.start;
-
-      data.forEach(function (item, index) {
-        var key = trackBy ? item[trackBy] : (oldStyle ? item[keyName] : index);
-        var reused = reusedMap[key];
-        if (reused) {
-          if (reused.item === reusedList[0]) {
-            reusedList.shift();
-          }
-          else {
-            reusedList.$remove(reused.item);
-            moveTarget(vm, reused.target, fragBlock.updateMark, true);
-          }
-          children.push(reused.target);
-          vms.push(reused.vm);
-          if (oldStyle) {
-            reused.vm = item;
-          }
-          else {
-            reused.vm[valueName] = item;
-          }
-          reused.vm[keyName] = index;
-          fragBlock.updateMark = reused.target;
-        }
-        else {
-          compileItem(item, index, vm);
-        }
-      });
-
-      delete fragBlock.updateMark;
-    }
-  );
-
-  fragBlock.data = list.slice(0);
-  list.forEach(function (item, index) {
-    compileItem(item, index, vm);
-  });
-}
-
-/**
- * Watch the display update and add/remove the element.
- *
- * @param  {object} target
- * @param  {object} fragBlock
- * @param  {object} context
- */
-function bindShown (vm, target, fragBlock, meta) {
-  var display = watchBlock(vm, fragBlock, target.shown, 'shown',
-    function (display) {
-      console.debug('[JS Framework] the "if" item was changed', display);
-
-      if (!fragBlock || !!fragBlock.display === !!display) {
-        return
-      }
-      fragBlock.display = !!display;
-      if (display) {
-        compile(vm, target, fragBlock, meta);
-      }
-      else {
-        removeTarget(vm, fragBlock, true);
-      }
-    }
-  );
-
-  fragBlock.display = !!display;
-  if (display) {
-    compile(vm, target, fragBlock, meta);
-  }
-}
-
-/**
- * Watch calc value changes and append certain type action to differ.
- * It is used for if or repeat data-binding generator.
- *
- * @param  {object}   fragBlock
- * @param  {function} calc
- * @param  {string}   type
- * @param  {function} handler
- * @return {any}      init value of calc
- */
-function watchBlock (vm, fragBlock, calc, type, handler) {
-  var differ = vm && vm._app && vm._app.differ;
-  var config = {};
-  var depth = (fragBlock.element.depth || 0) + 1;
-
-  return watch(vm, calc, function (value) {
-    config.latestValue = value;
-    if (differ && !config.recorded) {
-      differ.append(type, depth, fragBlock.blockId, function () {
-        var latestValue = config.latestValue;
-        handler(latestValue);
-        config.recorded = false;
-        config.latestValue = undefined;
-      });
-    }
-    config.recorded = true;
-  })
-}
-
-/**
- * Clone a context and merge certain data.
- *
- * @param  {object} mergedData
- * @return {object}
- */
-function mergeContext (context, mergedData) {
-  var newContext = Object.create(context);
-  newContext._data = mergedData;
-  initData(newContext);
-  initComputed(newContext);
-  newContext._realParent = context;
-  if (context._static) {
-    newContext._static = context._static;
-  }
-  return newContext
-}
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-/**
- * @fileOverview
- * Everything about component event which includes event object, event listener,
- * event emitter and lifecycle hooks.
- */
-
-/**
- * Event object definition. An event object has `type`, `timestamp` and
- * `detail` from which a component emit. The event object could be dispatched to
- * parents or broadcasted to children except `this.stop()` is called.
- * @param {string} type
- * @param {any}    detail
- */
-function Evt (type, detail) {
-  if (detail instanceof Evt) {
-    return detail
-  }
-
-  this.timestamp = Date.now();
-  this.detail = detail;
-  this.type = type;
-
-  var shouldStop = false;
-
-  /**
-   * stop dispatch and broadcast
-   */
-  this.stop = function () {
-    shouldStop = true;
-  };
-
-  /**
-   * check if it can't be dispatched or broadcasted
-   */
-  this.hasStopped = function () {
-    return shouldStop
-  };
-}
-
-/**
- * Emit an event but not broadcast down or dispatch up.
- * @param  {string} type
- * @param  {any}    detail
- */
-function $emit (type, detail) {
-  var this$1 = this;
-
-  var events = this._vmEvents;
-  var handlerList = events[type];
-  if (handlerList) {
-    var evt = new Evt(type, detail);
-    handlerList.forEach(function (handler) {
-      handler.call(this$1, evt);
-    });
-  }
-}
-
-/**
- * Emit an event and dispatch it up.
- * @param  {string} type
- * @param  {any}    detail
- */
-function $dispatch (type, detail) {
-  var evt = new Evt(type, detail);
-  this.$emit(type, evt);
-
-  if (!evt.hasStopped() && this._parent && this._parent.$dispatch) {
-    this._parent.$dispatch(type, evt);
-  }
-}
-
-/**
- * Emit an event and broadcast it down.
- * @param  {string} type
- * @param  {any}    detail
- */
-function $broadcast (type, detail) {
-  var evt = new Evt(type, detail);
-  this.$emit(type, evt);
-
-  if (!evt.hasStopped() && this._childrenVms) {
-    this._childrenVms.forEach(function (subVm) {
-      subVm.$broadcast(type, evt);
-    });
-  }
-}
-
-/**
- * Add event listener.
- * @param  {string}   type
- * @param  {function} handler
- */
-function $on (type, handler) {
-  if (!type || typeof handler !== 'function') {
-    return
-  }
-  var events = this._vmEvents;
-  var handlerList = events[type] || [];
-  handlerList.push(handler);
-  events[type] = handlerList;
-
-  // fixed old version lifecycle design
-  /* istanbul ignore if */
-  if (type === 'hook:ready' && this._ready) {
-    this.$emit('hook:ready');
-  }
-}
-
-/**
- * Remove event listener.
- * @param  {string}   type
- * @param  {function} handler
- */
-function $off (type, handler) {
-  if (!type) {
-    return
-  }
-  var events = this._vmEvents;
-  if (!handler) {
-    delete events[type];
-    return
-  }
-  var handlerList = events[type];
-  if (!handlerList) {
-    return
-  }
-  handlerList.$remove(handler);
-}
-
-var LIFE_CYCLE_TYPES = ['init', 'created', 'ready', 'destroyed'];
-
-/**
- * Init events:
- * 1. listen `events` in component options & `externalEvents`.
- * 2. bind lifecycle hooks.
- * @param  {Vm}     vm
- * @param  {object} externalEvents
- */
-function initEvents (vm, externalEvents) {
-  var options = vm._options || {};
-  var events = options.events || {};
-  for (var type1 in events) {
-    vm.$on(type1, events[type1]);
-  }
-  for (var type2 in externalEvents) {
-    vm.$on(type2, externalEvents[type2]);
-  }
-  LIFE_CYCLE_TYPES.forEach(function (type) {
-    vm.$on(("hook:" + type), options[type]);
-  });
-}
-
-/**
- * Bind event related methods to ViewModel instance.
- * @param  {Vm} vm
- */
-function mixinEvents (vm) {
-  vm.$emit = $emit;
-  vm.$dispatch = $dispatch;
-  vm.$broadcast = $broadcast;
-  vm.$on = $on;
-  vm.$off = $off;
-}
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-/**
- * @fileOverview
- * ViewModel Constructor & definition
- */
-
-/**
- * ViewModel constructor
- *
- * @param {string} type
- * @param {object} options    component options
- * @param {object} parentVm   which contains _app
- * @param {object} parentEl   root element or frag block
- * @param {object} mergedData external data
- * @param {object} externalEvents external events
- */
-function Vm (
-  type,
-  options,
-  parentVm,
-  parentEl,
-  mergedData,
-  externalEvents
-) {
-  parentVm = parentVm || {};
-  this._parent = parentVm._realParent ? parentVm._realParent : parentVm;
-  this._app = parentVm._app || {};
-  parentVm._childrenVms && parentVm._childrenVms.push(this);
-
-  if (!options && this._app.customComponentMap) {
-    options = this._app.customComponentMap[type];
-  }
-  options = options || {};
-
-  var data = options.data || {};
-
-  this._options = options;
-  this._methods = options.methods || {};
-  this._computed = options.computed || {};
-  this._css = options.style || {};
-  this._ids = {};
-  this._vmEvents = {};
-  this._childrenVms = [];
-  this._type = type;
-
-  // bind events and lifecycles
-  initEvents(this, externalEvents);
-
-  console.debug(("[JS Framework] \"init\" lifecycle in Vm(" + (this._type) + ")"));
-  this.$emit('hook:init');
-  this._inited = true;
-
-  // proxy data and methods
-  // observe data and add this to vms
-  this._data = typeof data === 'function' ? data() : data;
-  if (mergedData) {
-    extend(this._data, mergedData);
-  }
-  initState(this);
-
-  console.debug(("[JS Framework] \"created\" lifecycle in Vm(" + (this._type) + ")"));
-  this.$emit('hook:created');
-  this._created = true;
-
-  // backward old ready entry
-  if (options.methods && options.methods.ready) {
-    console.warn('"exports.methods.ready" is deprecated, ' +
-      'please use "exports.created" instead');
-    options.methods.ready.call(this);
-  }
-
-  if (!this._app.doc) {
-    return
-  }
-
-  // if no parentElement then specify the documentElement
-  this._parentEl = parentEl || this._app.doc.documentElement;
-  build(this);
-}
-
-mixinEvents(Vm.prototype);
-
-/**
- * Watch an function and bind all the data appeared in it. When the related
- * data changes, the callback will be called with new value as 1st param.
- *
- * @param {Function} fn
- * @param {Function} callback
- */
-Vm.prototype.$watch = function (fn, callback) {
-  watch(this, fn, callback);
-};
-
-Vm.set = set;
-Vm.delete = del;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-var nativeModules = {};
-
-// for testing
-
-/**
- * for testing
- */
-
-
-/**
- * for testing
- */
-
-
-// for framework
-
-/**
- * init modules for an app instance
- * the second param determines whether to replace an existed method
- */
-function initModules (modules, ifReplace) {
-  var loop = function ( moduleName ) {
-    // init `modules[moduleName][]`
-    var methods = nativeModules[moduleName];
-    if (!methods) {
-      methods = {};
-      nativeModules[moduleName] = methods;
-    }
-
-    // push each non-existed new method
-    modules[moduleName].forEach(function (method) {
-      if (typeof method === 'string') {
-        method = {
-          name: method
-        };
-      }
-
-      if (!methods[method.name] || ifReplace) {
-        methods[method.name] = method;
-      }
-    });
-  };
-
-  for (var moduleName in modules) loop( moduleName );
-}
-
-/**
- * init app methods
- */
-function initMethods$1 (Vm, apis) {
-  var p = Vm.prototype;
-
-  for (var apiName in apis) {
-    if (!p.hasOwnProperty(apiName)) {
-      p[apiName] = apis[apiName];
-    }
-  }
-}
-
-/**
- * get a module of methods for an app instance
- */
-function requireModule (app, name) {
-  var methods = nativeModules[name];
-  var target = {};
-  var loop = function ( methodName ) {
-    Object.defineProperty(target, methodName, {
-      configurable: true,
-      enumerable: true,
-      get: function moduleGetter () {
-        return function () {
-          var args = [], len = arguments.length;
-          while ( len-- ) args[ len ] = arguments[ len ];
-
-          return app.callTasks({
-          module: name,
-          method: methodName,
-          args: args
-        });
-        }
-      },
-      set: function moduleSetter (value) {
-        if (typeof value === 'function') {
-          return app.callTasks({
-            module: name,
-            method: methodName,
-            args: [value]
-          })
-        }
-      }
-    });
-  };
-
-  for (var methodName in methods) loop( methodName );
-  return target
-}
-
-/**
- * get a custom component options
- */
-function requireCustomComponent (app, name) {
-  var customComponentMap = app.customComponentMap;
-  return customComponentMap[name]
-}
-
-/**
- * register a custom component options
- */
-function registerCustomComponent (app, name, def) {
-  var customComponentMap = app.customComponentMap;
-
-  if (customComponentMap[name]) {
-    console.error(("[JS Framework] define a component(" + name + ") that already exists"));
-    return
-  }
-
-  customComponentMap[name] = def;
-}
-
-function createCommonjsModule(fn, module) {
-	return module = { exports: {} }, fn(module, module.exports), module.exports;
-}
-
-var semver = createCommonjsModule(function (module, exports) {
-exports = module.exports = SemVer;
-
-// The debug function is excluded entirely from the minified version.
-/* nomin */ var debug;
-/* nomin */ if (typeof process === 'object' &&
-    /* nomin */ process.env &&
-    /* nomin */ false &&
-    /* nomin */ /\bsemver\b/i.test(false))
-  /* nomin */ { debug = function() {
-    /* nomin */ var args = Array.prototype.slice.call(arguments, 0);
-    /* nomin */ args.unshift('SEMVER');
-    /* nomin */ console.log.apply(console, args);
-    /* nomin */ }; }
-/* nomin */ else
-  /* nomin */ { debug = function() {}; }
-
-// Note: this is the semver.org version of the spec that it implements
-// Not necessarily the package version of this code.
-exports.SEMVER_SPEC_VERSION = '2.0.0';
-
-var MAX_LENGTH = 256;
-var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991;
-
-// The actual regexps go on exports.re
-var re = exports.re = [];
-var src = exports.src = [];
-var R = 0;
-
-// The following Regular Expressions can be used for tokenizing,
-// validating, and parsing SemVer version strings.
-
-// ## Numeric Identifier
-// A single `0`, or a non-zero digit followed by zero or more digits.
-
-var NUMERICIDENTIFIER = R++;
-src[NUMERICIDENTIFIER] = '0|[1-9]\\d*';
-var NUMERICIDENTIFIERLOOSE = R++;
-src[NUMERICIDENTIFIERLOOSE] = '[0-9]+';
-
-
-// ## Non-numeric Identifier
-// Zero or more digits, followed by a letter or hyphen, and then zero or
-// more letters, digits, or hyphens.
-
-var NONNUMERICIDENTIFIER = R++;
-src[NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*';
-
-
-// ## Main Version
-// Three dot-separated numeric identifiers.
-
-var MAINVERSION = R++;
-src[MAINVERSION] = '(' + src[NUMERICIDENTIFIER] + ')\\.' +
-                   '(' + src[NUMERICIDENTIFIER] + ')\\.' +
-                   '(' + src[NUMERICIDENTIFIER] + ')';
-
-var MAINVERSIONLOOSE = R++;
-src[MAINVERSIONLOOSE] = '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' +
-                        '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' +
-                        '(' + src[NUMERICIDENTIFIERLOOSE] + ')';
-
-// ## Pre-release Version Identifier
-// A numeric identifier, or a non-numeric identifier.
-
-var PRERELEASEIDENTIFIER = R++;
-src[PRERELEASEIDENTIFIER] = '(?:' + src[NUMERICIDENTIFIER] +
-                            '|' + src[NONNUMERICIDENTIFIER] + ')';
-
-var PRERELEASEIDENTIFIERLOOSE = R++;
-src[PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[NUMERICIDENTIFIERLOOSE] +
-                                 '|' + src[NONNUMERICIDENTIFIER] + ')';
-
-
-// ## Pre-release Version
-// Hyphen, followed by one or more dot-separated pre-release version
-// identifiers.
-
-var PRERELEASE = R++;
-src[PRERELEASE] = '(?:-(' + src[PRERELEASEIDENTIFIER] +
-                  '(?:\\.' + src[PRERELEASEIDENTIFIER] + ')*))';
-
-var PRERELEASELOOSE = R++;
-src[PRERELEASELOOSE] = '(?:-?(' + src[PRERELEASEIDENTIFIERLOOSE] +
-                       '(?:\\.' + src[PRERELEASEIDENTIFIERLOOSE] + ')*))';
-
-// ## Build Metadata Identifier
-// Any combination of digits, letters, or hyphens.
-
-var BUILDIDENTIFIER = R++;
-src[BUILDIDENTIFIER] = '[0-9A-Za-z-]+';
-
-// ## Build Metadata
-// Plus sign, followed by one or more period-separated build metadata
-// identifiers.
-
-var BUILD = R++;
-src[BUILD] = '(?:\\+(' + src[BUILDIDENTIFIER] +
-             '(?:\\.' + src[BUILDIDENTIFIER] + ')*))';
-
-
-// ## Full Version String
-// A main version, followed optionally by a pre-release version and
-// build metadata.
-
-// Note that the only major, minor, patch, and pre-release sections of
-// the version string are capturing groups.  The build metadata is not a
-// capturing group, because it should not ever be used in version
-// comparison.
-
-var FULL = R++;
-var FULLPLAIN = 'v?' + src[MAINVERSION] +
-                src[PRERELEASE] + '?' +
-                src[BUILD] + '?';
-
-src[FULL] = '^' + FULLPLAIN + '$';
-
-// like full, but allows v1.2.3 and =1.2.3, which people do sometimes.
-// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty
-// common in the npm registry.
-var LOOSEPLAIN = '[v=\\s]*' + src[MAINVERSIONLOOSE] +
-                 src[PRERELEASELOOSE] + '?' +
-                 src[BUILD] + '?';
-
-var LOOSE = R++;
-src[LOOSE] = '^' + LOOSEPLAIN + '$';
-
-var GTLT = R++;
-src[GTLT] = '((?:<|>)?=?)';
-
-// Something like "2.*" or "1.2.x".
-// Note that "x.x" is a valid xRange identifer, meaning "any version"
-// Only the first item is strictly required.
-var XRANGEIDENTIFIERLOOSE = R++;
-src[XRANGEIDENTIFIERLOOSE] = src[NUMERICIDENTIFIERLOOSE] + '|x|X|\\*';
-var XRANGEIDENTIFIER = R++;
-src[XRANGEIDENTIFIER] = src[NUMERICIDENTIFIER] + '|x|X|\\*';
-
-var XRANGEPLAIN = R++;
-src[XRANGEPLAIN] = '[v=\\s]*(' + src[XRANGEIDENTIFIER] + ')' +
-                   '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' +
-                   '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' +
-                   '(?:' + src[PRERELEASE] + ')?' +
-                   src[BUILD] + '?' +
-                   ')?)?';
-
-var XRANGEPLAINLOOSE = R++;
-src[XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[XRANGEIDENTIFIERLOOSE] + ')' +
-                        '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' +
-                        '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' +
-                        '(?:' + src[PRERELEASELOOSE] + ')?' +
-                        src[BUILD] + '?' +
-                        ')?)?';
-
-var XRANGE = R++;
-src[XRANGE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAIN] + '$';
-var XRANGELOOSE = R++;
-src[XRANGELOOSE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAINLOOSE] + '$';
-
-// Tilde ranges.
-// Meaning is "reasonably at or greater than"
-var LONETILDE = R++;
-src[LONETILDE] = '(?:~>?)';
-
-var TILDETRIM = R++;
-src[TILDETRIM] = '(\\s*)' + src[LONETILDE] + '\\s+';
-re[TILDETRIM] = new RegExp(src[TILDETRIM], 'g');
-var tildeTrimReplace = '$1~';
-
-var TILDE = R++;
-src[TILDE] = '^' + src[LONETILDE] + src[XRANGEPLAIN] + '$';
-var TILDELOOSE = R++;
-src[TILDELOOSE] = '^' + src[LONETILDE] + src[XRANGEPLAINLOOSE] + '$';
-
-// Caret ranges.
-// Meaning is "at least and backwards compatible with"
-var LONECARET = R++;
-src[LONECARET] = '(?:\\^)';
-
-var CARETTRIM = R++;
-src[CARETTRIM] = '(\\s*)' + src[LONECARET] + '\\s+';
-re[CARETTRIM] = new RegExp(src[CARETTRIM], 'g');
-var caretTrimReplace = '$1^';
-
-var CARET = R++;
-src[CARET] = '^' + src[LONECARET] + src[XRANGEPLAIN] + '$';
-var CARETLOOSE = R++;
-src[CARETLOOSE] = '^' + src[LONECARET] + src[XRANGEPLAINLOOSE] + '$';
-
-// A simple gt/lt/eq thing, or just "" to indicate "any version"
-var COMPARATORLOOSE = R++;
-src[COMPARATORLOOSE] = '^' + src[GTLT] + '\\s*(' + LOOSEPLAIN + ')$|^$';
-var COMPARATOR = R++;
-src[COMPARATOR] = '^' + src[GTLT] + '\\s*(' + FULLPLAIN + ')$|^$';
-
-
-// An expression to strip any whitespace between the gtlt and the thing
-// it modifies, so that `> 1.2.3` ==> `>1.2.3`
-var COMPARATORTRIM = R++;
-src[COMPARATORTRIM] = '(\\s*)' + src[GTLT] +
-                      '\\s*(' + LOOSEPLAIN + '|' + src[XRANGEPLAIN] + ')';
-
-// this one has to use the /g flag
-re[COMPARATORTRIM] = new RegExp(src[COMPARATORTRIM], 'g');
-var comparatorTrimReplace = '$1$2$3';
-
-
-// Something like `1.2.3 - 1.2.4`
-// Note that these all use the loose form, because they'll be
-// checked against either the strict or loose comparator form
-// later.
-var HYPHENRANGE = R++;
-src[HYPHENRANGE] = '^\\s*(' + src[XRANGEPLAIN] + ')' +
-                   '\\s+-\\s+' +
-                   '(' + src[XRANGEPLAIN] + ')' +
-                   '\\s*$';
-
-var HYPHENRANGELOOSE = R++;
-src[HYPHENRANGELOOSE] = '^\\s*(' + src[XRANGEPLAINLOOSE] + ')' +
-                        '\\s+-\\s+' +
-                        '(' + src[XRANGEPLAINLOOSE] + ')' +
-                        '\\s*$';
-
-// Star ranges basically just allow anything at all.
-var STAR = R++;
-src[STAR] = '(<|>)?=?\\s*\\*';
-
-// Compile to actual regexp objects.
-// All are flag-free, unless they were created above with a flag.
-for (var i = 0; i < R; i++) {
-  debug(i, src[i]);
-  if (!re[i])
-    { re[i] = new RegExp(src[i]); }
-}
-
-exports.parse = parse;
-function parse(version, loose) {
-  if (version instanceof SemVer)
-    { return version; }
-
-  if (typeof version !== 'string')
-    { return null; }
-
-  if (version.length > MAX_LENGTH)
-    { return null; }
-
-  var r = loose ? re[LOOSE] : re[FULL];
-  if (!r.test(version))
-    { return null; }
-
-  try {
-    return new SemVer(version, loose);
-  } catch (er) {
-    return null;
-  }
-}
-
-exports.valid = valid;
-function valid(version, loose) {
-  var v = parse(version, loose);
-  return v ? v.version : null;
-}
-
-
-exports.clean = clean;
-function clean(version, loose) {
-  var s = parse(version.trim().replace(/^[=v]+/, ''), loose);
-  return s ? s.version : null;
-}
-
-exports.SemVer = SemVer;
-
-function SemVer(version, loose) {
-  if (version instanceof SemVer) {
-    if (version.loose === loose)
-      { return version; }
-    else
-      { version = version.version; }
-  } else if (typeof version !== 'string') {
-    throw new TypeError('Invalid Version: ' + version);
-  }
-
-  if (version.length > MAX_LENGTH)
-    { throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters') }
-
-  if (!(this instanceof SemVer))
-    { return new SemVer(version, loose); }
-
-  debug('SemVer', version, loose);
-  this.loose = loose;
-  var m = version.trim().match(loose ? re[LOOSE] : re[FULL]);
-
-  if (!m)
-    { throw new TypeError('Invalid Version: ' + version); }
-
-  this.raw = version;
-
-  // these are actually numbers
-  this.major = +m[1];
-  this.minor = +m[2];
-  this.patch = +m[3];
-
-  if (this.major > MAX_SAFE_INTEGER || this.major < 0)
-    { throw new TypeError('Invalid major version') }
-
-  if (this.minor > MAX_SAFE_INTEGER || this.minor < 0)
-    { throw new TypeError('Invalid minor version') }
-
-  if (this.patch > MAX_SAFE_INTEGER || this.patch < 0)
-    { throw new TypeError('Invalid patch version') }
-
-  // numberify any prerelease numeric ids
-  if (!m[4])
-    { this.prerelease = []; }
-  else
-    { this.prerelease = m[4].split('.').map(function(id) {
-      if (/^[0-9]+$/.test(id)) {
-        var num = +id;
-        if (num >= 0 && num < MAX_SAFE_INTEGER)
-          { return num; }
-      }
-      return id;
-    }); }
-
-  this.build = m[5] ? m[5].split('.') : [];
-  this.format();
-}
-
-SemVer.prototype.format = function() {
-  this.version = this.major + '.' + this.minor + '.' + this.patch;
-  if (this.prerelease.length)
-    { this.version += '-' + this.prerelease.join('.'); }
-  return this.version;
-};
-
-SemVer.prototype.toString = function() {
-  return this.version;
-};
-
-SemVer.prototype.compare = function(other) {
-  debug('SemVer.compare', this.version, this.loose, other);
-  if (!(other instanceof SemVer))
-    { other = new SemVer(other, this.loose); }
-
-  return this.compareMain(other) || this.comparePre(other);
-};
-
-SemVer.prototype.compareMain = function(other) {
-  if (!(other instanceof SemVer))
-    { other = new SemVer(other, this.loose); }
-
-  return compareIdentifiers(this.major, other.major) ||
-         compareIdentifiers(this.minor, other.minor) ||
-         compareIdentifiers(this.patch, other.patch);
-};
-
-SemVer.prototype.comparePre = function(other) {
-  var this$1 = this;
-
-  if (!(other instanceof SemVer))
-    { other = new SemVer(other, this.loose); }
-
-  // NOT having a prerelease is > having one
-  if (this.prerelease.length && !other.prerelease.length)
-    { return -1; }
-  else if (!this.prerelease.length && other.prerelease.length)
-    { return 1; }
-  else if (!this.prerelease.length && !other.prerelease.length)
-    { return 0; }
-
-  var i = 0;
-  do {
-    var a = this$1.prerelease[i];
-    var b = other.prerelease[i];
-    debug('prerelease compare', i, a, b);
-    if (a === undefined && b === undefined)
-      { return 0; }
-    else if (b === undefined)
-      { return 1; }
-    else if (a === undefined)
-      { return -1; }
-    else if (a === b)
-      { continue; }
-    else
-      { return compareIdentifiers(a, b); }
-  } while (++i);
-};
-
-// preminor will bump the version up to the next minor release, and immediately
-// down to pre-release. premajor and prepatch work the same way.
-SemVer.prototype.inc = function(release, identifier) {
-  var this$1 = this;
-
-  switch (release) {
-    case 'premajor':
-      this.prerelease.length = 0;
-      this.patch = 0;
-      this.minor = 0;
-      this.major++;
-      this.inc('pre', identifier);
-      break;
-    case 'preminor':
-      this.prerelease.length = 0;
-      this.patch = 0;
-      this.minor++;
-      this.inc('pre', identifier);
-      break;
-    case 'prepatch':
-      // If this is already a prerelease, it will bump to the next version
-      // drop any prereleases that might already exist, since they are not
-      // relevant at this point.
-      this.prerelease.length = 0;
-      this.inc('patch', identifier);
-      this.inc('pre', identifier);
-      break;
-    // If the input is a non-prerelease version, this acts the same as
-    // prepatch.
-    case 'prerelease':
-      if (this.prerelease.length === 0)
-        { this.inc('patch', identifier); }
-      this.inc('pre', identifier);
-      break;
-
-    case 'major':
-      // If this is a pre-major version, bump up to the same major version.
-      // Otherwise increment major.
-      // 1.0.0-5 bumps to 1.0.0
-      // 1.1.0 bumps to 2.0.0
-      if (this.minor !== 0 || this.patch !== 0 || this.prerelease.length === 0)
-        { this.major++; }
-      this.minor = 0;
-      this.patch = 0;
-      this.prerelease = [];
-      break;
-    case 'minor':
-      // If this is a pre-minor version, bump up to the same minor version.
-      // Otherwise increment minor.
-      // 1.2.0-5 bumps to 1.2.0
-      // 1.2.1 bumps to 1.3.0
-      if (this.patch !== 0 || this.prerelease.length === 0)
-        { this.minor++; }
-      this.patch = 0;
-      this.prerelease = [];
-      break;
-    case 'patch':
-      // If this is not a pre-release version, it will increment the patch.
-      // If it is a pre-release it will bump up to the same patch version.
-      // 1.2.0-5 patches to 1.2.0
-      // 1.2.0 patches to 1.2.1
-      if (this.prerelease.length === 0)
-        { this.patch++; }
-      this.prerelease = [];
-      break;
-    // This probably shouldn't be used publicly.
-    // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction.
-    case 'pre':
-      if (this.prerelease.length === 0)
-        { this.prerelease = [0]; }
-      else {
-        var i = this.prerelease.length;
-        while (--i >= 0) {
-          if (typeof this$1.prerelease[i] === 'number') {
-            this$1.prerelease[i]++;
-            i = -2;
-          }
-        }
-        if (i === -1) // didn't increment anything
-          { this.prerelease.push(0); }
-      }
-      if (identifier) {
-        // 1.2.0-beta.1 bumps to 1.2.0-beta.2,
-        // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0
-        if (this.prerelease[0] === identifier) {
-          if (isNaN(this.prerelease[1]))
-            { this.prerelease = [identifier, 0]; }
-        } else
-          { this.prerelease = [identifier, 0]; }
-      }
-      break;
-
-    default:
-      throw new Error('invalid increment argument: ' + release);
-  }
-  this.format();
-  this.raw = this.version;
-  return this;
-};
-
-exports.inc = inc;
-function inc(version, release, loose, identifier) {
-  if (typeof(loose) === 'string') {
-    identifier = loose;
-    loose = undefined;
-  }
-
-  try {
-    return new SemVer(version, loose).inc(release, identifier).version;
-  } catch (er) {
-    return null;
-  }
-}
-
-exports.diff = diff;
-function diff(version1, version2) {
-  if (eq(version1, version2)) {
-    return null;
-  } else {
-    var v1 = parse(version1);
-    var v2 = parse(version2);
-    if (v1.prerelease.length || v2.prerelease.length) {
-      for (var key in v1) {
-        if (key === 'major' || key === 'minor' || key === 'patch') {
-          if (v1[key] !== v2[key]) {
-            return 'pre'+key;
-          }
-        }
-      }
-      return 'prerelease';
-    }
-    for (var key in v1) {
-      if (key === 'major' || key === 'minor' || key === 'patch') {
-        if (v1[key] !== v2[key]) {
-          return key;
-        }
-      }
-    }
-  }
-}
-
-exports.compareIdentifiers = compareIdentifiers;
-
-var numeric = /^[0-9]+$/;
-function compareIdentifiers(a, b) {
-  var anum = numeric.test(a);
-  var bnum = numeric.test(b);
-
-  if (anum && bnum) {
-    a = +a;
-    b = +b;
-  }
-
-  return (anum && !bnum) ? -1 :
-         (bnum && !anum) ? 1 :
-         a < b ? -1 :
-         a > b ? 1 :
-         0;
-}
-
-exports.rcompareIdentifiers = rcompareIdentifiers;
-function rcompareIdentifiers(a, b) {
-  return compareIdentifiers(b, a);
-}
-
-exports.major = major;
-function major(a, loose) {
-  return new SemVer(a, loose).major;
-}
-
-exports.minor = minor;
-function minor(a, loose) {
-  return new SemVer(a, loose).minor;
-}
-
-exports.patch = patch;
-function patch(a, loose) {
-  return new SemVer(a, loose).patch;
-}
-
-exports.compare = compare;
-function compare(a, b, loose) {
-  return new SemVer(a, loose).compare(new SemVer(b, loose));
-}
-
-exports.compareLoose = compareLoose;
-function compareLoose(a, b) {
-  return compare(a, b, true);
-}
-
-exports.rcompare = rcompare;
-function rcompare(a, b, loose) {
-  return compare(b, a, loose);
-}
-
-exports.sort = sort;
-function sort(list, loose) {
-  return list.sort(function(a, b) {
-    return exports.compare(a, b, loose);
-  });
-}
-
-exports.rsort = rsort;
-function rsort(list, loose) {
-  return list.sort(function(a, b) {
-    return exports.rcompare(a, b, loose);
-  });
-}
-
-exports.gt = gt;
-function gt(a, b, loose) {
-  return compare(a, b, loose) > 0;
-}
-
-exports.lt = lt;
-function lt(a, b, loose) {
-  return compare(a, b, loose) < 0;
-}
-
-exports.eq = eq;
-function eq(a, b, loose) {
-  return compare(a, b, loose) === 0;
-}
-
-exports.neq = neq;
-function neq(a, b, loose) {
-  return compare(a, b, loose) !== 0;
-}
-
-exports.gte = gte;
-function gte(a, b, loose) {
-  return compare(a, b, loose) >= 0;
-}
-
-exports.lte = lte;
-function lte(a, b, loose) {
-  return compare(a, b, loose) <= 0;
-}
-
-exports.cmp = cmp;
-function cmp(a, op, b, loose) {
-  var ret;
-  switch (op) {
-    case '===':
-      if (typeof a === 'object') { a = a.version; }
-      if (typeof b === 'object') { b = b.version; }
-      ret = a === b;
-      break;
-    case '!==':
-      if (typeof a === 'object') { a = a.version; }
-      if (typeof b === 'object') { b = b.version; }
-      ret = a !== b;
-      break;
-    case '': case '=': case '==': ret = eq(a, b, loose); break;
-    case '!=': ret = neq(a, b, loose); break;
-    case '>': ret = gt(a, b, loose); break;
-    case '>=': ret = gte(a, b, loose); break;
-    case '<': ret = lt(a, b, loose); break;
-    case '<=': ret = lte(a, b, loose); break;
-    default: throw new TypeError('Invalid operator: ' + op);
-  }
-  return ret;
-}
-
-exports.Comparator = Comparator;
-function Comparator(comp, loose) {
-  if (comp instanceof Comparator) {
-    if (comp.loose === loose)
-      { return comp; }
-    else
-      { comp = comp.value; }
-  }
-
-  if (!(this instanceof Comparator))
-    { return new Comparator(comp, loose); }
-
-  debug('comparator', comp, loose);
-  this.loose = loose;
-  this.parse(comp);
-
-  if (this.semver === ANY)
-    { this.value = ''; }
-  else
-    { this.value = this.operator + this.semver.version; }
-
-  debug('comp', this);
-}
-
-var ANY = {};
-Comparator.prototype.parse = function(comp) {
-  var r = this.loose ? re[COMPARATORLOOSE] : re[COMPARATOR];
-  var m = comp.match(r);
-
-  if (!m)
-    { throw new TypeError('Invalid comparator: ' + comp); }
-
-  this.operator = m[1];
-  if (this.operator === '=')
-    { this.operator = ''; }
-
-  // if it literally is just '>' or '' then allow anything.
-  if (!m[2])
-    { this.semver = ANY; }
-  else
-    { this.semver = new SemVer(m[2], this.loose); }
-};
-
-Comparator.prototype.toString = function() {
-  return this.value;
-};
-
-Comparator.prototype.test = function(version) {
-  debug('Comparator.test', version, this.loose);
-
-  if (this.semver === ANY)
-    { return true; }
-
-  if (typeof version === 'string')
-    { version = new SemVer(version, this.loose); }
-
-  return cmp(version, this.operator, this.semver, this.loose);
-};
-
-Comparator.prototype.intersects = function(comp, loose) {
-  if (!(comp instanceof Comparator)) {
-    throw new TypeError('a Comparator is required');
-  }
-
-  var rangeTmp;
-
-  if (this.operator === '') {
-    rangeTmp = new Range(comp.value, loose);
-    return satisfies(this.value, rangeTmp, loose);
-  } else if (comp.operator === '') {
-    rangeTmp = new Range(this.value, loose);
-    return satisfies(comp.semver, rangeTmp, loose);
-  }
-
-  var sameDirectionIncreasing =
-    (this.operator === '>=' || this.operator === '>') &&
-    (comp.operator === '>=' || comp.operator === '>');
-  var sameDirectionDecreasing =
-    (this.operator === '<=' || this.operator === '<') &&
-    (comp.operator === '<=' || comp.operator === '<');
-  var sameSemVer = this.semver.version === comp.semver.version;
-  var differentDirectionsInclusive =
-    (this.operator === '>=' || this.operator === '<=') &&
-    (comp.operator === '>=' || comp.operator === '<=');
-  var oppositeDirectionsLessThan =
-    cmp(this.semver, '<', comp.semver, loose) &&
-    ((this.operator === '>=' || this.operator === '>') &&
-    (comp.operator === '<=' || comp.operator === '<'));
-  var oppositeDirectionsGreaterThan =
-    cmp(this.semver, '>', comp.semver, loose) &&
-    ((this.operator === '<=' || this.operator === '<') &&
-    (comp.operator === '>=' || comp.operator === '>'));
-
-  return sameDirectionIncreasing || sameDirectionDecreasing ||
-    (sameSemVer && differentDirectionsInclusive) ||
-    oppositeDirectionsLessThan || oppositeDirectionsGreaterThan;
-};
-
-
-exports.Range = Range;
-function Range(range, loose) {
-  if (range instanceof Range) {
-    if (range.loose === loose) {
-      return range;
-    } else {
-      return new Range(range.raw, loose);
-    }
-  }
-
-  if (range instanceof Comparator) {
-    return new Range(range.value, loose);
-  }
-
-  if (!(this instanceof Range))
-    { return new Range(range, loose); }
-
-  this.loose = loose;
-
-  // First, split based on boolean or ||
-  this.raw = range;
-  this.set = range.split(/\s*\|\|\s*/).map(function(range) {
-    return this.parseRange(range.trim());
-  }, this).filter(function(c) {
-    // throw out any that are not relevant for whatever reason
-    return c.length;
-  });
-
-  if (!this.set.length) {
-    throw new TypeError('Invalid SemVer Range: ' + range);
-  }
-
-  this.format();
-}
-
-Range.prototype.format = function() {
-  this.range = this.set.map(function(comps) {
-    return comps.join(' ').trim();
-  }).join('||').trim();
-  return this.range;
-};
-
-Range.prototype.toString = function() {
-  return this.range;
-};
-
-Range.prototype.parseRange = function(range) {
-  var loose = this.loose;
-  range = range.trim();
-  debug('range', range, loose);
-  // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4`
-  var hr = loose ? re[HYPHENRANGELOOSE] : re[HYPHENRANGE];
-  range = range.replace(hr, hyphenReplace);
-  debug('hyphen replace', range);
-  // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5`
-  range = range.replace(re[COMPARATORTRIM], comparatorTrimReplace);
-  debug('comparator trim', range, re[COMPARATORTRIM]);
-
-  // `~ 1.2.3` => `~1.2.3`
-  range = range.replace(re[TILDETRIM], tildeTrimReplace);
-
-  // `^ 1.2.3` => `^1.2.3`
-  range = range.replace(re[CARETTRIM], caretTrimReplace);
-
-  // normalize spaces
-  range = range.split(/\s+/).join(' ');
-
-  // At this point, the range is completely trimmed and
-  // ready to be split into comparators.
-
-  var compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR];
-  var set = range.split(' ').map(function(comp) {
-    return parseComparator(comp, loose);
-  }).join(' ').split(/\s+/);
-  if (this.loose) {
-    // in loose mode, throw out any that are not valid comparators
-    set = set.filter(function(comp) {
-      return !!comp.match(compRe);
-    });
-  }
-  set = set.map(function(comp) {
-    return new Comparator(comp, loose);
-  });
-
-  return set;
-};
-
-Range.prototype.intersects = function(range, loose) {
-  if (!(range instanceof Range)) {
-    throw new TypeError('a Range is required');
-  }
-
-  return this.set.some(function(thisComparators) {
-    return thisComparators.every(function(thisComparator) {
-      return range.set.some(function(rangeComparators) {
-        return rangeComparators.every(function(rangeComparator) {
-          return thisComparator.intersects(rangeComparator, loose);
-        });
-      });
-    });
-  });
-};
-
-// Mostly just for testing and legacy API reasons
-exports.toComparators = toComparators;
-function toComparators(range, loose) {
-  return new Range(range, loose).set.map(function(comp) {
-    return comp.map(function(c) {
-      return c.value;
-    }).join(' ').trim().split(' ');
-  });
-}
-
-// comprised of xranges, tildes, stars, and gtlt's at this point.
-// already replaced the hyphen ranges
-// turn into a set of JUST comparators.
-function parseComparator(comp, loose) {
-  debug('comp', comp);
-  comp = replaceCarets(comp, loose);
-  debug('caret', comp);
-  comp = replaceTildes(comp, loose);
-  debug('tildes', comp);
-  comp = replaceXRanges(comp, loose);
-  debug('xrange', comp);
-  comp = replaceStars(comp, loose);
-  debug('stars', comp);
-  return comp;
-}
-
-function isX(id) {
-  return !id || id.toLowerCase() === 'x' || id === '*';
-}
-
-// ~, ~> --> * (any, kinda silly)
-// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0
-// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0
-// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0
-// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0
-// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0
-function replaceTildes(comp, loose) {
-  return comp.trim().split(/\s+/).map(function(comp) {
-    return replaceTilde(comp, loose);
-  }).join(' ');
-}
-
-function replaceTilde(comp, loose) {
-  var r = loose ? re[TILDELOOSE] : re[TILDE];
-  return comp.replace(r, function(_, M, m, p, pr) {
-    debug('tilde', comp, _, M, m, p, pr);
-    var ret;
-
-    if (isX(M))
-      { ret = ''; }
-    else if (isX(m))
-      { ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; }
-    else if (isX(p))
-      // ~1.2 == >=1.2.0 <1.3.0
-      { ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; }
-    else if (pr) {
-      debug('replaceTilde pr', pr);
-      if (pr.charAt(0) !== '-')
-        { pr = '-' + pr; }
-      ret = '>=' + M + '.' + m + '.' + p + pr +
-            ' <' + M + '.' + (+m + 1) + '.0';
-    } else
-      // ~1.2.3 == >=1.2.3 <1.3.0
-      { ret = '>=' + M + '.' + m + '.' + p +
-            ' <' + M + '.' + (+m + 1) + '.0'; }
-
-    debug('tilde return', ret);
-    return ret;
-  });
-}
-
-// ^ --> * (any, kinda silly)
-// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0
-// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0
-// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0
-// ^1.2.3 --> >=1.2.3 <2.0.0
-// ^1.2.0 --> >=1.2.0 <2.0.0
-function replaceCarets(comp, loose) {
-  return comp.trim().split(/\s+/).map(function(comp) {
-    return replaceCaret(comp, loose);
-  }).join(' ');
-}
-
-function replaceCaret(comp, loose) {
-  debug('caret', comp, loose);
-  var r = loose ? re[CARETLOOSE] : re[CARET];
-  return comp.replace(r, function(_, M, m, p, pr) {
-    debug('caret', comp, _, M, m, p, pr);
-    var ret;
-
-    if (isX(M))
-      { ret = ''; }
-    else if (isX(m))
-      { ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; }
-    else if (isX(p)) {
-      if (M === '0')
-        { ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; }
-      else
-        { ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0'; }
-    } else if (pr) {
-      debug('replaceCaret pr', pr);
-      if (pr.charAt(0) !== '-')
-        { pr = '-' + pr; }
-      if (M === '0') {
-        if (m === '0')
-          { ret = '>=' + M + '.' + m + '.' + p + pr +
-                ' <' + M + '.' + m + '.' + (+p + 1); }
-        else
-          { ret = '>=' + M + '.' + m + '.' + p + pr +
-                ' <' + M + '.' + (+m + 1) + '.0'; }
-      } else
-        { ret = '>=' + M + '.' + m + '.' + p + pr +
-              ' <' + (+M + 1) + '.0.0'; }
-    } else {
-      debug('no pr');
-      if (M === '0') {
-        if (m === '0')
-          { ret = '>=' + M + '.' + m + '.' + p +
-                ' <' + M + '.' + m + '.' + (+p + 1); }
-        else
-          { ret = '>=' + M + '.' + m + '.' + p +
-                ' <' + M + '.' + (+m + 1) + '.0'; }
-      } else
-        { ret = '>=' + M + '.' + m + '.' + p +
-              ' <' + (+M + 1) + '.0.0'; }
-    }
-
-    debug('caret return', ret);
-    return ret;
-  });
-}
-
-function replaceXRanges(comp, loose) {
-  debug('replaceXRanges', comp, loose);
-  return comp.split(/\s+/).map(function(comp) {
-    return replaceXRange(comp, loose);
-  }).join(' ');
-}
-
-function replaceXRange(comp, loose) {
-  comp = comp.trim();
-  var r = loose ? re[XRANGELOOSE] : re[XRANGE];
-  return comp.replace(r, function(ret, gtlt, M, m, p, pr) {
-    debug('xRange', comp, ret, gtlt, M, m, p, pr);
-    var xM = isX(M);
-    var xm = xM || isX(m);
-    var xp = xm || isX(p);
-    var anyX = xp;
-
-    if (gtlt === '=' && anyX)
-      { gtlt = ''; }
-
-    if (xM) {
-      if (gtlt === '>' || gtlt === '<') {
-        // nothing is allowed
-        ret = '<0.0.0';
-      } else {
-        // nothing is forbidden
-        ret = '*';
-      }
-    } else if (gtlt && anyX) {
-      // replace X with 0
-      if (xm)
-        { m = 0; }
-      if (xp)
-        { p = 0; }
-
-      if (gtlt === '>') {
-        // >1 => >=2.0.0
-        // >1.2 => >=1.3.0
-        // >1.2.3 => >= 1.2.4
-        gtlt = '>=';
-        if (xm) {
-          M = +M + 1;
-          m = 0;
-          p = 0;
-        } else if (xp) {
-          m = +m + 1;
-          p = 0;
-        }
-      } else if (gtlt === '<=') {
-        // <=0.7.x is actually <0.8.0, since any 0.7.x should
-        // pass.  Similarly, <=7.x is actually <8.0.0, etc.
-        gtlt = '<';
-        if (xm)
-          { M = +M + 1; }
-        else
-          { m = +m + 1; }
-      }
-
-      ret = gtlt + M + '.' + m + '.' + p;
-    } else if (xm) {
-      ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0';
-    } else if (xp) {
-      ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0';
-    }
-
-    debug('xRange return', ret);
-
-    return ret;
-  });
-}
-
-// Because * is AND-ed with everything else in the comparator,
-// and '' means "any version", just remove the *s entirely.
-function replaceStars(comp, loose) {
-  debug('replaceStars', comp, loose);
-  // Looseness is ignored here.  star is always as loose as it gets!
-  return comp.trim().replace(re[STAR], '');
-}
-
-// This function is passed to string.replace(re[HYPHENRANGE])
-// M, m, patch, prerelease, build
-// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5
-// 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do
-// 1.2 - 3.4 => >=1.2.0 <3.5.0
-function hyphenReplace($0,
-                       from, fM, fm, fp, fpr, fb,
-                       to, tM, tm, tp, tpr, tb) {
-
-  if (isX(fM))
-    { from = ''; }
-  else if (isX(fm))
-    { from = '>=' + fM + '.0.0'; }
-  else if (isX(fp))
-    { from = '>=' + fM + '.' + fm + '.0'; }
-  else
-    { from = '>=' + from; }
-
-  if (isX(tM))
-    { to = ''; }
-  else if (isX(tm))
-    { to = '<' + (+tM + 1) + '.0.0'; }
-  else if (isX(tp))
-    { to = '<' + tM + '.' + (+tm + 1) + '.0'; }
-  else if (tpr)
-    { to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr; }
-  else
-    { to = '<=' + to; }
-
-  return (from + ' ' + to).trim();
-}
-
-
-// if ANY of the sets match ALL of its comparators, then pass
-Range.prototype.test = function(version) {
-  var this$1 = this;
-
-  if (!version)
-    { return false; }
-
-  if (typeof version === 'string')
-    { version = new SemVer(version, this.loose); }
-
-  for (var i = 0; i < this.set.length; i++) {
-    if (testSet(this$1.set[i], version))
-      { return true; }
-  }
-  return false;
-};
-
-function testSet(set, version) {
-  for (var i = 0; i < set.length; i++) {
-    if (!set[i].test(version))
-      { return false; }
-  }
-
-  if (version.prerelease.length) {
-    // Find the set of versions that are allowed to have prereleases
-    // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0
-    // That should allow `1.2.3-pr.2` to pass.
-    // However, `1.2.4-alpha.notready` should NOT be allowed,
-    // even though it's within the range set by the comparators.
-    for (var i = 0; i < set.length; i++) {
-      debug(set[i].semver);
-      if (set[i].semver === ANY)
-        { continue; }
-
-      if (set[i].semver.prerelease.length > 0) {
-        var allowed = set[i].semver;
-        if (allowed.major === version.major &&
-            allowed.minor === version.minor &&
-            allowed.patch === version.patch)
-          { return true; }
-      }
-    }
-
-    // Version has a -pre, but it's not one of the ones we like.
-    return false;
-  }
-
-  return true;
-}
-
-exports.satisfies = satisfies;
-function satisfies(version, range, loose) {
-  try {
-    range = new Range(range, loose);
-  } catch (er) {
-    return false;
-  }
-  return range.test(version);
-}
-
-exports.maxSatisfying = maxSatisfying;
-function maxSatisfying(versions, range, loose) {
-  var max = null;
-  var maxSV = null;
-  try {
-    var rangeObj = new Range(range, loose);
-  } catch (er) {
-    return null;
-  }
-  versions.forEach(function (v) {
-    if (rangeObj.test(v)) { // satisfies(v, range, loose)
-      if (!max || maxSV.compare(v) === -1) { // compare(max, v, true)
-        max = v;
-        maxSV = new SemVer(max, loose);
-      }
-    }
-  });
-  return max;
-}
-
-exports.minSatisfying = minSatisfying;
-function minSatisfying(versions, range, loose) {
-  var min = null;
-  var minSV = null;
-  try {
-    var rangeObj = new Range(range, loose);
-  } catch (er) {
-    return null;
-  }
-  versions.forEach(function (v) {
-    if (rangeObj.test(v)) { // satisfies(v, range, loose)
-      if (!min || minSV.compare(v) === 1) { // compare(min, v, true)
-        min = v;
-        minSV = new SemVer(min, loose);
-      }
-    }
-  });
-  return min;
-}
-
-exports.validRange = validRange;
-function validRange(range, loose) {
-  try {
-    // Return '*' instead of '' so that truthiness works.
-    // This will throw if it's invalid anyway
-    return new Range(range, loose).range || '*';
-  } catch (er) {
-    return null;
-  }
-}
-
-// Determine if version is less than all the versions possible in the range
-exports.ltr = ltr;
-function ltr(version, range, loose) {
-  return outside(version, range, '<', loose);
-}
-
-// Determine if version is greater than all the versions possible in the range.
-exports.gtr = gtr;
-function gtr(version, range, loose) {
-  return outside(version, range, '>', loose);
-}
-
-exports.outside = outside;
-function outside(version, range, hilo, loose) {
-  version = new SemVer(version, loose);
-  range = new Range(range, loose);
-
-  var gtfn, ltefn, ltfn, comp, ecomp;
-  switch (hilo) {
-    case '>':
-      gtfn = gt;
-      ltefn = lte;
-      ltfn = lt;
-      comp = '>';
-      ecomp = '>=';
-      break;
-    case '<':
-      gtfn = lt;
-      ltefn = gte;
-      ltfn = gt;
-      comp = '<';
-      ecomp = '<=';
-      break;
-    default:
-      throw new TypeError('Must provide a hilo val of "<" or ">"');
-  }
-
-  // If it satisifes the range it is not outside
-  if (satisfies(version, range, loose)) {
-    return false;
-  }
-
-  // From now on, variable terms are as if we're in "gtr" mode.
-  // but note that everything is flipped for the "ltr" function.
-
-  for (var i = 0; i < range.set.length; ++i) {
-    var comparators = range.set[i];
-
-    var high = null;
-    var low = null;
-
-    comparators.forEach(function(comparator) {
-      if (comparator.semver === ANY) {
-        comparator = new Comparator('>=0.0.0');
-      }
-      high = high || comparator;
-      low = low || comparator;
-      if (gtfn(comparator.semver, high.semver, loose)) {
-        high = comparator;
-      } else if (ltfn(comparator.semver, low.semver, loose)) {
-        low = comparator;
-      }
-    });
-
-    // If the edge version comparator has a operator then our version
-    // isn't outside it
-    if (high.operator === comp || high.operator === ecomp) {
-      return false;
-    }
-
-    // If the lowest version comparator has an operator and our version
-    // is less than it then it isn't higher than the range
-    if ((!low.operator || low.operator === comp) &&
-        ltefn(version, low.semver)) {
-      return false;
-    } else if (low.operator === ecomp && ltfn(version, low.semver)) {
-      return false;
-    }
-  }
-  return true;
-}
-
-exports.prerelease = prerelease;
-function prerelease(version, loose) {
-  var parsed = parse(version, loose);
-  return (parsed && parsed.prerelease.length) ? parsed.prerelease : null;
-}
-
-exports.intersects = intersects;
-function intersects(r1, r2, loose) {
-  r1 = new Range(r1, loose);
-  r2 = new Range(r2, loose);
-  return r1.intersects(r2)
-}
-});
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-/**
- * Normalize a version string.
- * @param  {String} Version. ie: 1, 1.0, 1.0.0
- * @return {String} Version
- */
-function normalizeVersion (v) {
-  var isValid = semver.valid(v);
-  if (isValid) {
-    return v
-  }
-
-  v = typeof (v) === 'string' ? v : '';
-  var split = v.split('.');
-  var i = 0;
-  var result = [];
-
-  while (i < 3) {
-    var s = typeof (split[i]) === 'string' && split[i] ? split[i] : '0';
-    result.push(s);
-    i++;
-  }
-
-  return result.join('.')
-}
-
-/**
- * Get informations from different error key. Like:
- * - code
- * - errorMessage
- * - errorType
- * - isDowngrade
- * @param  {string} key
- * @param  {string} val
- * @param  {string} criteria
- * @return {object}
- */
-function getError (key, val, criteria) {
-  var result = {
-    isDowngrade: true,
-    errorType: 1,
-    code: 1000
-  };
-  var getMsg = function (key, val, criteria) {
-    return 'Downgrade[' + key + '] :: deviceInfo '
-      + val + ' matched criteria ' + criteria
-  };
-  var _key = key.toLowerCase();
-
-  result.errorMessage = getMsg(key, val, criteria);
-
-  if (_key.indexOf('osversion') >= 0) {
-    result.code = 1001;
-  }
-  else if (_key.indexOf('appversion') >= 0) {
-    result.code = 1002;
-  }
-  else if (_key.indexOf('weexversion') >= 0) {
-    result.code = 1003;
-  }
-  else if (_key.indexOf('devicemodel') >= 0) {
-    result.code = 1004;
-  }
-
-  return result
-}
-
-/**
- * WEEX framework input(deviceInfo)
- * {
- *   platform: 'iOS' or 'android'
- *   osVersion: '1.0.0' or '1.0' or '1'
- *   appVersion: '1.0.0' or '1.0' or '1'
- *   weexVersion: '1.0.0' or '1.0' or '1'
- *   dDeviceModel: 'MODEL_NAME'
- * }
- *
- * downgrade config(config)
- * {
- *   ios: {
- *     osVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
- *     appVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
- *     weexVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
- *     deviceModel: ['modelA', 'modelB', ...]
- *   },
- *   android: {
- *     osVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
- *     appVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
- *     weexVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
- *     deviceModel: ['modelA', 'modelB', ...]
- *   }
- * }
- *
- *
- * @param  {object} deviceInfo Weex SDK framework input
- * @param  {object} config     user input
- * @return {Object}            { isDowngrade: true/false, errorMessage... }
- */
-function check (config, deviceInfo) {
-  deviceInfo = deviceInfo || global.WXEnvironment;
-  deviceInfo = isPlainObject(deviceInfo) ? deviceInfo : {};
-
-  var result = {
-    isDowngrade: false // defautl is pass
-  };
-
-  if (typof(config) === 'function') {
-    var customDowngrade = config.call(this, deviceInfo, {
-      semver: semver,
-      normalizeVersion: normalizeVersion
-    });
-
-    customDowngrade = !!customDowngrade;
-
-    result = customDowngrade ? getError('custom', '', 'custom params') : result;
-  }
-  else {
-    config = isPlainObject(config) ? config : {};
-
-    var platform = deviceInfo.platform || 'unknow';
-    var dPlatform = platform.toLowerCase();
-    var cObj = config[dPlatform] || {};
-
-    for (var i in deviceInfo) {
-      var key = i;
-      var keyLower = key.toLowerCase();
-      var val = deviceInfo[i];
-      var isVersion = keyLower.indexOf('version') >= 0;
-      var isDeviceModel = keyLower.indexOf('devicemodel') >= 0;
-      var criteria = cObj[i];
-
-      if (criteria && isVersion) {
-        var c = normalizeVersion(criteria);
-        var d = normalizeVersion(deviceInfo[i]);
-
-        if (semver.satisfies(d, c)) {
-          result = getError(key, val, criteria);
-          break
-        }
-      }
-      else if (isDeviceModel) {
-        var _criteria = typof(criteria) === 'array' ? criteria : [criteria];
-        if (_criteria.indexOf(val) >= 0) {
-          result = getError(key, val, criteria);
-          break
-        }
-      }
-    }
-  }
-
-  return result
-}
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-function setViewport (app, configs) {
-  if ( configs === void 0 ) configs = {};
-
-  /* istanbul ignore if */
-  {
-    console.debug(("[JS Framework] Set viewport (width: " + (configs.width) + ") for app#" + (app.id) + "."));
-    validateViewport(configs);
-  }
-
-  // Send viewport configs to native
-  if (app && app.callTasks) {
-    return app.callTasks([{
-      module: 'meta',
-      method: 'setViewport',
-      args: [configs]
-    }])
-  }
-
-  /* istanbul ignore next */
-  else {
-    console.warn("[JS Framework] Can't find \"callTasks\" method on current app.");
-  }
-}
-
-/**
- * Validate the viewport config.
- * @param {Object} configs
- */
-function validateViewport (configs) {
-  if ( configs === void 0 ) configs = {};
-
-  var width = configs.width;
-  if (width) {
-    if (typeof width !== 'number' && width !== 'device-width') {
-      console.warn(("[JS Framework] Not support to use " + width + " as viewport width."));
-      return false
-    }
-    return true
-  }
-  console.warn('[JS Framework] the viewport config should contain the "width" property.');
-  return false
-}
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-/**
- * bootstrap app from a certain custom component with config & data
- */
-function bootstrap (app, name, config, data) {
-  console.debug(("[JS Framework] bootstrap for " + name));
-
-  // 1. validate custom component name first
-  var cleanName;
-  if (isWeexComponent(name)) {
-    cleanName = removeWeexPrefix(name);
-  }
-  else if (isNpmModule(name)) {
-    cleanName = removeJSSurfix(name);
-    // check if define by old 'define' method
-    /* istanbul ignore if */
-    if (!requireCustomComponent(app, cleanName)) {
-      return new Error(("It's not a component: " + name))
-    }
-  }
-  else {
-    return new Error(("Wrong component name: " + name))
-  }
-
-  // 2. validate configuration
-  config = isPlainObject(config) ? config : {};
-  // 2.1 transformer version check
-  if (typeof config.transformerVersion === 'string' &&
-    typeof global.transformerVersion === 'string' &&
-    !semver.satisfies(config.transformerVersion,
-      global.transformerVersion)) {
-    return new Error("JS Bundle version: " + (config.transformerVersion) + " " +
-      "not compatible with " + (global.transformerVersion))
-  }
-  // 2.2 downgrade version check
-  var downgradeResult = check(config.downgrade);
-  /* istanbul ignore if */
-  if (downgradeResult.isDowngrade) {
-    app.callTasks([{
-      module: 'instanceWrap',
-      method: 'error',
-      args: [
-        downgradeResult.errorType,
-        downgradeResult.code,
-        downgradeResult.errorMessage
-      ]
-    }]);
-    return new Error(("Downgrade[" + (downgradeResult.code) + "]: " + (downgradeResult.errorMessage)))
-  }
-
-  // set viewport
-  if (config.viewport) {
-    setViewport(app, config.viewport);
-  }
-
-  // 3. create a new Vm with custom component name and data
-  app.vm = new Vm(cleanName, null, { _app: app }, null, data);
-}
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-/**
- * define(name, factory) for primary usage
- * or
- * define(name, deps, factory) for compatibility
- * Notice: DO NOT use function define() {},
- * it will cause error after builded by webpack
- */
-var defineFn = function (app, name) {
-  var args = [], len = arguments.length - 2;
-  while ( len-- > 0 ) args[ len ] = arguments[ len + 2 ];
-
-  console.debug(("[JS Framework] define a component " + name));
-
-  // adapt args:
-  // 1. name, deps[], factory()
-  // 2. name, factory()
-  // 3. name, definition{}
-  var factory, definition;
-  if (args.length > 1) {
-    definition = args[1];
-  }
-  else {
-    definition = args[0];
-  }
-  if (typeof definition === 'function') {
-    factory = definition;
-    definition = null;
-  }
-
-  // resolve definition from factory
-  if (factory) {
-    var r = function (name) {
-      if (isWeexComponent(name)) {
-        var cleanName = removeWeexPrefix(name);
-        return requireCustomComponent(app, cleanName)
-      }
-      if (isWeexModule(name)) {
-        var cleanName$1 = removeWeexPrefix(name);
-        return app.requireModule(cleanName$1)
-      }
-      if (isNormalModule(name) || isNpmModule(name)) {
-        var cleanName$2 = removeJSSurfix(name);
-        return app.commonModules[cleanName$2]
-      }
-    };
-    var m = { exports: {}};
-    factory(r, m.exports, m);
-    definition = m.exports;
-  }
-
-  // apply definition
-  if (isWeexComponent(name)) {
-    var cleanName = removeWeexPrefix(name);
-    registerCustomComponent(app, cleanName, definition);
-  }
-  else if (isWeexModule(name)) {
-    var cleanName$1 = removeWeexPrefix(name);
-    var obj;
-    initModules(( obj = {}, obj[cleanName$1] = definition, obj ));
-  }
-  else if (isNormalModule(name)) {
-    var cleanName$2 = removeJSSurfix(name);
-    app.commonModules[cleanName$2] = definition;
-  }
-  else if (isNpmModule(name)) {
-    var cleanName$3 = removeJSSurfix(name);
-    if (definition.template ||
-        definition.style ||
-        definition.methods) {
-      // downgrade to old define method (define('componentName', factory))
-      // the exports contain one key of template, style or methods
-      // but it has risk!!!
-      registerCustomComponent(app, cleanName$3, definition);
-    }
-    else {
-      app.commonModules[cleanName$3] = definition;
-    }
-  }
-};
-
-/**
- * @deprecated
- */
-function register$1 (app, type, options) {
-  console.warn('[JS Framework] Register is deprecated, please install lastest transformer.');
-  registerCustomComponent(app, type, options);
-}
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-/**
- * @fileOverview
- * api that invoked by js bundle code
- *
- * - define(name, factory): define a new composed component type
- * - bootstrap(type, config, data): require a certain type &
- *         render with (optional) data
- *
- * deprecated:
- * - register(type, options): register a new composed component type
- * - render(type, data): render by a certain type with (optional) data
- * - require(type)(data): require a type then render with data
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-/**
- * @fileOverview
- * instance controls from native
- *
- * - fire event
- * - callback
- * - refresh
- * - destroy
- *
- * corresponded with the API of instance manager (framework.js)
- */
-/**
- * Refresh an app with data to its root component options.
- * @param  {object} app
- * @param  {any}    data
- */
-function refresh (app, data) {
-  console.debug("[JS Framework] Refresh with", data,
-            ("in instance[" + (app.id) + "]"));
-  var vm = app.vm;
-  if (vm && data) {
-    if (typeof vm.refreshData === 'function') {
-      vm.refreshData(data);
-    }
-    else {
-      extend(vm, data);
-    }
-    app.differ.flush();
-    app.doc.taskCenter.send('dom', { action: 'refreshFinish' }, []);
-    return
-  }
-  return new Error(("invalid data \"" + data + "\""))
-}
-
-/**
- * Destroy an app.
- * @param  {object} app
- */
-function destroy (app) {
-  console.debug(("[JS Framework] Destory an instance(" + (app.id) + ")"));
-
-  if (app.vm) {
-    destroyVm(app.vm);
-  }
-
-  app.id = '';
-  app.options = null;
-  app.blocks = null;
-  app.vm = null;
-  app.doc.taskCenter.destroyCallback();
-  app.doc.destroy();
-  app.doc = null;
-  app.customComponentMap = null;
-  app.commonModules = null;
-}
-
-/**
- * Destroy an Vm.
- * @param {object} vm
- */
-function destroyVm (vm) {
-  delete vm._app;
-  delete vm._computed;
-  delete vm._css;
-  delete vm._data;
-  delete vm._ids;
-  delete vm._methods;
-  delete vm._options;
-  delete vm._parent;
-  delete vm._parentEl;
-  delete vm._rootEl;
-
-  // remove all watchers
-  if (vm._watchers) {
-    var watcherCount = vm._watchers.length;
-    while (watcherCount--) {
-      vm._watchers[watcherCount].teardown();
-    }
-    delete vm._watchers;
-  }
-
-  // destroy child vms recursively
-  if (vm._childrenVms) {
-    var vmCount = vm._childrenVms.length;
-    while (vmCount--) {
-      destroyVm(vm._childrenVms[vmCount]);
-    }
-    delete vm._childrenVms;
-  }
-
-  console.debug(("[JS Framework] \"destroyed\" lifecycle in Vm(" + (vm._type) + ")"));
-  vm.$emit('hook:destroyed');
-
-  delete vm._type;
-  delete vm._vmEvents;
-}
-
-/**
- * Get a JSON object to describe the document body.
- * @param  {object} app
- * @return {object}
- */
-function getRootElement (app) {
-  var doc = app.doc || {};
-  var body = doc.body || {};
-  return body.toJSON ? body.toJSON() : {}
-}
-
-/**
- * Fire an event from renderer. The event has type, an event object and an
- * element ref. If the event comes with some virtual-DOM changes, it should
- * have one more parameter to describe the changes.
- * @param  {object} app
- * @param  {string} ref
- * @param  {type}   type
- * @param  {object} e
- * @param  {object} domChanges
- */
-function fireEvent (app, ref, type, e, domChanges) {
-  console.debug(("[JS Framework] Fire a \"" + type + "\" event on an element(" + ref + ") in instance(" + (app.id) + ")"));
-  if (Array.isArray(ref)) {
-    ref.some(function (ref) {
-      return fireEvent(app, ref, type, e) !== false
-    });
-    return
-  }
-  var el = app.doc.getRef(ref);
-  if (el) {
-    var result = app.doc.fireEvent(el, type, e, domChanges);
-    app.differ.flush();
-    app.doc.taskCenter.send('dom', { action: 'updateFinish' }, []);
-    return result
-  }
-  return new Error(("invalid element reference \"" + ref + "\""))
-}
-
-/**
- * Make a callback for a certain app.
- * @param  {object}   app
- * @param  {number}   callbackId
- * @param  {any}      data
- * @param  {boolean}  ifKeepAlive
- */
-function callback (app, callbackId, data, ifKeepAlive) {
-  console.debug(("[JS Framework] Invoke a callback(" + callbackId + ") with"), data,
-            ("in instance(" + (app.id) + ")"));
-  var result = app.doc.taskCenter.callback(callbackId, data, ifKeepAlive);
-  updateActions(app);
-  app.doc.taskCenter.send('dom', { action: 'updateFinish' }, []);
-  return result
-}
-
-/**
- * Collect all virtual-DOM mutations together and send them to renderer.
- * @param  {object} app
- */
-function updateActions (app) {
-  app.differ.flush();
-}
-
-/**
- * Call all tasks from an app to renderer (native).
- * @param  {object} app
- * @param  {array}  tasks
- */
-function callTasks (app, tasks) {
-  var result;
-
-  /* istanbul ignore next */
-  if (typof(tasks) !== 'array') {
-    tasks = [tasks];
-  }
-
-  tasks.forEach(function (task) {
-    result = app.doc.taskCenter.send(
-      'module',
-      {
-        module: task.module,
-        method: task.method
-      },
-      task.args
-    );
-  });
-
-  return result
-}
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-/**
- * @fileOverview
- * instance controls from native
- *
- * - init bundle
- *
- * corresponded with the API of instance manager (framework.js)
- */
-
-/**
- * Init an app by run code witgh data
- * @param  {object} app
- * @param  {string} code
- * @param  {object} data
- */
-function init (app, code, data, services) {
-  console.debug('[JS Framework] Intialize an instance with:\n', data);
-  var result;
-
-  // prepare app env methods
-  var bundleDefine = function () {
-    var args = [], len = arguments.length;
-    while ( len-- ) args[ len ] = arguments[ len ];
-
-    return defineFn.apply(void 0, [ app ].concat( args ));
-  };
-  var bundleBootstrap = function (name, config, _data) {
-    result = bootstrap(app, name, config, _data || data);
-    updateActions(app);
-    app.doc.listener.createFinish();
-    console.debug(("[JS Framework] After intialized an instance(" + (app.id) + ")"));
-  };
-  var bundleVm = Vm;
-  /* istanbul ignore next */
-  var bundleRegister = function () {
-    var args = [], len = arguments.length;
-    while ( len-- ) args[ len ] = arguments[ len ];
-
-    return register$1.apply(void 0, [ app ].concat( args ));
-  };
-  /* istanbul ignore next */
-  var bundleRender = function (name, _data) {
-    result = bootstrap(app, name, {}, _data);
-  };
-  /* istanbul ignore next */
-  var bundleRequire = function (name) { return function (_data) {
-    result = bootstrap(app, name, {}, _data);
-  }; };
-  var bundleDocument = app.doc;
-  /* istanbul ignore next */
-  var bundleRequireModule = function (name) { return app.requireModule(removeWeexPrefix(name)); };
-
-  var weexGlobalObject = {
-    config: app.options,
-    define: bundleDefine,
-    bootstrap: bundleBootstrap,
-    requireModule: bundleRequireModule,
-    document: bundleDocument,
-    Vm: bundleVm
-  };
-
-  Object.freeze(weexGlobalObject);
-
-  // prepare code
-  var functionBody;
-  /* istanbul ignore if */
-  if (typeof code === 'function') {
-    // `function () {...}` -> `{...}`
-    // not very strict
-    functionBody = code.toString().substr(12);
-  }
-  /* istanbul ignore next */
-  else if (code) {
-    functionBody = code.toString();
-  }
-  // wrap IFFE and use strict mode
-  functionBody = "(function(global){\n\n\"use strict\";\n\n " + functionBody + " \n\n})(Object.create(this))";
-
-  // run code and get result
-  var WXEnvironment = global.WXEnvironment;
-  var timerAPIs = {};
-
-  /* istanbul ignore if */
-  if (WXEnvironment && WXEnvironment.platform !== 'Web') {
-    // timer APIs polyfill in native
-    var timer = app.requireModule('timer');
-    Object.assign(timerAPIs, {
-      setTimeout: function () {
-        var args = [], len = arguments.length;
-        while ( len-- ) args[ len ] = arguments[ len ];
-
-        var handler = function () {
-          args[0].apply(args, args.slice(2));
-        };
-        timer.setTimeout(handler, args[1]);
-        return app.doc.taskCenter.callbackManager.lastCallbackId.toString()
-      },
-      setInterval: function () {
-        var args = [], len = arguments.length;
-        while ( len-- ) args[ len ] = arguments[ len ];
-
-        var handler = function () {
-          args[0].apply(args, args.slice(2));
-        };
-        timer.setInterval(handler, args[1]);
-        return app.doc.taskCenter.callbackManager.lastCallbackId.toString()
-      },
-      clearTimeout: function (n) {
-        timer.clearTimeout(n);
-      },
-      clearInterval: function (n) {
-        timer.clearInterval(n);
-      }
-    });
-  }
-  // run code and get result
-  var globalObjects = Object.assign({
-    define: bundleDefine,
-    require: bundleRequire,
-    bootstrap: bundleBootstrap,
-    register: bundleRegister,
-    render: bundleRender,
-    __weex_define__: bundleDefine, // alias for define
-    __weex_bootstrap__: bundleBootstrap, // alias for bootstrap
-    __weex_document__: bundleDocument,
-    __weex_require__: bundleRequireModule,
-    __weex_viewmodel__: bundleVm,
-    weex: weexGlobalObject
-  }, timerAPIs, services);
-  if (!callFunctionNative(globalObjects, functionBody)) {
-    // If failed to compile functionBody on native side,
-    // fallback to callFunction.
-    callFunction(globalObjects, functionBody);
-  }
-
-  return result
-}
-
-/**
- * Call a new function body with some global objects.
- * @param  {object} globalObjects
- * @param  {string} code
- * @return {any}
- */
-function callFunction (globalObjects, body) {
-  var globalKeys = [];
-  var globalValues = [];
-  for (var key in globalObjects) {
-    globalKeys.push(key);
-    globalValues.push(globalObjects[key]);
-  }
-  globalKeys.push(body);
-
-  var result = new (Function.prototype.bind.apply( Function, [ null ].concat( globalKeys) ));
-  return result.apply(void 0, globalValues)
-}
-
-/**
- * Call a new function generated on the V8 native side.
- * @param  {object} globalObjects
- * @param  {string} body
- * @return {boolean} return true if no error occurred.
- */
-function callFunctionNative (globalObjects, body) {
-  if (typeof compileAndRunBundle !== 'function') {
-    return false
-  }
-
-  var fn = void 0;
-  var isNativeCompileOk = false;
-  var script = '(function (';
-  var globalKeys = [];
-  var globalValues = [];
-  for (var key in globalObjects) {
-    globalKeys.push(key);
-    globalValues.push(globalObjects[key]);
-  }
-  for (var i = 0; i < globalKeys.length - 1; ++i) {
-    script += globalKeys[i];
-    script += ',';
-  }
-  script += globalKeys[globalKeys.length - 1];
-  script += ') {';
-  script += body;
-  script += '} )';
-
-  try {
-    var weex = globalObjects.weex || {};
-    var config = weex.config || {};
-    fn = compileAndRunBundle(script,
-                             config.bundleUrl,
-                             config.bundleDigest,
-                             config.codeCachePath);
-    if (fn && typeof fn === 'function') {
-      fn.apply(void 0, globalValues);
-      isNativeCompileOk = true;
-    }
-  }
-  catch (e) {
-    console.error(e);
-  }
-
-  return isNativeCompileOk
-}
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-/**
- * @fileOverview
- * instance controls from native
- *
- * - init bundle
- * - fire event
- * - callback
- * - destroy
- *
- * corresponded with the API of instance manager (framework.js)
- */
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-var Differ = function Differ (id) {
-  this.id = id;
-  this.map = [];
-  this.hooks = [];
-};
-Differ.prototype.isEmpty = function isEmpty () {
-  return this.map.length === 0
-};
-Differ.prototype.append = function append (type, depth, ref, handler) {
-    var this$1 = this;
-
-  if (!this.hasTimer) {
-    this.hasTimer = true;
-    setTimeout(function () {
-      this$1.hasTimer = false;
-      this$1.flush(true);
-    }, 0);
-  }
-  var map = this.map;
-  if (!map[depth]) {
-    map[depth] = {};
-  }
-  var group = map[depth];
-  if (!group[type]) {
-    group[type] = {};
-  }
-  if (type === 'element') {
-    if (!group[type][ref]) {
-      group[type][ref] = [];
-    }
-    group[type][ref].push(handler);
-  }
-  else {
-    group[type][ref] = handler;
-  }
-};
-Differ.prototype.flush = function flush (isTimeout) {
-  var map = this.map.slice();
-  this.map.length = 0;
-  map.forEach(function (group) {
-    callTypeMap(group, 'repeat');
-    callTypeMap(group, 'shown');
-    callTypeList(group, 'element');
-  });
-
-  var hooks = this.hooks.slice();
-  this.hooks.length = 0;
-  hooks.forEach(function (fn) {
-    fn();
-  });
-
-  if (!this.isEmpty()) {
-    this.flush();
-  }
-};
-Differ.prototype.then = function then (fn) {
-  this.hooks.push(fn);
-};
-
-function callTypeMap (group, type) {
-  var map = group[type];
-  for (var ref in map) {
-    map[ref]();
-  }
-}
-
-function callTypeList (group, type) {
-  var map = group[type];
-  for (var ref in map) {
-    var list = map[ref];
-    list.forEach(function (handler) { handler(); });
-  }
-}
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-/**
- * @fileOverview
- * Weex App constructor & definition
- */
-
-/**
- * App constructor for Weex framework.
- * @param {string} id
- * @param {object} options
- */
-function App$1 (id, options) {
-  this.id = id;
-  this.options = options || {};
-  this.vm = null;
-  this.customComponentMap = {};
-  this.commonModules = {};
-
-  // document
-  this.doc = new config.Document(
-    id,
-    this.options.bundleUrl,
-    null,
-    config.Listener
-  );
-  this.differ = new Differ(id);
-}
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-/**
- * @fileOverview
- * Weex instance constructor & definition
- */
-
-/**
- * @deprecated
- */
-App$1.prototype.requireModule = function (name) {
-  return requireModule(this, name)
-};
-
-/**
- * @deprecated
- */
-App$1.prototype.updateActions = function () {
-  return updateActions(this)
-};
-
-/**
- * @deprecated
- */
-App$1.prototype.callTasks = function (tasks) {
-  return callTasks(this, tasks)
-};
-
-/**
- * Prevent modification of App and App.prototype
- */
-Object.freeze(App$1);
-Object.freeze(App$1.prototype);
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-var instanceMap = {};
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-/**
- * Create a Weex instance.
- *
- * @param  {string} id
- * @param  {string} code
- * @param  {object} options
- *         option `HAS_LOG` enable print log
- * @param  {object} data
- * @param  {object} info { created, ... services }
- */
-function createInstance (id, code, options, data, info) {
-  var ref = info || {};
-  var services = ref.services;
-  resetTarget();
-  var instance = instanceMap[id];
-  /* istanbul ignore else */
-  options = options || {};
-  var result;
-  /* istanbul ignore else */
-  if (!instance) {
-    instance = new App$1(id, options);
-    instanceMap[id] = instance;
-    result = init(instance, code, data, services);
-  }
-  else {
-    result = new Error(("invalid instance id \"" + id + "\""));
-  }
-  return (result instanceof Error) ? result : instance
-}
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-/**
- * Init config informations for Weex framework
- * @param  {object} cfg
- */
-function init$1 (cfg) {
-  config.Document = cfg.Document;
-  config.Element = cfg.Element;
-  config.Comment = cfg.Comment;
-  config.sendTasks = cfg.sendTasks;
-  config.Listener = cfg.Listener;
-}
-
-/**
- * Refresh a Weex instance with data.
- *
- * @param  {string} id
- * @param  {object} data
- */
-function refreshInstance (id, data) {
-  var instance = instanceMap[id];
-  var result;
-  /* istanbul ignore else */
-  if (instance) {
-    result = refresh(instance, data);
-  }
-  else {
-    result = new Error(("invalid instance id \"" + id + "\""));
-  }
-  return result
-}
-
-/**
- * Destroy a Weex instance.
- * @param  {string} id
- */
-function destroyInstance (id) {
-  // Markup some global state in native side
-  if (typeof markupState === 'function') {
-    markupState();
-  }
-
-  resetTarget();
-  var instance = instanceMap[id];
-  /* istanbul ignore else */
-  if (!instance) {
-    return new Error(("invalid instance id \"" + id + "\""))
-  }
-  destroy(instance);
-  delete instanceMap[id];
-  // notifyContextDisposed is used to tell v8 to do a full GC,
-  // but this would have a negative performance impact on weex,
-  // because all the inline cache in v8 would get cleared
-  // during a full GC.
-  // To take care of both memory and performance, just tell v8
-  // to do a full GC every eighteen times.
-  var idNum = Math.round(id);
-  var round = 18;
-  if (idNum > 0) {
-    var remainder = idNum % round;
-    if (!remainder && typeof notifyTrimMemory === 'function') {
-      notifyTrimMemory();
-    }
-  }
-  return instanceMap
-}
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-var nativeComponentMap$1 = config.nativeComponentMap;
-
-/**
- * Register the name of each native component.
- * @param  {array} components array of name
- */
-function registerComponents (components) {
-  if (Array.isArray(components)) {
-    components.forEach(function register (name) {
-      /* istanbul ignore if */
-      if (!name) {
-        return
-      }
-      if (typeof name === 'string') {
-        nativeComponentMap$1[name] = true;
-      }
-      /* istanbul ignore else */
-      else if (typeof name === 'object' && typeof name.type === 'string') {
-        nativeComponentMap$1[name.type] = name;
-      }
-    });
-  }
-}
-
-/**
- * Register the name and methods of each module.
- * @param  {object} modules a object of modules
- */
-function registerModules (modules) {
-  /* istanbul ignore else */
-  if (typeof modules === 'object') {
-    initModules(modules);
-  }
-}
-
-/**
- * Register the name and methods of each api.
- * @param  {object} apis a object of apis
- */
-function registerMethods (methods) {
-  /* istanbul ignore else */
-  if (typeof methods === 'object') {
-    initMethods$1(Vm, methods);
-  }
-}
-
-// @todo: Hack for this framework only. Will be re-designed or removed later.
-global.registerMethods = registerMethods;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-var jsHandlers = {
-  fireEvent: function (id) {
-    var args = [], len = arguments.length - 1;
-    while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
-
-    return fireEvent.apply(void 0, [ instanceMap[id] ].concat( args ))
-  },
-  callback: function (id) {
-    var args = [], len = arguments.length - 1;
-    while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
-
-    return callback.apply(void 0, [ instanceMap[id] ].concat( args ))
-  }
-};
-
-/**
- * Accept calls from native (event or callback).
- *
- * @param  {string} id
- * @param  {array} tasks list with `method` and `args`
- */
-function receiveTasks (id, tasks) {
-  var instance = instanceMap[id];
-  if (instance && Array.isArray(tasks)) {
-    var results = [];
-    tasks.forEach(function (task) {
-      var handler = jsHandlers[task.method];
-      var args = [].concat( task.args );
-      /* istanbul ignore else */
-      if (typeof handler === 'function') {
-        args.unshift(id);
-        results.push(handler.apply(void 0, args));
-      }
-    });
-    return results
-  }
-  return new Error(("invalid instance id \"" + id + "\" or tasks"))
-}
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-/**
- * Get a whole element tree of an instance for debugging.
- * @param  {string} id
- * @return {object} a virtual dom tree
- */
-function getRoot (id) {
-  var instance = instanceMap[id];
-  var result;
-  /* istanbul ignore else */
-  if (instance) {
-    result = getRootElement(instance);
-  }
-  else {
-    result = new Error(("invalid instance id \"" + id + "\""));
-  }
-  return result
-}
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-/**
- * @fileOverview Weex framework entry.
- */
-
-// register special methods for Weex framework
-registerMethods(methods);
-
-/**
- * Prevent modification of Vm and Vm.prototype
- */
-Object.freeze(Vm);
-
-exports.registerComponents = registerComponents;
-exports.registerModules = registerModules;
-exports.registerMethods = registerMethods;
-exports.createInstance = createInstance;
-exports.init = init$1;
-exports.refreshInstance = refreshInstance;
-exports.destroyInstance = destroyInstance;
-exports.receiveTasks = receiveTasks;
-exports.getRoot = getRoot;
-
-Object.defineProperty(exports, '__esModule', { value: true });
-
-})));
-//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjpudWxsLCJzb3VyY2VzIjpbIi4uLy4uL2h0bWw1L2ZyYW1ld29ya3MvbGVnYWN5L2FwaS9tZXRob2RzLmpzIiwiLi4vLi4vaHRtbDUvZnJhbWV3b3Jrcy9sZWdhY3kvdXRpbC9zaGFyZWQuanMiLCIuLi8uLi9odG1sNS9mcmFtZXdvcmtzL2xlZ2FjeS91dGlsL2luZGV4LmpzIiwiLi4vLi4vaHRtbDUvZnJhbWV3b3Jrcy9sZWdhY3kvY29yZS9kZXAuanMiLCIuLi8uLi9odG1sNS9mcmFtZXdvcmtzL2xlZ2FjeS9jb3JlL3dhdGNoZXIuanMiLCIuLi8uLi9odG1sNS9mcmFtZXdvcmtzL2xlZ2FjeS9jb3JlL2FycmF5LmpzIiwiLi4vLi4vaHRtbDUvZnJhbWV3b3Jrcy9sZWdhY3kvY29yZS9vYnNlcnZlci5qcyIsIi4uLy4uL2h0bWw1L2ZyYW1ld29ya3MvbGVnYWN5L2NvcmUvc3RhdGUuanMiLCIuLi8uLi9odG1sNS9mcmFtZXdvcmtzL2xlZ2FjeS9jb25maWcuanMiLCIuLi8uLi9odG1sNS9mcmFtZXdvcmtzL2xlZ2FjeS92bS9kaXJlY3RpdmUuanMiLCIuLi8uLi9odG1sNS9mcmFtZXdvcmtzL2xlZ2FjeS92bS9kb20taGVscGVyLmpzIiwiLi4vLi4vaHRtbDUvZnJhbWV3b3Jrcy9sZWdhY3kvdm0vY29tcGlsZXIuanMiLCIuLi8uLi9odG1sNS9mcmFtZXdvcmtzL2xlZ2FjeS92bS9ldmVudHMuanMiLCIuLi8uLi9odG1sNS9mcmFtZXdvcmtzL2xlZ2FjeS92bS9pbmRleC5qcyIsIi4uLy4uL2h0bWw1L2ZyYW1ld29ya3MvbGVnYWN5L2FwcC9yZWdpc3Rlci5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9zZW12ZXIvc2VtdmVyLmpzIiwiLi4vLi4vaHRtbDUvZnJhbWV3b3Jrcy9sZWdhY3kvYXBwL2Rvd25ncmFkZS5qcyIsIi4uLy4uL2h0bWw1L2ZyYW1ld29ya3MvbGVnYWN5L2FwcC92aWV3cG9ydC5qcyIsIi4uLy4uL2h0bWw1L2ZyYW1ld29ya3MvbGVnYWN5L2FwcC9idW5kbGUvYm9vdHN0cmFwLmpzIiwiLi4vLi4vaHRtbDUvZnJhbWV3b3Jrcy9sZWdhY3kvYXBwL2J1bmRsZS9kZWZpbmUuanMiLCIuLi8uLi9odG1sNS9mcmFtZXdvcmtzL2xlZ2FjeS9hcHAvYnVuZGxlL2luZGV4LmpzIiwiLi4vLi4vaHRtbDUvZnJhbWV3b3Jrcy9sZWdhY3kvYXBwL2N0cmwvbWlzYy5qcyIsIi4uLy4uL2h0bWw1L2ZyYW1ld29ya3MvbGVnYWN5L2FwcC9jdHJsL2luaXQuanMiLCIuLi8uLi9odG1sNS9mcmFtZXdvcmtzL2xlZ2FjeS9hcHAvY3RybC9pbmRleC5qcyIsIi4uLy4uL2h0bWw1L2ZyYW1ld29ya3MvbGVnYWN5L2FwcC9kaWZmZXIuanMiLCIuLi8uLi9odG1sNS9mcmFtZXdvcmtzL2xlZ2FjeS9hcHAvaW5zdGFuY2UuanMiLCIuLi8uLi9odG1sNS9mcmFtZXdvcmtzL2xlZ2FjeS9hcHAvaW5kZXguanMiLCIuLi8uLi9odG1sNS9mcmFtZXdvcmtzL2xlZ2FjeS9zdGF0aWMvbWFwLmpzIiwiLi4vLi4vaHRtbDUvZnJhbWV3b3Jrcy9sZWdhY3kvc3RhdGljL2NyZWF0ZS5qcyIsIi4uLy4uL2h0bWw1L2ZyYW1ld29ya3MvbGVnYWN5L3N0YXRpYy9saWZlLmpzIiwiLi4vLi4vaHRtbDUvZnJhbWV3b3Jrcy9sZWdhY3kvc3RhdGljL3JlZ2lzdGVyLmpzIiwiLi4vLi4vaHRtbDUvZnJhbWV3b3Jrcy9sZWdhY3kvc3RhdGljL2JyaWRnZS5qcyIsIi4uLy4uL2h0bWw1L2ZyYW1ld29ya3MvbGVnYWN5L3N0YXRpYy9taXNjLmpzIiwiLi4vLi4vaHRtbDUvZnJhbWV3b3Jrcy9sZWdhY3kvaW5kZXguanMiXSwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmVcbiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZVxuICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb25cbiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGVcbiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGVcbiAqIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZVxuICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLFxuICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW5cbiAqIFwiQVMgSVNcIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXG4gKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGVcbiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnNcbiAqIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG4vKipcbiAqIEBmaWxlT3ZlcnZpZXcgVGhlIGFwaSBmb3IgaW52b2tpbmcgd2l0aCBcIiRcIiBwcmVmaXhcbiAqL1xuXG4vKipcbiAqIEBkZXByZWNhdGVkIHVzZSAkdm0gaW5zdGVhZFxuICogZmluZCB0aGUgdm0gYnkgaWRcbiAqIE5vdGU6IHRoZXJlIGlzIG9ubHkgb25lIGlkIGluIHdob2xlIGNvbXBvbmVudFxuICogQHBhcmFtICB7c3RyaW5nfSBpZFxuICogQHJldHVybiB7Vm19XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiAkIChpZCkge1xuICBjb25zb2xlLndhcm4oJ1tKUyBGcmFtZXdvcmtdIFZtIyQgaXMgZGVwcmVjYXRlZCwgcGxlYXNlIHVzZSBWbSMkdm0gaW5zdGVhZCcpXG4gIGNvbnN0IGluZm8gPSB0aGlzLl9pZHNbaWRdXG4gIGlmIChpbmZvKSB7XG4gICAgcmV0dXJuIGluZm8udm1cbiAgfVxufVxuXG4vKipcbiAqIGZpbmQgdGhlIGVsZW1lbnQgYnkgaWRcbiAqIE5vdGU6IHRoZXJlIGlzIG9ubHkgb25lIGlkIGluIHdob2xlIGNvbXBvbmVudFxuICogQHBhcmFtICB7c3RyaW5nfSBpZFxuICogQHJldHVybiB7RWxlbWVudH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uICRlbCAoaWQpIHtcbiAgY29uc3QgaW5mbyA9IHRoaXMuX2lkc1tpZF1cbiAgaWYgKGluZm8pIHtcbiAgICByZXR1cm4gaW5mby5lbFxuICB9XG59XG5cbi8qKlxuICogZmluZCB0aGUgdm0gb2YgdGhlIGN1c3RvbSBjb21wb25lbnQgYnkgaWRcbiAqIE5vdGU6IHRoZXJlIGlzIG9ubHkgb25lIGlkIGluIHdob2xlIGNvbXBvbmVudFxuICogQHBhcmFtICB7c3RyaW5nfSBpZFxuICogQHJldHVybiB7Vm19XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiAkdm0gKGlkKSB7XG4gIGNvbnN0IGluZm8gPSB0aGlzLl9pZHNbaWRdXG4gIGlmIChpbmZvKSB7XG4gICAgcmV0dXJuIGluZm8udm1cbiAgfVxufVxuXG4vKipcbiAqIEZpcmUgd2hlbiBkaWZmZXIgcmVuZGVyaW5nIGZpbmlzaGVkXG4gKlxuICogQHBhcmFtICB7RnVuY3Rpb259IGZuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiAkcmVuZGVyVGhlbiAoZm4pIHtcbiAgY29uc3QgYXBwID0gdGhpcy5fYXBwXG4gIGNvbnN0IGRpZmZlciA9IGFwcC5kaWZmZXJcbiAgcmV0dXJuIGRpZmZlci50aGVuKCgpID0+IHtcbiAgICBmbigpXG4gIH0pXG59XG5cbi8qKlxuICogc2Nyb2xsIGFuIGVsZW1lbnQgc3BlY2lmaWVkIGJ5IGlkIGludG8gdmlldyxcbiAqIG1vcmVvdmVyIHNwZWNpZnkgYSBudW1iZXIgb2Ygb2Zmc2V0IG9wdGlvbmFsbHlcbiAqIEBwYXJhbSAge3N0cmluZ30gaWRcbiAqIEBwYXJhbSAge251bWJlcn0gb2Zmc2V0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiAkc2Nyb2xsVG8gKGlkLCBvZmZzZXQpIHtcbiAgY29uc29sZS53YXJuKCdbSlMgRnJhbWV3b3JrXSBWbSMkc2Nyb2xsVG8gaXMgZGVwcmVjYXRlZCwgJyArXG4gICAgICAgICAgJ3BsZWFzZSB1c2UgXCJyZXF1aXJlKFxcJ0B3ZWV4LW1vZHVsZS9kb21cXCcpJyArXG4gICAgICAgICAgJy5zY3JvbGxUbyhlbCwgb3B0aW9ucylcIiBpbnN0ZWFkJylcbiAgY29uc3QgZWwgPSB0aGlzLiRlbChpZClcbiAgaWYgKGVsKSB7XG4gICAgY29uc3QgZG9tID0gdGhpcy5fYXBwLnJlcXVpcmVNb2R1bGUoJ2RvbScpXG4gICAgZG9tLnNjcm9sbFRvRWxlbWVudChlbC5yZWYsIHsgb2Zmc2V0OiBvZmZzZXQgfSlcbiAgfVxufVxuXG4vKipcbiAqIHBlcmZvcm0gdHJhbnNpdGlvbiBhbmltYXRpb24gb24gYW4gZWxlbWVudCBzcGVjaWZpZWQgYnkgaWRcbiAqIEBwYXJhbSAge3N0cmluZ30gICBpZFxuICogQHBhcmFtICB7b2JqZWN0fSAgIG9wdGlvbnNcbiAqIEBwYXJhbSAge29iamVjdH0gICBvcHRpb25zLnN0eWxlc1xuICogQHBhcmFtICB7b2JqZWN0fSAgIG9wdGlvbnMuZHVyYXRpb24obXMpXG4gKiBAcGFyYW0gIHtvYmplY3R9ICAgW29wdGlvbnMudGltaW5nRnVuY3Rpb25dXG4gKiBAcGFyYW0gIHtvYmplY3R9ICAgW29wdGlvbnMuZGVsYXk9MChtcyldXG4gKiBAcGFyYW0gIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uICR0cmFuc2l0aW9uIChpZCwgb3B0aW9ucywgY2FsbGJhY2spIHtcbiAgY29uc3QgZWwgPSB0aGlzLiRlbChpZClcbiAgaWYgKGVsICYmIG9wdGlvbnMgJiYgb3B0aW9ucy5zdHlsZXMpIHtcbiAgICBjb25zdCBhbmltYXRpb24gPSB0aGlzLl9hcHAucmVxdWlyZU1vZHVsZSgnYW5pbWF0aW9uJylcbiAgICBhbmltYXRpb24udHJhbnNpdGlvbihlbC5yZWYsIG9wdGlvbnMsICguLi5hcmdzKSA9PiB7XG4gICAgICB0aGlzLl9zZXRTdHlsZShlbCwgb3B0aW9ucy5zdHlsZXMpXG4gICAgICBjYWxsYmFjayAmJiBjYWxsYmFjayguLi5hcmdzKVxuICAgIH0pXG4gIH1cbn1cblxuLyoqXG4gKiBnZXQgc29tZSBjb25maWdcbiAqIEByZXR1cm4ge29iamVjdH0gc29tZSBjb25maWcgZm9yIGFwcCBpbnN0YW5jZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IGJ1bmRsZVVybFxuICogQHByb3BlcnR5IHtib29sZWFufSBkZWJ1Z1xuICogQHByb3BlcnR5IHtvYmplY3R9IGVudlxuICogQHByb3BlcnR5IHtzdHJpbmd9IGVudi53ZWV4VmVyc2lvbihleC4gMS4wLjApXG4gKiBAcHJvcGVydHkge3N0cmluZ30gZW52LmFwcE5hbWUoZXguIFRCL1RNKVxuICogQHByb3BlcnR5IHtzdHJpbmd9IGVudi5hcHBWZXJzaW9uKGV4LiA1LjAuMClcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBlbnYucGxhdGZvcm0oZXguIGlPUy9BbmRyb2lkKVxuICogQHByb3BlcnR5IHtzdHJpbmd9IGVudi5vc1ZlcnNpb24oZXguIDcuMC4wKVxuICogQHByb3BlcnR5IHtzdHJpbmd9IGVudi5kZXZpY2VNb2RlbCAqKm5hdGl2ZSBvbmx5KipcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBlbnYuW2RldmljZVdpZHRoPTc1MF1cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBlbnYuZGV2aWNlSGVpZ2h0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiAkZ2V0Q29uZmlnIChjYWxsYmFjaykge1xuICBjb25zdCBjb25maWcgPSB0aGlzLl9hcHAub3B0aW9uc1xuICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY29uc29sZS53YXJuKCdbSlMgRnJhbWV3b3JrXSB0aGUgY2FsbGJhY2sgb2YgVm0jJGdldENvbmZpZyhjYWxsYmFjaykgaXMgZGVwcmVjYXRlZCwgJyArXG4gICAgICAndGhpcyBhcGkgbm93IGNhbiBkaXJlY3RseSBSRVRVUk4gY29uZmlnIGluZm8uJylcbiAgICBjYWxsYmFjayhjb25maWcpXG4gIH1cbiAgcmV0dXJuIGNvbmZpZ1xufVxuXG4vKipcbiAqIEBkZXByZWNhdGVkXG4gKiByZXF1ZXN0IG5ldHdvcmsgdmlhIGh0dHAgcHJvdG9jb2xcbiAqIEBwYXJhbSAge29iamVjdH0gICBwYXJhbXNcbiAqIEBwYXJhbSAge0Z1bmN0aW9ufSBjYWxsYmFja1xuICovXG5leHBvcnQgZnVuY3Rpb24gJHNlbmRIdHRwIChwYXJhbXMsIGNhbGxiYWNrKSB7XG4gIGNvbnNvbGUud2FybignW0pTIEZyYW1ld29ya10gVm0jJHNlbmRIdHRwIGlzIGRlcHJlY2F0ZWQsICcgK1xuICAgICAgICAgICdwbGVhc2UgdXNlIFwicmVxdWlyZShcXCdAd2VleC1tb2R1bGUvc3RyZWFtXFwnKScgK1xuICAgICAgICAgICcuc2VuZEh0dHAocGFyYW1zLCBjYWxsYmFjaylcIiBpbnN0ZWFkJylcbiAgY29uc3Qgc3RyZWFtID0gdGhpcy5fYXBwLnJlcXVpcmVNb2R1bGUoJ3N0cmVhbScpXG4gIHN0cmVhbS5zZW5kSHR0cChwYXJhbXMsIGNhbGxiYWNrKVxufVxuXG4vKipcbiAqIEBkZXByZWNhdGVkXG4gKiBvcGVuIGEgdXJsXG4gKiBAcGFyYW0gIHtzdHJpbmd9IHVybFxuICovXG5leHBvcnQgZnVuY3Rpb24gJG9wZW5VUkwgKHVybCkge1xuICBjb25zb2xlLndhcm4oJ1tKUyBGcmFtZXdvcmtdIFZtIyRvcGVuVVJMIGlzIGRlcHJlY2F0ZWQsICcgK1xuICAgICAgICAgICdwbGVhc2UgdXNlIFwicmVxdWlyZShcXCdAd2VleC1tb2R1bGUvZXZlbnRcXCcpJyArXG4gICAgICAgICAgJy5vcGVuVVJMKHVybClcIiBpbnN0ZWFkJylcbiAgY29uc3QgZXZlbnQgPSB0aGlzLl9hcHAucmVxdWlyZU1vZHVsZSgnZXZlbnQnKVxuICBldmVudC5vcGVuVVJMKHVybClcbn1cblxuLyoqXG4gKiBAZGVwcmVjYXRlZFxuICogc2V0IGEgdGl0bGUgZm9yIHBhZ2VcbiAqIEBwYXJhbSAge3N0cmluZ30gdGl0bGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uICRzZXRUaXRsZSAodGl0bGUpIHtcbiAgY29uc29sZS53YXJuKCdbSlMgRnJhbWV3b3JrXSBWbSMkc2V0VGl0bGUgaXMgZGVwcmVjYXRlZCwgJyArXG4gICAgICAgICAgJ3BsZWFzZSB1c2UgXCJyZXF1aXJlKFxcJ0B3ZWV4LW1vZHVsZS9wYWdlSW5mb1xcJyknICtcbiAgICAgICAgICAnLnNldFRpdGxlKHRpdGxlKVwiIGluc3RlYWQnKVxuICBjb25zdCBwYWdlSW5mbyA9IHRoaXMuX2FwcC5yZXF1aXJlTW9kdWxlKCdwYWdlSW5mbycpXG4gIHBhZ2VJbmZvLnNldFRpdGxlKHRpdGxlKVxufVxuXG4vKipcbiAqIEBkZXByZWNhdGVkIHVzZSBcInJlcXVpcmUoJ0B3ZWV4LW1vZHVsZS9tb2R1bGVOYW1lJykgaW5zdGVhZFwiXG4gKiBpbnZva2UgYSBuYXRpdmUgbWV0aG9kIGJ5IHNwZWNpZmluZyB0aGUgbmFtZSBvZiBtb2R1bGUgYW5kIG1ldGhvZFxuICogQHBhcmFtICB7c3RyaW5nfSBtb2R1bGVOYW1lXG4gKiBAcGFyYW0gIHtzdHJpbmd9IG1ldGhvZE5hbWVcbiAqIEBwYXJhbSAgey4uLip9IHRoZSByZXN0IGFyZ3VtZW50c1xuICovXG5leHBvcnQgZnVuY3Rpb24gJGNhbGwgKG1vZHVsZU5hbWUsIG1ldGhvZE5hbWUsIC4uLmFyZ3MpIHtcbiAgY29uc29sZS53YXJuKCdbSlMgRnJhbWV3b3JrXSBWbSMkY2FsbCBpcyBkZXByZWNhdGVkLCAnICtcbiAgICAncGxlYXNlIHVzZSBcInJlcXVpcmUoXFwnQHdlZXgtbW9kdWxlL21vZHVsZU5hbWVcXCcpXCIgaW5zdGVhZCcpXG4gIGNvbnN0IG1vZHVsZSA9IHRoaXMuX2FwcC5yZXF1aXJlTW9kdWxlKG1vZHVsZU5hbWUpXG4gIGlmIChtb2R1bGUgJiYgbW9kdWxlW21ldGhvZE5hbWVdKSB7XG4gICAgbW9kdWxlW21ldGhvZE5hbWVdKC4uLmFyZ3MpXG4gIH1cbn1cbiIsIi8qXG4gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lXG4gKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGVcbiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uXG4gKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlXG4gKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlXG4gKiBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2VcbiAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZyxcbiAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuXG4gKiBcIkFTIElTXCIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWVxuICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlXG4gKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zXG4gKiB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuLyoqXG4gKiBNaXggcHJvcGVydGllcyBpbnRvIHRhcmdldCBvYmplY3QuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHRvXG4gKiBAcGFyYW0ge09iamVjdH0gZnJvbVxuICovXG5cbmZ1bmN0aW9uIGV4dGVuZCAodGFyZ2V0LCAuLi5zcmMpIHtcbiAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgaWYgKHR5cGVvZiBPYmplY3QuYXNzaWduID09PSAnZnVuY3Rpb24nKSB7XG4gICAgT2JqZWN0LmFzc2lnbih0YXJnZXQsIC4uLnNyYylcbiAgfVxuICBlbHNlIHtcbiAgICBjb25zdCBmaXJzdCA9IHNyYy5zaGlmdCgpXG4gICAgZm9yIChjb25zdCBrZXkgaW4gZmlyc3QpIHtcbiAgICAgIHRhcmdldFtrZXldID0gZmlyc3Rba2V5XVxuICAgIH1cbiAgICBpZiAoc3JjLmxlbmd0aCkge1xuICAgICAgZXh0ZW5kKHRhcmdldCwgLi4uc3JjKVxuICAgIH1cbiAgfVxuICByZXR1cm4gdGFyZ2V0XG59XG5cbi8qKlxuICogRGVmaW5lIGEgcHJvcGVydHkuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICogQHBhcmFtIHtTdHJpbmd9IGtleVxuICogQHBhcmFtIHsqfSB2YWxcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gW2VudW1lcmFibGVdXG4gKi9cblxuZnVuY3Rpb24gZGVmIChvYmosIGtleSwgdmFsLCBlbnVtZXJhYmxlKSB7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIGtleSwge1xuICAgIHZhbHVlOiB2YWwsXG4gICAgZW51bWVyYWJsZTogISFlbnVtZXJhYmxlLFxuICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICB9KVxufVxuXG4vKipcbiAqIFJlbW92ZSBhbiBpdGVtIGZyb20gYW4gYXJyYXlcbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJcbiAqIEBwYXJhbSB7Kn0gaXRlbVxuICovXG5cbmZ1bmN0aW9uIHJlbW92ZSAoYXJyLCBpdGVtKSB7XG4gIGlmIChhcnIubGVuZ3RoKSB7XG4gICAgY29uc3QgaW5kZXggPSBhcnIuaW5kZXhPZihpdGVtKVxuICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICByZXR1cm4gYXJyLnNwbGljZShpbmRleCwgMSlcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBDaGVjayB3aGV0aGVyIHRoZSBvYmplY3QgaGFzIHRoZSBwcm9wZXJ0eS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKiBAcGFyYW0ge1N0cmluZ30ga2V5XG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5jb25zdCBoYXNPd25Qcm9wZXJ0eSA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHlcbmZ1bmN0aW9uIGhhc093biAob2JqLCBrZXkpIHtcbiAgcmV0dXJuIGhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpXG59XG5cbi8qKlxuICogU2ltcGxlIGJpbmQsIGZhc3RlciB0aGFuIG5hdGl2ZVxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcGFyYW0ge09iamVjdH0gY3R4XG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuXG5mdW5jdGlvbiBiaW5kIChmbiwgY3R4KSB7XG4gIHJldHVybiBmdW5jdGlvbiAoYSkge1xuICAgIGNvbnN0IGwgPSBhcmd1bWVudHMubGVuZ3RoXG4gICAgcmV0dXJuIGxcbiAgICAgID8gbCA+IDFcbiAgICAgICAgPyBmbi5hcHBseShjdHgsIGFyZ3VtZW50cylcbiAgICAgICAgOiBmbi5jYWxsKGN0eCwgYSlcbiAgICAgIDogZm4uY2FsbChjdHgpXG4gIH1cbn1cblxuLyoqXG4gKiBDb252ZXJ0IGFuIEFycmF5LWxpa2Ugb2JqZWN0IHRvIGEgcmVhbCBBcnJheS5cbiAqXG4gKiBAcGFyYW0ge0FycmF5LWxpa2V9IGxpc3RcbiAqIEBwYXJhbSB7TnVtYmVyfSBbc3RhcnRdIC0gc3RhcnQgaW5kZXhcbiAqIEByZXR1cm4ge0FycmF5fVxuICovXG5cbmZ1bmN0aW9uIHRvQXJyYXkgKGxpc3QsIHN0YXJ0KSB7XG4gIHN0YXJ0ID0gc3RhcnQgfHwgMFxuICBsZXQgaSA9IGxpc3QubGVuZ3RoIC0gc3RhcnRcbiAgY29uc3QgcmV0ID0gbmV3IEFycmF5KGkpXG4gIHdoaWxlIChpLS0pIHtcbiAgICByZXRbaV0gPSBsaXN0W2kgKyBzdGFydF1cbiAgfVxuICByZXR1cm4gcmV0XG59XG5cbi8qKlxuICogUXVpY2sgb2JqZWN0IGNoZWNrIC0gdGhpcyBpcyBwcmltYXJpbHkgdXNlZCB0byB0ZWxsXG4gKiBPYmplY3RzIGZyb20gcHJpbWl0aXZlIHZhbHVlcyB3aGVuIHdlIGtub3cgdGhlIHZhbHVlXG4gKiBpcyBhIEpTT04tY29tcGxpYW50IHR5cGUuXG4gKlxuICogQHBhcmFtIHsqfSBvYmpcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cblxuZnVuY3Rpb24gaXNPYmplY3QgKG9iaikge1xuICByZXR1cm4gb2JqICE9PSBudWxsICYmIHR5cGVvZiBvYmogPT09ICdvYmplY3QnXG59XG5cbi8qKlxuICogU3RyaWN0IG9iamVjdCB0eXBlIGNoZWNrLiBPbmx5IHJldHVybnMgdHJ1ZVxuICogZm9yIHBsYWluIEphdmFTY3JpcHQgb2JqZWN0cy5cbiAqXG4gKiBAcGFyYW0geyp9IG9ialxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuXG5jb25zdCB0b1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmdcbmNvbnN0IE9CSkVDVF9TVFJJTkcgPSAnW29iamVjdCBPYmplY3RdJ1xuZnVuY3Rpb24gaXNQbGFpbk9iamVjdCAob2JqKSB7XG4gIHJldHVybiB0b1N0cmluZy5jYWxsKG9iaikgPT09IE9CSkVDVF9TVFJJTkdcbn1cblxuZXhwb3J0IHtcbiAgZXh0ZW5kLFxuICBkZWYsXG4gIHJlbW92ZSxcbiAgaGFzT3duLFxuICBiaW5kLFxuICB0b0FycmF5LFxuICBpc09iamVjdCxcbiAgaXNQbGFpbk9iamVjdFxufVxuIiwiLypcbiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmVcbiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZVxuICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb25cbiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGVcbiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGVcbiAqIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZVxuICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLFxuICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW5cbiAqIFwiQVMgSVNcIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXG4gKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGVcbiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnNcbiAqIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5leHBvcnQge1xuICBleHRlbmQsXG4gIGRlZixcbiAgcmVtb3ZlLFxuICBoYXNPd24sXG4gIGJpbmQsXG4gIHRvQXJyYXksXG4gIGlzT2JqZWN0LFxuICBpc1BsYWluT2JqZWN0XG59IGZyb20gJy4vc2hhcmVkJ1xuXG4vKipcbiAqIENoZWNrIGlmIGEgc3RyaW5nIHN0YXJ0cyB3aXRoICQgb3IgX1xuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGlzUmVzZXJ2ZWQgKHN0cikge1xuICBjb25zdCBjID0gKHN0ciArICcnKS5jaGFyQ29kZUF0KDApXG4gIHJldHVybiBjID09PSAweDI0IHx8IGMgPT09IDB4NUZcbn1cblxuLy8gY2FuIHdlIHVzZSBfX3Byb3RvX18/XG5leHBvcnQgY29uc3QgaGFzUHJvdG8gPSAnX19wcm90b19fJyBpbiB7fVxuXG5sZXQgX1NldFxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbmlmICh0eXBlb2YgU2V0ICE9PSAndW5kZWZpbmVkJyAmJiBTZXQudG9TdHJpbmcoKS5tYXRjaCgvbmF0aXZlIGNvZGUvKSkge1xuICAvLyB1c2UgbmF0aXZlIFNldCB3aGVuIGF2YWlsYWJsZS5cbiAgX1NldCA9IFNldFxufVxuZWxzZSB7XG4gIC8vIGEgbm9uLXN0YW5kYXJkIFNldCBwb2x5ZmlsbCB0aGF0IG9ubHkgd29ya3Mgd2l0aCBwcmltaXRpdmUga2V5cy5cbiAgX1NldCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnNldCA9IE9iamVjdC5jcmVhdGUobnVsbClcbiAgfVxuICBfU2V0LnByb3RvdHlwZS5oYXMgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuIHRoaXMuc2V0W2tleV0gIT09IHVuZGVmaW5lZFxuICB9XG4gIF9TZXQucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICBpZiAoa2V5ID09IG51bGwgfHwgdGhpcy5zZXRba2V5XSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIHRoaXMuc2V0W2tleV0gPSAxXG4gIH1cbiAgX1NldC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5zZXQgPSBPYmplY3QuY3JlYXRlKG51bGwpXG4gIH1cbn1cblxuZXhwb3J0IHsgX1NldCB9XG5cbi8qKlxuICogUG9seWZpbGwgaW4gaU9TNyBieSBuYXRpdmUgYmVjYXVzZSB0aGUgSmF2YVNjcmlwdCBwb2x5ZmlsbCBoYXMgbWVtb3J5IHByb2JsZW0uXG4gKiBAcmV0dXJuIHtvYmplY3R9XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU5ld1NldCAoKSB7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gIC8qIGVzbGludC1kaXNhYmxlICovXG4gIGlmICh0eXBlb2YgbmF0aXZlU2V0ID09PSAnb2JqZWN0Jykge1xuICAgIHJldHVybiBuYXRpdmVTZXQuY3JlYXRlKClcbiAgfVxuICAvKiBlc2xpbnQtZW5hYmxlICovXG4gIHJldHVybiBuZXcgX1NldCgpXG59XG5cbi8qKlxuICogQ3JlYXRlIGEgY2FjaGVkIHZlcnNpb24gb2YgYSBwdXJlIGZ1bmN0aW9uLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY2FjaGVkIChmbikge1xuICBjb25zdCBjYWNoZSA9IE9iamVjdC5jcmVhdGUobnVsbClcbiAgcmV0dXJuIGZ1bmN0aW9uIGNhY2hlZEZuIChzdHIpIHtcbiAgICBjb25zdCBoaXQgPSBjYWNoZVtzdHJdXG4gICAgcmV0dXJuIGhpdCB8fCAoY2FjaGVbc3RyXSA9IGZuKHN0cikpXG4gIH1cbn1cblxuLyoqXG4gKiBDYW1lbGl6ZSBhIGh5cGhlbi1kZWxtaXRlZCBzdHJpbmcuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5cbmNvbnN0IGNhbWVsaXplUkUgPSAvLShcXHcpL2dcbmV4cG9ydCBjb25zdCBjYW1lbGl6ZSA9IGNhY2hlZChzdHIgPT4ge1xuICByZXR1cm4gc3RyLnJlcGxhY2UoY2FtZWxpemVSRSwgdG9VcHBlcilcbn0pXG5cbmZ1bmN0aW9uIHRvVXBwZXIgKF8sIGMpIHtcbiAgcmV0dXJuIGMgPyBjLnRvVXBwZXJDYXNlKCkgOiAnJ1xufVxuXG4vKipcbiAqIEh5cGhlbmF0ZSBhIGNhbWVsQ2FzZSBzdHJpbmcuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5cbmNvbnN0IGh5cGhlbmF0ZVJFID0gLyhbYS16XFxkXSkoW0EtWl0pL2dcbmV4cG9ydCBjb25zdCBoeXBoZW5hdGUgPSBjYWNoZWQoc3RyID0+IHtcbiAgcmV0dXJuIHN0clxuICAgIC5yZXBsYWNlKGh5cGhlbmF0ZVJFLCAnJDEtJDInKVxuICAgIC50b0xvd2VyQ2FzZSgpXG59KVxuXG5leHBvcnQgZnVuY3Rpb24gdHlwb2YgKHYpIHtcbiAgY29uc3QgcyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2KVxuICByZXR1cm4gcy5zdWJzdHJpbmcoOCwgcy5sZW5ndGggLSAxKS50b0xvd2VyQ2FzZSgpXG59XG5cbi8vIHdlZXggbmFtZSBydWxlc1xuXG5jb25zdCBXRUVYX0NPTVBPTkVOVF9SRUcgPSAvXkB3ZWV4LWNvbXBvbmVudFxcLy9cbmNvbnN0IFdFRVhfTU9EVUxFX1JFRyA9IC9eQHdlZXgtbW9kdWxlXFwvL1xuY29uc3QgTk9STUFMX01PRFVMRV9SRUcgPSAvXlxcLnsxLDJ9XFwvL1xuY29uc3QgSlNfU1VSRklYX1JFRyA9IC9cXC5qcyQvXG5cbmV4cG9ydCBjb25zdCBpc1dlZXhDb21wb25lbnQgPSBuYW1lID0+ICEhbmFtZS5tYXRjaChXRUVYX0NPTVBPTkVOVF9SRUcpXG5leHBvcnQgY29uc3QgaXNXZWV4TW9kdWxlID0gbmFtZSA9PiAhIW5hbWUubWF0Y2goV0VFWF9NT0RVTEVfUkVHKVxuZXhwb3J0IGNvbnN0IGlzTm9ybWFsTW9kdWxlID0gbmFtZSA9PiAhIW5hbWUubWF0Y2goTk9STUFMX01PRFVMRV9SRUcpXG5leHBvcnQgY29uc3QgaXNOcG1Nb2R1bGUgPSBuYW1lID0+ICFpc1dlZXhDb21wb25lbnQobmFtZSkgJiYgIWlzV2VleE1vZHVsZShuYW1lKSAmJiAhaXNOb3JtYWxNb2R1bGUobmFtZSlcblxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZVdlZXhQcmVmaXggKHN0cikge1xuICBjb25zdCByZXN1bHQgPSBzdHIucmVwbGFjZShXRUVYX0NPTVBPTkVOVF9SRUcsICcnKS5yZXBsYWNlKFdFRVhfTU9EVUxFX1JFRywgJycpXG4gIHJldHVybiByZXN1bHRcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZUpTU3VyZml4IChzdHIpIHtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKEpTX1NVUkZJWF9SRUcsICcnKVxufVxuIiwiLyogZXNsaW50LWRpc2FibGUgKi9cblxuXG5pbXBvcnQgeyByZW1vdmUgfSBmcm9tICcuLi91dGlsL2luZGV4J1xuXG5sZXQgdWlkID0gMFxuXG4vKipcbiAqIEEgZGVwIGlzIGFuIG9ic2VydmFibGUgdGhhdCBjYW4gaGF2ZSBtdWx0aXBsZVxuICogZGlyZWN0aXZlcyBzdWJzY3JpYmluZyB0byBpdC5cbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBEZXAgKCkge1xuICB0aGlzLmlkID0gdWlkKytcbiAgdGhpcy5zdWJzID0gW11cbn1cblxuLy8gdGhlIGN1cnJlbnQgdGFyZ2V0IHdhdGNoZXIgYmVpbmcgZXZhbHVhdGVkLlxuLy8gdGhpcyBpcyBnbG9iYWxseSB1bmlxdWUgYmVjYXVzZSB0aGVyZSBjb3VsZCBiZSBvbmx5IG9uZVxuLy8gd2F0Y2hlciBiZWluZyBldmFsdWF0ZWQgYXQgYW55IHRpbWUuXG5EZXAudGFyZ2V0ID0gbnVsbFxubGV0IHRhcmdldFN0YWNrID0gW11cblxuZXhwb3J0IGZ1bmN0aW9uIHB1c2hUYXJnZXQgKF90YXJnZXQpIHtcbiAgaWYgKERlcC50YXJnZXQpIHRhcmdldFN0YWNrLnB1c2goRGVwLnRhcmdldClcbiAgRGVwLnRhcmdldCA9IF90YXJnZXRcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBvcFRhcmdldCAoKSB7XG4gIERlcC50YXJnZXQgPSB0YXJnZXRTdGFjay5wb3AoKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVzZXRUYXJnZXQgKCkge1xuICBEZXAudGFyZ2V0ID0gbnVsbFxuICB0YXJnZXRTdGFjayA9IFtdXG59XG5cbi8qKlxuICogQWRkIGEgZGlyZWN0aXZlIHN1YnNjcmliZXIuXG4gKlxuICogQHBhcmFtIHtEaXJlY3RpdmV9IHN1YlxuICovXG5cbkRlcC5wcm90b3R5cGUuYWRkU3ViID0gZnVuY3Rpb24gKHN1Yikge1xuICB0aGlzLnN1YnMucHVzaChzdWIpXG59XG5cbi8qKlxuICogUmVtb3ZlIGEgZGlyZWN0aXZlIHN1YnNjcmliZXIuXG4gKlxuICogQHBhcmFtIHtEaXJlY3RpdmV9IHN1YlxuICovXG5cbkRlcC5wcm90b3R5cGUucmVtb3ZlU3ViID0gZnVuY3Rpb24gKHN1Yikge1xuICByZW1vdmUodGhpcy5zdWJzLCBzdWIpXG59XG5cbi8qKlxuICogQWRkIHNlbGYgYXMgYSBkZXBlbmRlbmN5IHRvIHRoZSB0YXJnZXQgd2F0Y2hlci5cbiAqL1xuXG5EZXAucHJvdG90eXBlLmRlcGVuZCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKERlcC50YXJnZXQpIHtcbiAgICBEZXAudGFyZ2V0LmFkZERlcCh0aGlzKVxuICB9XG59XG5cbi8qKlxuICogTm90aWZ5IGFsbCBzdWJzY3JpYmVycyBvZiBhIG5ldyB2YWx1ZS5cbiAqL1xuXG5EZXAucHJvdG90eXBlLm5vdGlmeSA9IGZ1bmN0aW9uICgpIHtcbiAgLy8gc3RhYmxpemUgdGhlIHN1YnNjcmliZXIgbGlzdCBmaXJzdFxuICBjb25zdCBzdWJzID0gdGhpcy5zdWJzLnNsaWNlKClcbiAgZm9yIChsZXQgaSA9IDAsIGwgPSBzdWJzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIHN1YnNbaV0udXBkYXRlKClcbiAgfVxufVxuIiwiLyogZXNsaW50LWRpc2FibGUgKi9cblxuXG5pbXBvcnQgRGVwLCB7IHB1c2hUYXJnZXQsIHBvcFRhcmdldCB9IGZyb20gJy4vZGVwJ1xuLy8gaW1wb3J0IHsgcHVzaFdhdGNoZXIgfSBmcm9tICcuL2JhdGNoZXInXG5pbXBvcnQge1xuICByZW1vdmUsXG4gIGV4dGVuZCxcbiAgaXNPYmplY3QsXG4gIGNyZWF0ZU5ld1NldFxuICAvLyBfU2V0IGFzIFNldFxufSBmcm9tICcuLi91dGlsL2luZGV4J1xuXG5sZXQgdWlkID0gMFxuXG4vKipcbiAqIEEgd2F0Y2hlciBwYXJzZXMgYW4gZXhwcmVzc2lvbiwgY29sbGVjdHMgZGVwZW5kZW5jaWVzLFxuICogYW5kIGZpcmVzIGNhbGxiYWNrIHdoZW4gdGhlIGV4cHJlc3Npb24gdmFsdWUgY2hhbmdlcy5cbiAqIFRoaXMgaXMgdXNlZCBmb3IgYm90aCB0aGUgJHdhdGNoKCkgYXBpIGFuZCBkaXJlY3RpdmVzLlxuICpcbiAqIEBwYXJhbSB7VnVlfSB2bVxuICogQHBhcmFtIHtTdHJpbmd8RnVuY3Rpb259IGV4cE9yRm5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNiXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogICAgICAgICAgICAgICAgIC0ge0FycmF5fSBmaWx0ZXJzXG4gKiAgICAgICAgICAgICAgICAgLSB7Qm9vbGVhbn0gdHdvV2F5XG4gKiAgICAgICAgICAgICAgICAgLSB7Qm9vbGVhbn0gZGVlcFxuICogICAgICAgICAgICAgICAgIC0ge0Jvb2xlYW59IHVzZXJcbiAqICAgICAgICAgICAgICAgICAtIHtCb29sZWFufSBzeW5jXG4gKiAgICAgICAgICAgICAgICAgLSB7Qm9vbGVhbn0gbGF6eVxuICogICAgICAgICAgICAgICAgIC0ge0Z1bmN0aW9ufSBbcHJlUHJvY2Vzc11cbiAqICAgICAgICAgICAgICAgICAtIHtGdW5jdGlvbn0gW3Bvc3RQcm9jZXNzXVxuICogQGNvbnN0cnVjdG9yXG4gKi9cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gV2F0Y2hlciAodm0sIGV4cE9yRm4sIGNiLCBvcHRpb25zKSB7XG4gIC8vIG1peCBpbiBvcHRpb25zXG4gIGlmIChvcHRpb25zKSB7XG4gICAgZXh0ZW5kKHRoaXMsIG9wdGlvbnMpXG4gIH1cbiAgY29uc3QgaXNGbiA9IHR5cGVvZiBleHBPckZuID09PSAnZnVuY3Rpb24nXG4gIHRoaXMudm0gPSB2bVxuICB2bS5fd2F0Y2hlcnMucHVzaCh0aGlzKVxuICB0aGlzLmV4cHJlc3Npb24gPSBleHBPckZuXG4gIHRoaXMuY2IgPSBjYlxuICB0aGlzLmlkID0gKyt1aWQgLy8gdWlkIGZvciBiYXRjaGluZ1xuICB0aGlzLmFjdGl2ZSA9IHRydWVcbiAgdGhpcy5kaXJ0eSA9IHRoaXMubGF6eSAvLyBmb3IgbGF6eSB3YXRjaGVyc1xuICB0aGlzLmRlcHMgPSBbXVxuICB0aGlzLm5ld0RlcHMgPSBbXVxuICB0aGlzLmRlcElkcyA9IGNyZWF0ZU5ld1NldCgpIC8vIG5ldyBTZXQoKVxuICB0aGlzLm5ld0RlcElkcyA9IGNyZWF0ZU5ld1NldCgpIC8vIG5ldyBTZXQoKVxuICAvLyBwYXJzZSBleHByZXNzaW9uIGZvciBnZXR0ZXJcbiAgaWYgKGlzRm4pIHtcbiAgICB0aGlzLmdldHRlciA9IGV4cE9yRm5cbiAgfVxuICB0aGlzLnZhbHVlID0gdGhpcy5sYXp5XG4gICAgPyB1bmRlZmluZWRcbiAgICA6IHRoaXMuZ2V0KClcbiAgLy8gc3RhdGUgZm9yIGF2b2lkaW5nIGZhbHNlIHRyaWdnZXJzIGZvciBkZWVwIGFuZCBBcnJheVxuICAvLyB3YXRjaGVycyBkdXJpbmcgdm0uX2RpZ2VzdCgpXG4gIHRoaXMucXVldWVkID0gdGhpcy5zaGFsbG93ID0gZmFsc2Vcbn1cblxuLyoqXG4gKiBFdmFsdWF0ZSB0aGUgZ2V0dGVyLCBhbmQgcmUtY29sbGVjdCBkZXBlbmRlbmNpZXMuXG4gKi9cblxuV2F0Y2hlci5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKCkge1xuICBwdXNoVGFyZ2V0KHRoaXMpXG4gIGNvbnN0IHZhbHVlID0gdGhpcy5nZXR0ZXIuY2FsbCh0aGlzLnZtLCB0aGlzLnZtKVxuICAvLyBcInRvdWNoXCIgZXZlcnkgcHJvcGVydHkgc28gdGhleSBhcmUgYWxsIHRyYWNrZWQgYXNcbiAgLy8gZGVwZW5kZW5jaWVzIGZvciBkZWVwIHdhdGNoaW5nXG4gIGlmICh0aGlzLmRlZXApIHtcbiAgICB0cmF2ZXJzZSh2YWx1ZSlcbiAgfVxuICBwb3BUYXJnZXQoKVxuICB0aGlzLmNsZWFudXBEZXBzKClcbiAgcmV0dXJuIHZhbHVlXG59XG5cbi8qKlxuICogQWRkIGEgZGVwZW5kZW5jeSB0byB0aGlzIGRpcmVjdGl2ZS5cbiAqXG4gKiBAcGFyYW0ge0RlcH0gZGVwXG4gKi9cblxuV2F0Y2hlci5wcm90b3R5cGUuYWRkRGVwID0gZnVuY3Rpb24gKGRlcCkge1xuICBjb25zdCBpZCA9IGRlcC5pZFxuICBpZiAoIXRoaXMubmV3RGVwSWRzLmhhcyhpZCkpIHtcbiAgICB0aGlzLm5ld0RlcElkcy5hZGQoaWQpXG4gICAgdGhpcy5uZXdEZXBzLnB1c2goZGVwKVxuICAgIGlmICghdGhpcy5kZXBJZHMuaGFzKGlkKSkge1xuICAgICAgZGVwLmFkZFN1Yih0aGlzKVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIENsZWFuIHVwIGZvciBkZXBlbmRlbmN5IGNvbGxlY3Rpb24uXG4gKi9cblxuV2F0Y2hlci5wcm90b3R5cGUuY2xlYW51cERlcHMgPSBmdW5jdGlvbiAoKSB7XG4gIGxldCBpID0gdGhpcy5kZXBzLmxlbmd0aFxuICB3aGlsZSAoaS0tKSB7XG4gICAgY29uc3QgZGVwID0gdGhpcy5kZXBzW2ldXG4gICAgaWYgKCF0aGlzLm5ld0RlcElkcy5oYXMoZGVwLmlkKSkge1xuICAgICAgZGVwLnJlbW92ZVN1Yih0aGlzKVxuICAgIH1cbiAgfVxuICBsZXQgdG1wID0gdGhpcy5kZXBJZHNcbiAgdGhpcy5kZXBJZHMgPSB0aGlzLm5ld0RlcElkc1xuICB0aGlzLm5ld0RlcElkcyA9IHRtcFxuICB0aGlzLm5ld0RlcElkcy5jbGVhcigpXG4gIHRtcCA9IHRoaXMuZGVwc1xuICB0aGlzLmRlcHMgPSB0aGlzLm5ld0RlcHNcbiAgdGhpcy5uZXdEZXBzID0gdG1wXG4gIHRoaXMubmV3RGVwcy5sZW5ndGggPSAwXG59XG5cbi8qKlxuICogU3Vic2NyaWJlciBpbnRlcmZhY2UuXG4gKiBXaWxsIGJlIGNhbGxlZCB3aGVuIGEgZGVwZW5kZW5jeSBjaGFuZ2VzLlxuICpcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gc2hhbGxvd1xuICovXG5cbldhdGNoZXIucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIChzaGFsbG93KSB7XG4gIGlmICh0aGlzLmxhenkpIHtcbiAgICB0aGlzLmRpcnR5ID0gdHJ1ZVxuICB9IGVsc2Uge1xuICAgIHRoaXMucnVuKClcbiAgfVxuICAvLyB9IGVsc2UgaWYgKHRoaXMuc3luYykge1xuICAvLyAgIHRoaXMucnVuKClcbiAgLy8gfSBlbHNlIHtcbiAgLy8gICAvLyBpZiBxdWV1ZWQsIG9ubHkgb3ZlcndyaXRlIHNoYWxsb3cgd2l0aCBub24tc2hhbGxvdyxcbiAgLy8gICAvLyBidXQgbm90IHRoZSBvdGhlciB3YXkgYXJvdW5kLlxuICAvLyAgIHRoaXMuc2hhbGxvdyA9IHRoaXMucXVldWVkXG4gIC8vICAgICA/IHNoYWxsb3dcbiAgLy8gICAgICAgPyB0aGlzLnNoYWxsb3dcbiAgLy8gICAgICAgOiBmYWxzZVxuICAvLyAgICAgOiAhIXNoYWxsb3dcbiAgLy8gICB0aGlzLnF1ZXVlZCA9IHRydWVcbiAgLy8gICBwdXNoV2F0Y2hlcih0aGlzKVxuICAvLyB9XG59XG5cbi8qKlxuICogQmF0Y2hlciBqb2IgaW50ZXJmYWNlLlxuICogV2lsbCBiZSBjYWxsZWQgYnkgdGhlIGJhdGNoZXIuXG4gKi9cblxuV2F0Y2hlci5wcm90b3R5cGUucnVuID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5hY3RpdmUpIHtcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZ2V0KClcbiAgICBpZiAoXG4gICAgICB2YWx1ZSAhPT0gdGhpcy52YWx1ZSB8fFxuICAgICAgLy8gRGVlcCB3YXRjaGVycyBhbmQgd2F0Y2hlcnMgb24gT2JqZWN0L0FycmF5cyBzaG91bGQgZmlyZSBldmVuXG4gICAgICAvLyB3aGVuIHRoZSB2YWx1ZSBpcyB0aGUgc2FtZSwgYmVjYXVzZSB0aGUgdmFsdWUgbWF5XG4gICAgICAvLyBoYXZlIG11dGF0ZWQ7IGJ1dCBvbmx5IGRvIHNvIGlmIHRoaXMgaXMgYVxuICAgICAgLy8gbm9uLXNoYWxsb3cgdXBkYXRlIChjYXVzZWQgYnkgYSB2bSBkaWdlc3QpLlxuICAgICAgKChpc09iamVjdCh2YWx1ZSkgfHwgdGhpcy5kZWVwKSAmJiAhdGhpcy5zaGFsbG93KVxuICAgICkge1xuICAgICAgLy8gc2V0IG5ldyB2YWx1ZVxuICAgICAgY29uc3Qgb2xkVmFsdWUgPSB0aGlzLnZhbHVlXG4gICAgICB0aGlzLnZhbHVlID0gdmFsdWVcbiAgICAgIHRoaXMuY2IuY2FsbCh0aGlzLnZtLCB2YWx1ZSwgb2xkVmFsdWUpXG4gICAgfVxuICAgIHRoaXMucXVldWVkID0gdGhpcy5zaGFsbG93ID0gZmFsc2VcbiAgfVxufVxuXG4vKipcbiAqIEV2YWx1YXRlIHRoZSB2YWx1ZSBvZiB0aGUgd2F0Y2hlci5cbiAqIFRoaXMgb25seSBnZXRzIGNhbGxlZCBmb3IgbGF6eSB3YXRjaGVycy5cbiAqL1xuXG5XYXRjaGVyLnByb3RvdHlwZS5ldmFsdWF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy52YWx1ZSA9IHRoaXMuZ2V0KClcbiAgdGhpcy5kaXJ0eSA9IGZhbHNlXG59XG5cbi8qKlxuICogRGVwZW5kIG9uIGFsbCBkZXBzIGNvbGxlY3RlZCBieSB0aGlzIHdhdGNoZXIuXG4gKi9cblxuV2F0Y2hlci5wcm90b3R5cGUuZGVwZW5kID0gZnVuY3Rpb24gKCkge1xuICBsZXQgaSA9IHRoaXMuZGVwcy5sZW5ndGhcbiAgd2hpbGUgKGktLSkge1xuICAgIHRoaXMuZGVwc1tpXS5kZXBlbmQoKVxuICB9XG59XG5cbi8qKlxuICogUmVtb3ZlIHNlbGYgZnJvbSBhbGwgZGVwZW5kZW5jaWVzJyBzdWJjcmliZXIgbGlzdC5cbiAqL1xuXG5XYXRjaGVyLnByb3RvdHlwZS50ZWFyZG93biA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuYWN0aXZlKSB7XG4gICAgLy8gcmVtb3ZlIHNlbGYgZnJvbSB2bSdzIHdhdGNoZXIgbGlzdFxuICAgIC8vIHRoaXMgaXMgYSBzb21ld2hhdCBleHBlbnNpdmUgb3BlcmF0aW9uIHNvIHdlIHNraXAgaXRcbiAgICAvLyBpZiB0aGUgdm0gaXMgYmVpbmcgZGVzdHJveWVkIG9yIGlzIHBlcmZvcm1pbmcgYSB2LWZvclxuICAgIC8vIHJlLXJlbmRlciAodGhlIHdhdGNoZXIgbGlzdCBpcyB0aGVuIGZpbHRlcmVkIGJ5IHYtZm9yKS5cbiAgICBpZiAoIXRoaXMudm0uX2lzQmVpbmdEZXN0cm95ZWQgJiYgIXRoaXMudm0uX3ZGb3JSZW1vdmluZykge1xuICAgICAgcmVtb3ZlKHRoaXMudm0uX3dhdGNoZXJzLCB0aGlzKVxuICAgIH1cbiAgICBsZXQgaSA9IHRoaXMuZGVwcy5sZW5ndGhcbiAgICB3aGlsZSAoaS0tKSB7XG4gICAgICB0aGlzLmRlcHNbaV0ucmVtb3ZlU3ViKHRoaXMpXG4gICAgfVxuICAgIHRoaXMuYWN0aXZlID0gZmFsc2VcbiAgICB0aGlzLnZtID0gdGhpcy5jYiA9IHRoaXMudmFsdWUgPSBudWxsXG4gIH1cbn1cblxuLyoqXG4gKiBSZWNydXNpdmVseSB0cmF2ZXJzZSBhbiBvYmplY3QgdG8gZXZva2UgYWxsIGNvbnZlcnRlZFxuICogZ2V0dGVycywgc28gdGhhdCBldmVyeSBuZXN0ZWQgcHJvcGVydHkgaW5zaWRlIHRoZSBvYmplY3RcbiAqIGlzIGNvbGxlY3RlZCBhcyBhIFwiZGVlcFwiIGRlcGVuZGVuY3kuXG4gKlxuICogQHBhcmFtIHsqfSB2YWxcbiAqIEBwYXJhbSB7U2V0fSBzZWVuXG4gKi9cblxuY29uc3Qgc2Vlbk9iamVjdHMgPSBjcmVhdGVOZXdTZXQoKSAvLyBuZXcgU2V0KClcbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5mdW5jdGlvbiB0cmF2ZXJzZSAodmFsLCBzZWVuKSB7XG4gIGxldCBpLCBrZXlzLCBpc0EsIGlzT1xuICBpZiAoIXNlZW4pIHtcbiAgICBzZWVuID0gc2Vlbk9iamVjdHNcbiAgICBzZWVuLmNsZWFyKClcbiAgfVxuICBpc0EgPSBBcnJheS5pc0FycmF5KHZhbClcbiAgaXNPID0gaXNPYmplY3QodmFsKVxuICBpZiAoaXNBIHx8IGlzTykge1xuICAgIGlmICh2YWwuX19vYl9fKSB7XG4gICAgICBjb25zdCBkZXBJZCA9IHZhbC5fX29iX18uZGVwLmlkXG4gICAgICBpZiAoc2Vlbi5oYXMoZGVwSWQpKSB7XG4gICAgICAgIHJldHVyblxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2Vlbi5hZGQoZGVwSWQpXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChpc0EpIHtcbiAgICAgIGkgPSB2YWwubGVuZ3RoXG4gICAgICB3aGlsZSAoaS0tKSB0cmF2ZXJzZSh2YWxbaV0sIHNlZW4pXG4gICAgfSBlbHNlIGlmIChpc08pIHtcbiAgICAgIGtleXMgPSBPYmplY3Qua2V5cyh2YWwpXG4gICAgICBpID0ga2V5cy5sZW5ndGhcbiAgICAgIHdoaWxlIChpLS0pIHRyYXZlcnNlKHZhbFtrZXlzW2ldXSwgc2VlbilcbiAgICB9XG4gIH1cbn1cbiIsIi8qIGVzbGludC1kaXNhYmxlICovXG5cblxuaW1wb3J0IHsgZGVmIH0gZnJvbSAnLi4vdXRpbC9pbmRleCdcblxuY29uc3QgYXJyYXlQcm90byA9IEFycmF5LnByb3RvdHlwZVxuZXhwb3J0IGNvbnN0IGFycmF5TWV0aG9kcyA9IE9iamVjdC5jcmVhdGUoYXJyYXlQcm90bylcblxuLyoqXG4gKiBJbnRlcmNlcHQgbXV0YXRpbmcgbWV0aG9kcyBhbmQgZW1pdCBldmVudHNcbiAqL1xuXG47W1xuICAncHVzaCcsXG4gICdwb3AnLFxuICAnc2hpZnQnLFxuICAndW5zaGlmdCcsXG4gICdzcGxpY2UnLFxuICAnc29ydCcsXG4gICdyZXZlcnNlJ1xuXVxuLmZvckVhY2goZnVuY3Rpb24gKG1ldGhvZCkge1xuICAvLyBjYWNoZSBvcmlnaW5hbCBtZXRob2RcbiAgY29uc3Qgb3JpZ2luYWwgPSBhcnJheVByb3RvW21ldGhvZF1cbiAgZGVmKGFycmF5TWV0aG9kcywgbWV0aG9kLCBmdW5jdGlvbiBtdXRhdG9yICgpIHtcbiAgICAvLyBhdm9pZCBsZWFraW5nIGFyZ3VtZW50czpcbiAgICAvLyBodHRwOi8vanNwZXJmLmNvbS9jbG9zdXJlLXdpdGgtYXJndW1lbnRzXG4gICAgbGV0IGkgPSBhcmd1bWVudHMubGVuZ3RoXG4gICAgY29uc3QgYXJncyA9IG5ldyBBcnJheShpKVxuICAgIHdoaWxlIChpLS0pIHtcbiAgICAgIGFyZ3NbaV0gPSBhcmd1bWVudHNbaV1cbiAgICB9XG4gICAgY29uc3QgcmVzdWx0ID0gb3JpZ2luYWwuYXBwbHkodGhpcywgYXJncylcbiAgICBjb25zdCBvYiA9IHRoaXMuX19vYl9fXG4gICAgbGV0IGluc2VydGVkXG4gICAgc3dpdGNoIChtZXRob2QpIHtcbiAgICAgIGNhc2UgJ3B1c2gnOlxuICAgICAgICBpbnNlcnRlZCA9IGFyZ3NcbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgJ3Vuc2hpZnQnOlxuICAgICAgICBpbnNlcnRlZCA9IGFyZ3NcbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgJ3NwbGljZSc6XG4gICAgICAgIGluc2VydGVkID0gYXJncy5zbGljZSgyKVxuICAgICAgICBicmVha1xuICAgIH1cbiAgICBpZiAoaW5zZXJ0ZWQpIG9iLm9ic2VydmVBcnJheShpbnNlcnRlZClcbiAgICAvLyBub3RpZnkgY2hhbmdlXG4gICAgb2IuZGVwLm5vdGlmeSgpXG4gICAgcmV0dXJuIHJlc3VsdFxuICB9KVxufSlcblxuLyoqXG4gKiBTd2FwIHRoZSBlbGVtZW50IGF0IHRoZSBnaXZlbiBpbmRleCB3aXRoIGEgbmV3IHZhbHVlXG4gKiBhbmQgZW1pdHMgY29ycmVzcG9uZGluZyBldmVudC5cbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gaW5kZXhcbiAqIEBwYXJhbSB7Kn0gdmFsXG4gKiBAcmV0dXJuIHsqfSAtIHJlcGxhY2VkIGVsZW1lbnRcbiAqL1xuXG5kZWYoXG4gIGFycmF5UHJvdG8sXG4gICckc2V0JyxcbiAgZnVuY3Rpb24gJHNldCAoaW5kZXgsIHZhbCkge1xuICAgIGNvbnNvbGUud2FybihgW0pTIEZyYW1ld29ya10gXCJBcnJheS5wcm90b3R5cGUuJHNldFwiIGlzIG5vdCBhIHN0YW5kYXJkIEFQSSxgXG4gICAgICArIGAgaXQgd2lsbCBiZSByZW1vdmVkIGluIHRoZSBuZXh0IHZlcnNpb24uYClcbiAgICBpZiAoaW5kZXggPj0gdGhpcy5sZW5ndGgpIHtcbiAgICAgIHRoaXMubGVuZ3RoID0gaW5kZXggKyAxXG4gICAgfVxuICAgIHJldHVybiB0aGlzLnNwbGljZShpbmRleCwgMSwgdmFsKVswXVxuICB9XG4pXG5cbi8qKlxuICogQ29udmVuaWVuY2UgbWV0aG9kIHRvIHJlbW92ZSB0aGUgZWxlbWVudCBhdCBnaXZlbiBpbmRleC5cbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gaW5kZXhcbiAqIEBwYXJhbSB7Kn0gdmFsXG4gKi9cblxuZGVmKFxuICBhcnJheVByb3RvLFxuICAnJHJlbW92ZScsXG4gIGZ1bmN0aW9uICRyZW1vdmUgKGluZGV4KSB7XG4gICAgY29uc29sZS53YXJuKGBbSlMgRnJhbWV3b3JrXSBcIkFycmF5LnByb3RvdHlwZS4kcmVtb3ZlXCIgaXMgbm90IGEgc3RhbmRhcmQgQVBJLGBcbiAgICAgICsgYCBpdCB3aWxsIGJlIHJlbW92ZWQgaW4gdGhlIG5leHQgdmVyc2lvbi5gKVxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgIGlmICghdGhpcy5sZW5ndGgpIHJldHVyblxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgaWYgKHR5cGVvZiBpbmRleCAhPT0gJ251bWJlcicpIHtcbiAgICAgIGluZGV4ID0gdGhpcy5pbmRleE9mKGluZGV4KVxuICAgIH1cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICB0aGlzLnNwbGljZShpbmRleCwgMSlcbiAgICB9XG4gIH1cbilcbiIsIi8qIGVzbGludC1kaXNhYmxlICovXG5cblxuaW1wb3J0IERlcCBmcm9tICcuL2RlcCdcbmltcG9ydCB7IGFycmF5TWV0aG9kcyB9IGZyb20gJy4vYXJyYXknXG5pbXBvcnQge1xuICBkZWYsXG4gIHJlbW92ZSxcbiAgaXNPYmplY3QsXG4gIGlzUGxhaW5PYmplY3QsXG4gIGhhc1Byb3RvLFxuICBoYXNPd24sXG4gIGlzUmVzZXJ2ZWRcbn0gZnJvbSAnLi4vdXRpbC9pbmRleCdcblxuY29uc3QgYXJyYXlLZXlzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoYXJyYXlNZXRob2RzKVxuXG4vKipcbiAqIE9ic2VydmVyIGNsYXNzIHRoYXQgYXJlIGF0dGFjaGVkIHRvIGVhY2ggb2JzZXJ2ZWRcbiAqIG9iamVjdC4gT25jZSBhdHRhY2hlZCwgdGhlIG9ic2VydmVyIGNvbnZlcnRzIHRhcmdldFxuICogb2JqZWN0J3MgcHJvcGVydHkga2V5cyBpbnRvIGdldHRlci9zZXR0ZXJzIHRoYXRcbiAqIGNvbGxlY3QgZGVwZW5kZW5jaWVzIGFuZCBkaXNwYXRjaGVzIHVwZGF0ZXMuXG4gKlxuICogQHBhcmFtIHtBcnJheXxPYmplY3R9IHZhbHVlXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gT2JzZXJ2ZXIgKHZhbHVlKSB7XG4gIHRoaXMudmFsdWUgPSB2YWx1ZVxuICB0aGlzLmRlcCA9IG5ldyBEZXAoKVxuICBkZWYodmFsdWUsICdfX29iX18nLCB0aGlzKVxuICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICBjb25zdCBhdWdtZW50ID0gaGFzUHJvdG9cbiAgICAgID8gcHJvdG9BdWdtZW50XG4gICAgICA6IGNvcHlBdWdtZW50XG4gICAgYXVnbWVudCh2YWx1ZSwgYXJyYXlNZXRob2RzLCBhcnJheUtleXMpXG4gICAgdGhpcy5vYnNlcnZlQXJyYXkodmFsdWUpXG4gIH0gZWxzZSB7XG4gICAgdGhpcy53YWxrKHZhbHVlKVxuICB9XG59XG5cbi8vIEluc3RhbmNlIG1ldGhvZHNcblxuLyoqXG4gKiBXYWxrIHRocm91Z2ggZWFjaCBwcm9wZXJ0eSBhbmQgY29udmVydCB0aGVtIGludG9cbiAqIGdldHRlci9zZXR0ZXJzLiBUaGlzIG1ldGhvZCBzaG91bGQgb25seSBiZSBjYWxsZWQgd2hlblxuICogdmFsdWUgdHlwZSBpcyBPYmplY3QuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICovXG5cbk9ic2VydmVyLnByb3RvdHlwZS53YWxrID0gZnVuY3Rpb24gKG9iaikge1xuICBmb3IgKGxldCBrZXkgaW4gb2JqKSB7XG4gICAgdGhpcy5jb252ZXJ0KGtleSwgb2JqW2tleV0pXG4gIH1cbn1cblxuLyoqXG4gKiBPYnNlcnZlIGEgbGlzdCBvZiBBcnJheSBpdGVtcy5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBpdGVtc1xuICovXG5cbk9ic2VydmVyLnByb3RvdHlwZS5vYnNlcnZlQXJyYXkgPSBmdW5jdGlvbiAoaXRlbXMpIHtcbiAgZm9yIChsZXQgaSA9IDAsIGwgPSBpdGVtcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBvYnNlcnZlKGl0ZW1zW2ldKVxuICB9XG59XG5cbi8qKlxuICogQ29udmVydCBhIHByb3BlcnR5IGludG8gZ2V0dGVyL3NldHRlciBzbyB3ZSBjYW4gZW1pdFxuICogdGhlIGV2ZW50cyB3aGVuIHRoZSBwcm9wZXJ0eSBpcyBhY2Nlc3NlZC9jaGFuZ2VkLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBrZXlcbiAqIEBwYXJhbSB7Kn0gdmFsXG4gKi9cblxuT2JzZXJ2ZXIucHJvdG90eXBlLmNvbnZlcnQgPSBmdW5jdGlvbiAoa2V5LCB2YWwpIHtcbiAgZGVmaW5lUmVhY3RpdmUodGhpcy52YWx1ZSwga2V5LCB2YWwpXG59XG5cbi8qKlxuICogQWRkIGFuIG93bmVyIHZtLCBzbyB0aGF0IHdoZW4gJHNldC8kZGVsZXRlIG11dGF0aW9uc1xuICogaGFwcGVuIHdlIGNhbiBub3RpZnkgb3duZXIgdm1zIHRvIHByb3h5IHRoZSBrZXlzIGFuZFxuICogZGlnZXN0IHRoZSB3YXRjaGVycy4gVGhpcyBpcyBvbmx5IGNhbGxlZCB3aGVuIHRoZSBvYmplY3RcbiAqIGlzIG9ic2VydmVkIGFzIGFuIGluc3RhbmNlJ3Mgcm9vdCAkZGF0YS5cbiAqXG4gKiBAcGFyYW0ge1Z1ZX0gdm1cbiAqL1xuXG5PYnNlcnZlci5wcm90b3R5cGUuYWRkVm0gPSBmdW5jdGlvbiAodm0pIHtcbiAgKHRoaXMudm1zIHx8ICh0aGlzLnZtcyA9IFtdKSkucHVzaCh2bSlcbn1cblxuLyoqXG4gKiBSZW1vdmUgYW4gb3duZXIgdm0uIFRoaXMgaXMgY2FsbGVkIHdoZW4gdGhlIG9iamVjdCBpc1xuICogc3dhcHBlZCBvdXQgYXMgYW4gaW5zdGFuY2UncyAkZGF0YSBvYmplY3QuXG4gKlxuICogQHBhcmFtIHtWdWV9IHZtXG4gKi9cblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbk9ic2VydmVyLnByb3RvdHlwZS5yZW1vdmVWbSA9IGZ1bmN0aW9uICh2bSkge1xuICByZW1vdmUodGhpcy52bXMsIHZtKVxufVxuXG4vLyBoZWxwZXJzXG5cbi8qKlxuICogQXVnbWVudCBhbiB0YXJnZXQgT2JqZWN0IG9yIEFycmF5IGJ5IGludGVyY2VwdGluZ1xuICogdGhlIHByb3RvdHlwZSBjaGFpbiB1c2luZyBfX3Byb3RvX19cbiAqXG4gKiBAcGFyYW0ge09iamVjdHxBcnJheX0gdGFyZ2V0XG4gKiBAcGFyYW0ge09iamVjdH0gc3JjXG4gKi9cblxuZnVuY3Rpb24gcHJvdG9BdWdtZW50ICh0YXJnZXQsIHNyYykge1xuICAvKiBlc2xpbnQtZGlzYWJsZSBuby1wcm90byAqL1xuICB0YXJnZXQuX19wcm90b19fID0gc3JjXG4gIC8qIGVzbGludC1lbmFibGUgbm8tcHJvdG8gKi9cbn1cblxuLyoqXG4gKiBBdWdtZW50IGFuIHRhcmdldCBPYmplY3Qgb3IgQXJyYXkgYnkgZGVmaW5pbmdcbiAqIGhpZGRlbiBwcm9wZXJ0aWVzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fEFycmF5fSB0YXJnZXRcbiAqIEBwYXJhbSB7T2JqZWN0fSBwcm90b1xuICovXG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5mdW5jdGlvbiBjb3B5QXVnbWVudCAodGFyZ2V0LCBzcmMsIGtleXMpIHtcbiAgZm9yIChsZXQgaSA9IDAsIGwgPSBrZXlzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGNvbnN0IGtleSA9IGtleXNbaV1cbiAgICBkZWYodGFyZ2V0LCBrZXksIHNyY1trZXldKVxuICB9XG59XG5cbi8qKlxuICogQXR0ZW1wdCB0byBjcmVhdGUgYW4gb2JzZXJ2ZXIgaW5zdGFuY2UgZm9yIGEgdmFsdWUsXG4gKiByZXR1cm5zIHRoZSBuZXcgb2JzZXJ2ZXIgaWYgc3VjY2Vzc2Z1bGx5IG9ic2VydmVkLFxuICogb3IgdGhlIGV4aXN0aW5nIG9ic2VydmVyIGlmIHRoZSB2YWx1ZSBhbHJlYWR5IGhhcyBvbmUuXG4gKlxuICogQHBhcmFtIHsqfSB2YWx1ZVxuICogQHBhcmFtIHtWdWV9IFt2bV1cbiAqIEByZXR1cm4ge09ic2VydmVyfHVuZGVmaW5lZH1cbiAqIEBzdGF0aWNcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gb2JzZXJ2ZSAodmFsdWUsIHZtKSB7XG4gIGlmICghaXNPYmplY3QodmFsdWUpKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgbGV0IG9iXG4gIGlmIChoYXNPd24odmFsdWUsICdfX29iX18nKSAmJiB2YWx1ZS5fX29iX18gaW5zdGFuY2VvZiBPYnNlcnZlcikge1xuICAgIG9iID0gdmFsdWUuX19vYl9fXG4gIH0gZWxzZSBpZiAoXG4gICAgKEFycmF5LmlzQXJyYXkodmFsdWUpIHx8IGlzUGxhaW5PYmplY3QodmFsdWUpKSAmJlxuICAgIE9iamVjdC5pc0V4dGVuc2libGUodmFsdWUpICYmXG4gICAgIXZhbHVlLl9pc1Z1ZVxuICApIHtcbiAgICBvYiA9IG5ldyBPYnNlcnZlcih2YWx1ZSlcbiAgfVxuICBpZiAob2IgJiYgdm0pIHtcbiAgICBvYi5hZGRWbSh2bSlcbiAgfVxuICByZXR1cm4gb2Jcbn1cblxuLyoqXG4gKiBEZWZpbmUgYSByZWFjdGl2ZSBwcm9wZXJ0eSBvbiBhbiBPYmplY3QuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICogQHBhcmFtIHtTdHJpbmd9IGtleVxuICogQHBhcmFtIHsqfSB2YWxcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZGVmaW5lUmVhY3RpdmUgKG9iaiwga2V5LCB2YWwpIHtcbiAgY29uc3QgZGVwID0gbmV3IERlcCgpXG5cbiAgY29uc3QgcHJvcGVydHkgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iaiwga2V5KVxuICBpZiAocHJvcGVydHkgJiYgcHJvcGVydHkuY29uZmlndXJhYmxlID09PSBmYWxzZSkge1xuICAgIHJldHVyblxuICB9XG5cbiAgLy8gY2F0ZXIgZm9yIHByZS1kZWZpbmVkIGdldHRlci9zZXR0ZXJzXG4gIGNvbnN0IGdldHRlciA9IHByb3BlcnR5ICYmIHByb3BlcnR5LmdldFxuICBjb25zdCBzZXR0ZXIgPSBwcm9wZXJ0eSAmJiBwcm9wZXJ0eS5zZXRcblxuICBsZXQgY2hpbGRPYiA9IG9ic2VydmUodmFsKVxuICBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqLCBrZXksIHtcbiAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICBnZXQ6IGZ1bmN0aW9uIHJlYWN0aXZlR2V0dGVyICgpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gZ2V0dGVyID8gZ2V0dGVyLmNhbGwob2JqKSA6IHZhbFxuICAgICAgaWYgKERlcC50YXJnZXQpIHtcbiAgICAgICAgZGVwLmRlcGVuZCgpXG4gICAgICAgIGlmIChjaGlsZE9iKSB7XG4gICAgICAgICAgY2hpbGRPYi5kZXAuZGVwZW5kKClcbiAgICAgICAgfVxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICBmb3IgKGxldCBlLCBpID0gMCwgbCA9IHZhbHVlLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICAgICAgZSA9IHZhbHVlW2ldXG4gICAgICAgICAgICBlICYmIGUuX19vYl9fICYmIGUuX19vYl9fLmRlcC5kZXBlbmQoKVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbHVlXG4gICAgfSxcbiAgICBzZXQ6IGZ1bmN0aW9uIHJlYWN0aXZlU2V0dGVyIChuZXdWYWwpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gZ2V0dGVyID8gZ2V0dGVyLmNhbGwob2JqKSA6IHZhbFxuICAgICAgaWYgKG5ld1ZhbCA9PT0gdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG4gICAgICBpZiAoc2V0dGVyKSB7XG4gICAgICAgIHNldHRlci5jYWxsKG9iaiwgbmV3VmFsKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFsID0gbmV3VmFsXG4gICAgICB9XG4gICAgICBjaGlsZE9iID0gb2JzZXJ2ZShuZXdWYWwpXG4gICAgICBkZXAubm90aWZ5KClcbiAgICB9XG4gIH0pXG59XG5cbi8qKlxuICogU2V0IGEgcHJvcGVydHkgb24gYW4gb2JqZWN0LiBBZGRzIHRoZSBuZXcgcHJvcGVydHkgYW5kXG4gKiB0cmlnZ2VycyBjaGFuZ2Ugbm90aWZpY2F0aW9uIGlmIHRoZSBwcm9wZXJ0eSBkb2Vzbid0XG4gKiBhbHJlYWR5IGV4aXN0LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqIEBwYXJhbSB7U3RyaW5nfSBrZXlcbiAqIEBwYXJhbSB7Kn0gdmFsXG4gKiBAcHVibGljXG4gKi9cblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXQgKG9iaiwga2V5LCB2YWwpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkob2JqKSkge1xuICAgIHJldHVybiBvYmouc3BsaWNlKGtleSwgMSwgdmFsKVxuICB9XG4gIGlmIChoYXNPd24ob2JqLCBrZXkpKSB7XG4gICAgb2JqW2tleV0gPSB2YWxcbiAgICByZXR1cm5cbiAgfVxuICBpZiAob2JqLl9pc1Z1ZSkge1xuICAgIHNldChvYmouX2RhdGEsIGtleSwgdmFsKVxuICAgIHJldHVyblxuICB9XG4gIGNvbnN0IG9iID0gb2JqLl9fb2JfX1xuICBpZiAoIW9iKSB7XG4gICAgb2JqW2tleV0gPSB2YWxcbiAgICByZXR1cm5cbiAgfVxuICBvYi5jb252ZXJ0KGtleSwgdmFsKVxuICBvYi5kZXAubm90aWZ5KClcbiAgaWYgKG9iLnZtcykge1xuICAgIGxldCBpID0gb2Iudm1zLmxlbmd0aFxuICAgIHdoaWxlIChpLS0pIHtcbiAgICAgIGNvbnN0IHZtID0gb2Iudm1zW2ldXG4gICAgICBwcm94eSh2bSwga2V5KVxuICAgICAgLy8gdm0uJGZvcmNlVXBkYXRlKClcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHZhbFxufVxuXG4vKipcbiAqIERlbGV0ZSBhIHByb3BlcnR5IGFuZCB0cmlnZ2VyIGNoYW5nZSBpZiBuZWNlc3NhcnkuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICogQHBhcmFtIHtTdHJpbmd9IGtleVxuICovXG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5leHBvcnQgZnVuY3Rpb24gZGVsIChvYmosIGtleSkge1xuICBpZiAoIWhhc093bihvYmosIGtleSkpIHtcbiAgICByZXR1cm5cbiAgfVxuICBkZWxldGUgb2JqW2tleV1cbiAgY29uc3Qgb2IgPSBvYmouX19vYl9fXG5cbiAgaWYgKCFvYikge1xuICAgIGlmIChvYmouX2lzVnVlKSB7XG4gICAgICBkZWxldGUgb2JqLl9kYXRhW2tleV1cbiAgICAgIC8vIG9iai4kZm9yY2VVcGRhdGUoKVxuICAgIH1cbiAgICByZXR1cm5cbiAgfVxuICBvYi5kZXAubm90aWZ5KClcbiAgaWYgKG9iLnZtcykge1xuICAgIGxldCBpID0gb2Iudm1zLmxlbmd0aFxuICAgIHdoaWxlIChpLS0pIHtcbiAgICAgIGNvbnN0IHZtID0gb2Iudm1zW2ldXG4gICAgICB1bnByb3h5KHZtLCBrZXkpXG4gICAgICAvLyB2bS4kZm9yY2VVcGRhdGUoKVxuICAgIH1cbiAgfVxufVxuXG5jb25zdCBLRVlfV09SRFMgPSBbJyRpbmRleCcsICckdmFsdWUnLCAnJGV2ZW50J11cbmV4cG9ydCBmdW5jdGlvbiBwcm94eSAodm0sIGtleSkge1xuICBpZiAoS0VZX1dPUkRTLmluZGV4T2Yoa2V5KSA+IC0xIHx8ICFpc1Jlc2VydmVkKGtleSkpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodm0sIGtleSwge1xuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgIGdldDogZnVuY3Rpb24gcHJveHlHZXR0ZXIgKCkge1xuICAgICAgICByZXR1cm4gdm0uX2RhdGFba2V5XVxuICAgICAgfSxcbiAgICAgIHNldDogZnVuY3Rpb24gcHJveHlTZXR0ZXIgKHZhbCkge1xuICAgICAgICB2bS5fZGF0YVtrZXldID0gdmFsXG4gICAgICB9XG4gICAgfSlcbiAgfVxufVxuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVucHJveHkgKHZtLCBrZXkpIHtcbiAgaWYgKCFpc1Jlc2VydmVkKGtleSkpIHtcbiAgICBkZWxldGUgdm1ba2V5XVxuICB9XG59XG4iLCIvKiBlc2xpbnQtZGlzYWJsZSAqL1xuXG5cbmltcG9ydCBXYXRjaGVyIGZyb20gJy4vd2F0Y2hlcidcbmltcG9ydCBEZXAgZnJvbSAnLi9kZXAnXG5pbXBvcnQge1xuICBvYnNlcnZlLFxuICBwcm94eSxcbiAgdW5wcm94eVxufSBmcm9tICcuL29ic2VydmVyJ1xuaW1wb3J0IHtcbiAgaXNQbGFpbk9iamVjdCxcbiAgYmluZFxufSBmcm9tICcuLi91dGlsL2luZGV4J1xuXG5leHBvcnQgZnVuY3Rpb24gaW5pdFN0YXRlICh2bSkge1xuICB2bS5fd2F0Y2hlcnMgPSBbXVxuICBpbml0RGF0YSh2bSlcbiAgaW5pdENvbXB1dGVkKHZtKVxuICBpbml0TWV0aG9kcyh2bSlcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGluaXREYXRhICh2bSkge1xuICBsZXQgZGF0YSA9IHZtLl9kYXRhXG5cbiAgaWYgKCFpc1BsYWluT2JqZWN0KGRhdGEpKSB7XG4gICAgZGF0YSA9IHt9XG4gIH1cbiAgLy8gcHJveHkgZGF0YSBvbiBpbnN0YW5jZVxuICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoZGF0YSlcbiAgbGV0IGkgPSBrZXlzLmxlbmd0aFxuICB3aGlsZSAoaS0tKSB7XG4gICAgcHJveHkodm0sIGtleXNbaV0pXG4gIH1cbiAgLy8gb2JzZXJ2ZSBkYXRhXG4gIG9ic2VydmUoZGF0YSwgdm0pXG59XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5mdW5jdGlvbiBub29wICgpIHtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGluaXRDb21wdXRlZCAodm0pIHtcbiAgY29uc3QgY29tcHV0ZWQgPSB2bS5fY29tcHV0ZWRcbiAgaWYgKGNvbXB1dGVkKSB7XG4gICAgZm9yIChsZXQga2V5IGluIGNvbXB1dGVkKSB7XG4gICAgICBjb25zdCB1c2VyRGVmID0gY29tcHV0ZWRba2V5XVxuICAgICAgY29uc3QgZGVmID0ge1xuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgdXNlckRlZiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBkZWYuZ2V0ID0gbWFrZUNvbXB1dGVkR2V0dGVyKHVzZXJEZWYsIHZtKVxuICAgICAgICBkZWYuc2V0ID0gbm9vcFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVmLmdldCA9IHVzZXJEZWYuZ2V0XG4gICAgICAgICAgPyB1c2VyRGVmLmNhY2hlICE9PSBmYWxzZVxuICAgICAgICAgICAgPyBtYWtlQ29tcHV0ZWRHZXR0ZXIodXNlckRlZi5nZXQsIHZtKVxuICAgICAgICAgICAgOiBiaW5kKHVzZXJEZWYuZ2V0LCB2bSlcbiAgICAgICAgICA6IG5vb3BcbiAgICAgICAgZGVmLnNldCA9IHVzZXJEZWYuc2V0XG4gICAgICAgICAgPyBiaW5kKHVzZXJEZWYuc2V0LCB2bSlcbiAgICAgICAgICA6IG5vb3BcbiAgICAgIH1cbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh2bSwga2V5LCBkZWYpXG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIG1ha2VDb21wdXRlZEdldHRlciAoZ2V0dGVyLCBvd25lcikge1xuICBjb25zdCB3YXRjaGVyID0gbmV3IFdhdGNoZXIob3duZXIsIGdldHRlciwgbnVsbCwge1xuICAgIGxhenk6IHRydWVcbiAgfSlcbiAgcmV0dXJuIGZ1bmN0aW9uIGNvbXB1dGVkR2V0dGVyICgpIHtcbiAgICBpZiAod2F0Y2hlci5kaXJ0eSkge1xuICAgICAgd2F0Y2hlci5ldmFsdWF0ZSgpXG4gICAgfVxuICAgIGlmIChEZXAudGFyZ2V0KSB7XG4gICAgICB3YXRjaGVyLmRlcGVuZCgpXG4gICAgfVxuICAgIHJldHVybiB3YXRjaGVyLnZhbHVlXG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGluaXRNZXRob2RzICh2bSkge1xuICBjb25zdCBtZXRob2RzID0gdm0uX21ldGhvZHNcbiAgaWYgKG1ldGhvZHMpIHtcbiAgICBmb3IgKGxldCBrZXkgaW4gbWV0aG9kcykge1xuICAgICAgdm1ba2V5XSA9IG1ldGhvZHNba2V5XVxuICAgIH1cbiAgfVxufVxuIiwiLypcbiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmVcbiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZVxuICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb25cbiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGVcbiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGVcbiAqIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZVxuICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLFxuICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW5cbiAqIFwiQVMgSVNcIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXG4gKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGVcbiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnNcbiAqIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG4vLyBAdG9kbzogSXQgc2hvdWxkIGJlIHJlZ2lzdGVyZWQgYnkgbmF0aXZlIGZyb20gYHJlZ2lzdGVyQ29tcG9uZW50cygpYC5cblxuZXhwb3J0IGRlZmF1bHQge1xuICBuYXRpdmVDb21wb25lbnRNYXA6IHtcbiAgICB0ZXh0OiB0cnVlLFxuICAgIGltYWdlOiB0cnVlLFxuICAgIGNvbnRhaW5lcjogdHJ1ZSxcbiAgICBzbGlkZXI6IHtcbiAgICAgIHR5cGU6ICdzbGlkZXInLFxuICAgICAgYXBwZW5kOiAndHJlZSdcbiAgICB9LFxuICAgIGNlbGw6IHtcbiAgICAgIHR5cGU6ICdjZWxsJyxcbiAgICAgIGFwcGVuZDogJ3RyZWUnXG4gICAgfVxuICB9XG59XG4iLCIvKlxuICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZVxuICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlXG4gKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvblxuICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZVxuICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZVxuICogXCJMaWNlbnNlXCIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlXG4gKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsXG4gKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhblxuICogXCJBUyBJU1wiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTllcbiAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZVxuICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9uc1xuICogdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbi8qKlxuICogQGZpbGVPdmVydmlld1xuICogRGlyZWN0aXZlIFBhcnNlclxuICovXG5cbmltcG9ydCB7IGJpbmQsIHR5cG9mIH0gZnJvbSAnLi4vdXRpbC9pbmRleCdcbmltcG9ydCBXYXRjaGVyIGZyb20gJy4uL2NvcmUvd2F0Y2hlcidcbmltcG9ydCBjb25maWcgZnJvbSAnLi4vY29uZmlnJ1xuXG5jb25zdCB7IG5hdGl2ZUNvbXBvbmVudE1hcCB9ID0gY29uZmlnXG5cbmNvbnN0IFNFVFRFUlMgPSB7XG4gIGF0dHI6ICdzZXRBdHRyJyxcbiAgc3R5bGU6ICdzZXRTdHlsZScsXG4gIGV2ZW50OiAnYWRkRXZlbnQnXG59XG5cbi8qKlxuICogYXBwbHkgdGhlIG5hdGl2ZSBjb21wb25lbnQncyBvcHRpb25zKHNwZWNpZmllZCBieSB0ZW1wbGF0ZS50eXBlKVxuICogdG8gdGhlIHRlbXBsYXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhcHBseU5haXR2ZUNvbXBvbmVudE9wdGlvbnMgKHRlbXBsYXRlKSB7XG4gIGNvbnN0IHsgdHlwZSB9ID0gdGVtcGxhdGVcbiAgY29uc3Qgb3B0aW9ucyA9IG5hdGl2ZUNvbXBvbmVudE1hcFt0eXBlXVxuXG4gIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ29iamVjdCcpIHtcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBvcHRpb25zKSB7XG4gICAgICBpZiAodGVtcGxhdGVba2V5XSA9PSBudWxsKSB7XG4gICAgICAgIHRlbXBsYXRlW2tleV0gPSBvcHRpb25zW2tleV1cbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKHR5cG9mKHRlbXBsYXRlW2tleV0pID09PSAnb2JqZWN0JyAmJlxuICAgICAgICB0eXBvZihvcHRpb25zW2tleV0pID09PSAnb2JqZWN0Jykge1xuICAgICAgICBmb3IgKGNvbnN0IHN1YmtleSBpbiBvcHRpb25zW2tleV0pIHtcbiAgICAgICAgICBpZiAodGVtcGxhdGVba2V5XVtzdWJrZXldID09IG51bGwpIHtcbiAgICAgICAgICAgIHRlbXBsYXRlW2tleV1bc3Via2V5XSA9IG9wdGlvbnNba2V5XVtzdWJrZXldXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogYmluZCBhbGwgaWQsIGF0dHIsIGNsYXNzbmFtZXMsIHN0eWxlLCBldmVudHMgdG8gYW4gZWxlbWVudFxuICovXG5leHBvcnQgZnVuY3Rpb24gYmluZEVsZW1lbnQgKHZtLCBlbCwgdGVtcGxhdGUpIHtcbiAgc2V0SWQodm0sIGVsLCB0ZW1wbGF0ZS5pZCwgdm0pXG4gIHNldEF0dHIodm0sIGVsLCB0ZW1wbGF0ZS5hdHRyKVxuICBzZXRDbGFzcyh2bSwgZWwsIHRlbXBsYXRlLmNsYXNzTGlzdClcbiAgc2V0U3R5bGUodm0sIGVsLCB0ZW1wbGF0ZS5zdHlsZSlcbiAgYmluZEV2ZW50cyh2bSwgZWwsIHRlbXBsYXRlLmV2ZW50cylcbn1cblxuLyoqXG4gKiBiaW5kIGFsbCBwcm9wcyB0byBzdWIgdm0gYW5kIGJpbmQgYWxsIHN0eWxlLCBldmVudHMgdG8gdGhlIHJvb3QgZWxlbWVudFxuICogb2YgdGhlIHN1YiB2bSBpZiBpdCBkb2Vzbid0IGhhdmUgYSByZXBsYWNlZCBtdWx0aS1ub2RlIGZyYWdtZW50XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBiaW5kU3ViVm0gKHZtLCBzdWJWbSwgdGVtcGxhdGUsIHJlcGVhdEl0ZW0pIHtcbiAgc3ViVm0gPSBzdWJWbSB8fCB7fVxuICB0ZW1wbGF0ZSA9IHRlbXBsYXRlIHx8IHt9XG5cbiAgY29uc3Qgb3B0aW9ucyA9IHN1YlZtLl9vcHRpb25zIHx8IHt9XG5cbiAgLy8gYmluZCBwcm9wc1xuICBsZXQgcHJvcHMgPSBvcHRpb25zLnByb3BzXG5cbiAgaWYgKEFycmF5LmlzQXJyYXkocHJvcHMpKSB7XG4gICAgcHJvcHMgPSBwcm9wcy5yZWR1Y2UoKHJlc3VsdCwgdmFsdWUpID0+IHtcbiAgICAgIHJlc3VsdFt2YWx1ZV0gPSB0cnVlXG4gICAgICByZXR1cm4gcmVzdWx0XG4gICAgfSwge30pXG4gIH1cblxuICBtZXJnZVByb3BzKHJlcGVhdEl0ZW0sIHByb3BzLCB2bSwgc3ViVm0pXG4gIG1lcmdlUHJvcHModGVtcGxhdGUuYXR0ciwgcHJvcHMsIHZtLCBzdWJWbSlcbn1cblxuLyoqXG4gKiBtZXJnZSBjbGFzcyBhbmQgc3R5bGVzIGZyb20gdm0gdG8gc3ViIHZtLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYmluZFN1YlZtQWZ0ZXJJbml0aWFsaXplZCAodm0sIHN1YlZtLCB0ZW1wbGF0ZSwgdGFyZ2V0ID0ge30pIHtcbiAgbWVyZ2VDbGFzc1N0eWxlKHRlbXBsYXRlLmNsYXNzTGlzdCwgdm0sIHN1YlZtKVxuICBtZXJnZVN0eWxlKHRlbXBsYXRlLnN0eWxlLCB2bSwgc3ViVm0pXG5cbiAgLy8gYmluZCBzdWJWbSB0byB0aGUgdGFyZ2V0IGVsZW1lbnRcbiAgaWYgKHRhcmdldC5jaGlsZHJlbikge1xuICAgIHRhcmdldC5jaGlsZHJlblt0YXJnZXQuY2hpbGRyZW4ubGVuZ3RoIC0gMV0uX3ZtID0gc3ViVm1cbiAgfVxuICBlbHNlIHtcbiAgICB0YXJnZXQuX3ZtID0gc3ViVm1cbiAgfVxufVxuXG4vKipcbiAqIEJpbmQgcHJvcHMgZnJvbSB2bSB0byBzdWIgdm0gYW5kIHdhdGNoIHRoZWlyIHVwZGF0ZXMuXG4gKi9cbmZ1bmN0aW9uIG1lcmdlUHJvcHMgKHRhcmdldCwgcHJvcHMsIHZtLCBzdWJWbSkge1xuICBpZiAoIXRhcmdldCkge1xuICAgIHJldHVyblxuICB9XG4gIGZvciAoY29uc3Qga2V5IGluIHRhcmdldCkge1xuICAgIGlmICghcHJvcHMgfHwgcHJvcHNba2V5XSkge1xuICAgICAgY29uc3QgdmFsdWUgPSB0YXJnZXRba2V5XVxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBjb25zdCByZXR1cm5WYWx1ZSA9IHdhdGNoKHZtLCB2YWx1ZSwgZnVuY3Rpb24gKHYpIHtcbiAgICAgICAgICBzdWJWbVtrZXldID0gdlxuICAgICAgICB9KVxuICAgICAgICBzdWJWbVtrZXldID0gcmV0dXJuVmFsdWVcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBzdWJWbVtrZXldID0gdmFsdWVcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBCaW5kIHN0eWxlIGZyb20gdm0gdG8gc3ViIHZtIGFuZCB3YXRjaCB0aGVpciB1cGRhdGVzLlxuICovXG5mdW5jdGlvbiBtZXJnZVN0eWxlICh0YXJnZXQsIHZtLCBzdWJWbSkge1xuICBmb3IgKGNvbnN0IGtleSBpbiB0YXJnZXQpIHtcbiAgICBjb25zdCB2YWx1ZSA9IHRhcmdldFtrZXldXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgY29uc3QgcmV0dXJuVmFsdWUgPSB3YXRjaCh2bSwgdmFsdWUsIGZ1bmN0aW9uICh2KSB7XG4gICAgICAgIGlmIChzdWJWbS5fcm9vdEVsKSB7XG4gICAgICAgICAgc3ViVm0uX3Jvb3RFbC5zZXRTdHlsZShrZXksIHYpXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICBzdWJWbS5fcm9vdEVsLnNldFN0eWxlKGtleSwgcmV0dXJuVmFsdWUpXG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgaWYgKHN1YlZtLl9yb290RWwpIHtcbiAgICAgICAgc3ViVm0uX3Jvb3RFbC5zZXRTdHlsZShrZXksIHZhbHVlKVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEJpbmQgY2xhc3MgJiBzdHlsZSBmcm9tIHZtIHRvIHN1YiB2bSBhbmQgd2F0Y2ggdGhlaXIgdXBkYXRlcy5cbiAqL1xuZnVuY3Rpb24gbWVyZ2VDbGFzc1N0eWxlICh0YXJnZXQsIHZtLCBzdWJWbSkge1xuICBjb25zdCBjc3MgPSB2bS5fb3B0aW9ucyAmJiB2bS5fb3B0aW9ucy5zdHlsZSB8fCB7fVxuXG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICBpZiAoIXN1YlZtLl9yb290RWwpIHtcbiAgICByZXR1cm5cbiAgfVxuXG4gIGNvbnN0IGNsYXNzTmFtZSA9ICdAb3JpZ2luYWxSb290RWwnXG4gIGNzc1tjbGFzc05hbWVdID0gc3ViVm0uX3Jvb3RFbC5jbGFzc1N0eWxlXG5cbiAgZnVuY3Rpb24gYWRkQ2xhc3NOYW1lIChsaXN0LCBuYW1lKSB7XG4gICAgaWYgKHR5cG9mKGxpc3QpID09PSAnYXJyYXknKSB7XG4gICAgICBsaXN0LnVuc2hpZnQobmFtZSlcbiAgICB9XG4gIH1cblxuICBpZiAodHlwZW9mIHRhcmdldCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNvbnN0IHZhbHVlID0gd2F0Y2godm0sIHRhcmdldCwgdiA9PiB7XG4gICAgICBhZGRDbGFzc05hbWUodiwgY2xhc3NOYW1lKVxuICAgICAgc2V0Q2xhc3NTdHlsZShzdWJWbS5fcm9vdEVsLCBjc3MsIHYpXG4gICAgfSlcbiAgICBhZGRDbGFzc05hbWUodmFsdWUsIGNsYXNzTmFtZSlcbiAgICBzZXRDbGFzc1N0eWxlKHN1YlZtLl9yb290RWwsIGNzcywgdmFsdWUpXG4gIH1cbiAgZWxzZSBpZiAodGFyZ2V0ICE9IG51bGwpIHtcbiAgICBhZGRDbGFzc05hbWUodGFyZ2V0LCBjbGFzc05hbWUpXG4gICAgc2V0Q2xhc3NTdHlsZShzdWJWbS5fcm9vdEVsLCBjc3MsIHRhcmdldClcbiAgfVxufVxuXG4vKipcbiAqIGJpbmQgaWQgdG8gYW4gZWxlbWVudFxuICogZWFjaCBpZCBpcyB1bmlxdWUgaW4gYSB3aG9sZSB2bVxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0SWQgKHZtLCBlbCwgaWQsIHRhcmdldCkge1xuICBjb25zdCBtYXAgPSBPYmplY3QuY3JlYXRlKG51bGwpXG5cbiAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMobWFwLCB7XG4gICAgdm06IHtcbiAgICAgIHZhbHVlOiB0YXJnZXQsXG4gICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICBjb25maWd1cmFibGU6IGZhbHNlXG4gICAgfSxcbiAgICBlbDoge1xuICAgICAgZ2V0OiAoKSA9PiBlbCB8fCB0YXJnZXQuX3Jvb3RFbCxcbiAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2VcbiAgICB9XG4gIH0pXG5cbiAgaWYgKHR5cGVvZiBpZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNvbnN0IGhhbmRsZXIgPSBpZFxuICAgIGlkID0gaGFuZGxlci5jYWxsKHZtKVxuICAgIGlmIChpZCB8fCBpZCA9PT0gMCkge1xuICAgICAgdm0uX2lkc1tpZF0gPSBtYXBcbiAgICB9XG4gICAgd2F0Y2godm0sIGhhbmRsZXIsIChuZXdJZCkgPT4ge1xuICAgICAgaWYgKG5ld0lkKSB7XG4gICAgICAgIHZtLl9pZHNbbmV3SWRdID0gbWFwXG4gICAgICB9XG4gICAgfSlcbiAgfVxuICBlbHNlIGlmIChpZCAmJiB0eXBlb2YgaWQgPT09ICdzdHJpbmcnKSB7XG4gICAgdm0uX2lkc1tpZF0gPSBtYXBcbiAgfVxufVxuXG4vKipcbiAqIGJpbmQgYXR0ciB0byBhbiBlbGVtZW50XG4gKi9cbmZ1bmN0aW9uIHNldEF0dHIgKHZtLCBlbCwgYXR0cikge1xuICBiaW5kRGlyKHZtLCBlbCwgJ2F0dHInLCBhdHRyKVxufVxuXG5mdW5jdGlvbiBzZXRDbGFzc1N0eWxlIChlbCwgY3NzLCBjbGFzc0xpc3QpIHtcbiAgaWYgKHR5cGVvZiBjbGFzc0xpc3QgPT09ICdzdHJpbmcnKSB7XG4gICAgY2xhc3NMaXN0ID0gY2xhc3NMaXN0LnNwbGl0KC9cXHMrLylcbiAgfVxuICBjbGFzc0xpc3QuZm9yRWFjaCgobmFtZSwgaSkgPT4ge1xuICAgIGNsYXNzTGlzdC5zcGxpY2UoaSwgMSwgLi4ubmFtZS5zcGxpdCgvXFxzKy8pKVxuICB9KVxuICBjb25zdCBjbGFzc1N0eWxlID0ge31cbiAgY29uc3QgbGVuZ3RoID0gY2xhc3NMaXN0Lmxlbmd0aFxuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBzdHlsZSA9IGNzc1tjbGFzc0xpc3RbaV1dXG4gICAgaWYgKHN0eWxlKSB7XG4gICAgICBPYmplY3Qua2V5cyhzdHlsZSkuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICAgIGNsYXNzU3R5bGVba2V5XSA9IHN0eWxlW2tleV1cbiAgICAgIH0pXG4gICAgfVxuICB9XG4gIGVsLnNldENsYXNzU3R5bGUoY2xhc3NTdHlsZSlcbn1cblxuLyoqXG4gKiBiaW5kIGNsYXNzbmFtZXMgdG8gYW4gZWxlbWVudFxuICovXG5mdW5jdGlvbiBzZXRDbGFzcyAodm0sIGVsLCBjbGFzc0xpc3QpIHtcbiAgaWYgKHR5cGVvZiBjbGFzc0xpc3QgIT09ICdmdW5jdGlvbicgJiYgIUFycmF5LmlzQXJyYXkoY2xhc3NMaXN0KSkge1xuICAgIHJldHVyblxuICB9XG4gIGlmIChBcnJheS5pc0FycmF5KGNsYXNzTGlzdCkgJiYgIWNsYXNzTGlzdC5sZW5ndGgpIHtcbiAgICBlbC5zZXRDbGFzc1N0eWxlKHt9KVxuICAgIHJldHVyblxuICB9XG5cbiAgY29uc3Qgc3R5bGUgPSB2bS5fb3B0aW9ucyAmJiB2bS5fb3B0aW9ucy5zdHlsZSB8fCB7fVxuICBpZiAodHlwZW9mIGNsYXNzTGlzdCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNvbnN0IHZhbHVlID0gd2F0Y2godm0sIGNsYXNzTGlzdCwgdiA9PiB7XG4gICAgICBzZXRDbGFzc1N0eWxlKGVsLCBzdHlsZSwgdilcbiAgICB9KVxuICAgIHNldENsYXNzU3R5bGUoZWwsIHN0eWxlLCB2YWx1ZSlcbiAgfVxuICBlbHNlIHtcbiAgICBzZXRDbGFzc1N0eWxlKGVsLCBzdHlsZSwgY2xhc3NMaXN0KVxuICB9XG59XG5cbi8qKlxuICogYmluZCBzdHlsZSB0byBhbiBlbGVtZW50XG4gKi9cbmZ1bmN0aW9uIHNldFN0eWxlICh2bSwgZWwsIHN0eWxlKSB7XG4gIGJpbmREaXIodm0sIGVsLCAnc3R5bGUnLCBzdHlsZSlcbn1cblxuLyoqXG4gKiBhZGQgYW4gZXZlbnQgdHlwZSBhbmQgaGFuZGxlciB0byBhbiBlbGVtZW50IGFuZCBnZW5lcmF0ZSBhIGRvbSB1cGRhdGVcbiAqL1xuZnVuY3Rpb24gc2V0RXZlbnQgKHZtLCBlbCwgdHlwZSwgaGFuZGxlcikge1xuICBlbC5hZGRFdmVudCh0eXBlLCBiaW5kKGhhbmRsZXIsIHZtKSlcbn1cblxuLyoqXG4gKiBhZGQgYWxsIGV2ZW50cyBvZiBhbiBlbGVtZW50XG4gKi9cbmZ1bmN0aW9uIGJpbmRFdmVudHMgKHZtLCBlbCwgZXZlbnRzKSB7XG4gIGlmICghZXZlbnRzKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKGV2ZW50cylcbiAgbGV0IGkgPSBrZXlzLmxlbmd0aFxuICB3aGlsZSAoaS0tKSB7XG4gICAgY29uc3Qga2V5ID0ga2V5c1tpXVxuICAgIGxldCBoYW5kbGVyID0gZXZlbnRzW2tleV1cbiAgICBpZiAodHlwZW9mIGhhbmRsZXIgPT09ICdzdHJpbmcnKSB7XG4gICAgICBoYW5kbGVyID0gdm1baGFuZGxlcl1cbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihgW0pTIEZyYW1ld29ya10gVGhlIGV2ZW50IGhhbmRsZXIgXCIke2hhbmRsZXJ9XCIgaXMgbm90IGRlZmluZWQuYClcbiAgICAgIH1cbiAgICB9XG4gICAgc2V0RXZlbnQodm0sIGVsLCBrZXksIGhhbmRsZXIpXG4gIH1cbn1cblxuLyoqXG4gKiBzZXQgYSBzZXJpZXMgb2YgbWVtYmVycyBhcyBhIGtpbmQgb2YgYW4gZWxlbWVudFxuICogZm9yIGV4YW1wbGU6IHN0eWxlLCBhdHRyLCAuLi5cbiAqIGlmIHRoZSB2YWx1ZSBpcyBhIGZ1bmN0aW9uIHRoZW4gYmluZCB0aGUgZGF0YSBjaGFuZ2VzXG4gKi9cbmZ1bmN0aW9uIGJpbmREaXIgKHZtLCBlbCwgbmFtZSwgZGF0YSkge1xuICBpZiAoIWRhdGEpIHtcbiAgICByZXR1cm5cbiAgfVxuICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoZGF0YSlcbiAgbGV0IGkgPSBrZXlzLmxlbmd0aFxuICB3aGlsZSAoaS0tKSB7XG4gICAgY29uc3Qga2V5ID0ga2V5c1tpXVxuICAgIGNvbnN0IHZhbHVlID0gZGF0YVtrZXldXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgYmluZEtleSh2bSwgZWwsIG5hbWUsIGtleSwgdmFsdWUpXG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgZWxbU0VUVEVSU1tuYW1lXV0oa2V5LCB2YWx1ZSlcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBiaW5kIGRhdGEgY2hhbmdlcyB0byBhIGNlcnRhaW4ga2V5IHRvIGEgbmFtZSBzZXJpZXMgaW4gYW4gZWxlbWVudFxuICovXG5mdW5jdGlvbiBiaW5kS2V5ICh2bSwgZWwsIG5hbWUsIGtleSwgY2FsYykge1xuICBjb25zdCBtZXRob2ROYW1lID0gU0VUVEVSU1tuYW1lXVxuICAvLyB3YXRjaCB0aGUgY2FsYywgYW5kIHJldHVybnMgYSB2YWx1ZSBieSBjYWxjLmNhbGwoKVxuICBjb25zdCB2YWx1ZSA9IHdhdGNoKHZtLCBjYWxjLCAodmFsdWUpID0+IHtcbiAgICBmdW5jdGlvbiBoYW5kbGVyICgpIHtcbiAgICAgIGVsW21ldGhvZE5hbWVdKGtleSwgdmFsdWUpXG4gICAgfVxuICAgIGNvbnN0IGRpZmZlciA9IHZtICYmIHZtLl9hcHAgJiYgdm0uX2FwcC5kaWZmZXJcbiAgICBpZiAoZGlmZmVyKSB7XG4gICAgICBkaWZmZXIuYXBwZW5kKCdlbGVtZW50JywgZWwuZGVwdGgsIGVsLnJlZiwgaGFuZGxlcilcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBoYW5kbGVyKClcbiAgICB9XG4gIH0pXG5cbiAgZWxbbWV0aG9kTmFtZV0oa2V5LCB2YWx1ZSlcbn1cblxuLyoqXG4gKiB3YXRjaCBhIGNhbGMgZnVuY3Rpb24gYW5kIGNhbGxiYWNrIGlmIHRoZSBjYWxjIHZhbHVlIGNoYW5nZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdhdGNoICh2bSwgY2FsYywgY2FsbGJhY2spIHtcbiAgaWYgKHZtLl9zdGF0aWMpIHtcbiAgICByZXR1cm4gY2FsYy5jYWxsKHZtLCB2bSlcbiAgfVxuICBjb25zdCB3YXRjaGVyID0gbmV3IFdhdGNoZXIodm0sIGNhbGMsIGZ1bmN0aW9uICh2YWx1ZSwgb2xkVmFsdWUpIHtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JyAmJiB2YWx1ZSA9PT0gb2xkVmFsdWUpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBjYWxsYmFjayh2YWx1ZSlcbiAgfSlcblxuICByZXR1cm4gd2F0Y2hlci52YWx1ZVxufVxuIiwiLypcbiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmVcbiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZVxuICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb25cbiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGVcbiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGVcbiAqIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZVxuICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLFxuICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW5cbiAqIFwiQVMgSVNcIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXG4gKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGVcbiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnNcbiAqIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG4vKipcbiAqIEBmaWxlT3ZlcnZpZXcgRG9jdW1lbnQgJiBFbGVtZW50IEhlbHBlcnMuXG4gKlxuICogcmVxdWlyZWQ6XG4gKiBEb2N1bWVudCM6IGNyZWF0ZUVsZW1lbnQsIGNyZWF0ZUNvbW1lbnQsIGdldFJlZlxuICogRWxlbWVudCM6IGFwcGVuZENoaWxkLCBpbnNlcnRCZWZvcmUsIHJlbW92ZUNoaWxkLCBuZXh0U2libGluZ1xuICovXG5cbi8qKlxuICogQ3JlYXRlIGEgYm9keSBieSB0eXBlXG4gKiBVc2luZyB0aGlzLl9hcHAuZG9jXG4gKlxuICogQHBhcmFtICB7c3RyaW5nfSB0eXBlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVCb2R5ICh2bSwgdHlwZSkge1xuICBjb25zdCBkb2MgPSB2bS5fYXBwLmRvY1xuICByZXR1cm4gZG9jLmNyZWF0ZUJvZHkodHlwZSlcbn1cblxuLyoqXG4gKiBDcmVhdGUgYW4gZWxlbWVudCBieSB0eXBlXG4gKiBVc2luZyB0aGlzLl9hcHAuZG9jXG4gKlxuICogQHBhcmFtICB7c3RyaW5nfSB0eXBlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVFbGVtZW50ICh2bSwgdHlwZSkge1xuICBjb25zdCBkb2MgPSB2bS5fYXBwLmRvY1xuICByZXR1cm4gZG9jLmNyZWF0ZUVsZW1lbnQodHlwZSlcbn1cblxuLyoqXG4gKiBDcmVhdGUgYW5kIHJldHVybiBhIGZyYWcgYmxvY2sgZm9yIGFuIGVsZW1lbnQuXG4gKiBUaGUgZnJhZyBibG9jayBoYXMgYSBzdGFydGVyLCBlbmRlciBhbmQgdGhlIGVsZW1lbnQgaXRzZWxmLlxuICpcbiAqIEBwYXJhbSAge29iamVjdH0gZWxlbWVudFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQmxvY2sgKHZtLCBlbGVtZW50KSB7XG4gIGNvbnN0IHN0YXJ0ID0gY3JlYXRlQmxvY2tTdGFydCh2bSlcbiAgY29uc3QgZW5kID0gY3JlYXRlQmxvY2tFbmQodm0pXG4gIGNvbnN0IGJsb2NrSWQgPSBsYXN0ZXN0QmxvY2tJZCsrXG4gIGlmIChlbGVtZW50LmVsZW1lbnQpIHtcbiAgICBsZXQgdXBkYXRlTWFyayA9IGVsZW1lbnQudXBkYXRlTWFya1xuICAgIGlmICh1cGRhdGVNYXJrKSB7XG4gICAgICBpZiAodXBkYXRlTWFyay5lbGVtZW50KSB7XG4gICAgICAgIHVwZGF0ZU1hcmsgPSB1cGRhdGVNYXJrLmVuZFxuICAgICAgfVxuICAgICAgZWxlbWVudC5lbGVtZW50Lmluc2VydEFmdGVyKGVuZCwgdXBkYXRlTWFyaylcbiAgICAgIGVsZW1lbnQuZWxlbWVudC5pbnNlcnRBZnRlcihzdGFydCwgdXBkYXRlTWFyaylcbiAgICAgIGVsZW1lbnQudXBkYXRlTWFyayA9IGVuZFxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGVsZW1lbnQuZWxlbWVudC5pbnNlcnRCZWZvcmUoc3RhcnQsIGVsZW1lbnQuZW5kKVxuICAgICAgZWxlbWVudC5lbGVtZW50Lmluc2VydEJlZm9yZShlbmQsIGVsZW1lbnQuZW5kKVxuICAgIH1cbiAgICBlbGVtZW50ID0gZWxlbWVudC5lbGVtZW50XG4gIH1cbiAgZWxzZSB7XG4gICAgZWxlbWVudC5hcHBlbmRDaGlsZChzdGFydClcbiAgICBlbGVtZW50LmFwcGVuZENoaWxkKGVuZClcbiAgfVxuICByZXR1cm4geyBzdGFydCwgZW5kLCBlbGVtZW50LCBibG9ja0lkIH1cbn1cblxubGV0IGxhc3Rlc3RCbG9ja0lkID0gMVxuXG4vKipcbiAqIENyZWF0ZSBhbmQgcmV0dXJuIGEgYmxvY2sgc3RhcnRlci5cbiAqIFVzaW5nIHRoaXMuX2FwcC5kb2NcbiAqL1xuZnVuY3Rpb24gY3JlYXRlQmxvY2tTdGFydCAodm0pIHtcbiAgY29uc3QgZG9jID0gdm0uX2FwcC5kb2NcbiAgY29uc3QgYW5jaG9yID0gZG9jLmNyZWF0ZUNvbW1lbnQoJ3N0YXJ0JylcbiAgcmV0dXJuIGFuY2hvclxufVxuXG4vKipcbiAqIENyZWF0ZSBhbmQgcmV0dXJuIGEgYmxvY2sgZW5kZXIuXG4gKiBVc2luZyB0aGlzLl9hcHAuZG9jXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUJsb2NrRW5kICh2bSkge1xuICBjb25zdCBkb2MgPSB2bS5fYXBwLmRvY1xuICBjb25zdCBhbmNob3IgPSBkb2MuY3JlYXRlQ29tbWVudCgnZW5kJylcbiAgcmV0dXJuIGFuY2hvclxufVxuXG4vKipcbiAqIEF0dGFjaCB0YXJnZXQgdG8gYSBjZXJ0YWluIGRlc3QgdXNpbmcgYXBwZW5kQ2hpbGQgYnkgZGVmYXVsdC5cbiAqIElmIHRoZSBkZXN0IGlzIGEgZnJhZyBibG9jayB0aGVuIGluc2VydCBiZWZvcmUgdGhlIGVuZGVyLlxuICogSWYgdGhlIHRhcmdldCBpcyBhIGZyYWcgYmxvY2sgdGhlbiBhdHRhY2ggdGhlIHN0YXJ0ZXIgYW5kIGVuZGVyIGluIG9yZGVyLlxuICpcbiAqIEBwYXJhbSAge29iamVjdH0gdGFyZ2V0XG4gKiBAcGFyYW0gIHtvYmplY3R9IGRlc3RcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGF0dGFjaFRhcmdldCAodm0sIHRhcmdldCwgZGVzdCkge1xuICBpZiAoZGVzdC5lbGVtZW50KSB7XG4gICAgY29uc3QgYmVmb3JlID0gZGVzdC5lbmRcbiAgICBjb25zdCBhZnRlciA9IGRlc3QudXBkYXRlTWFya1xuICAgIC8vIHB1c2ggbmV3IHRhcmdldCBmb3Igd2F0Y2ggbGlzdCB1cGRhdGUgbGF0ZXJcbiAgICBpZiAoZGVzdC5jaGlsZHJlbikge1xuICAgICAgZGVzdC5jaGlsZHJlbi5wdXNoKHRhcmdldClcbiAgICB9XG4gICAgLy8gZm9yIGNoZWNrIHJlcGVhdCBjYXNlXG4gICAgaWYgKGFmdGVyKSB7XG4gICAgICBjb25zdCBzaWduYWwgPSBtb3ZlVGFyZ2V0KHZtLCB0YXJnZXQsIGFmdGVyKVxuICAgICAgZGVzdC51cGRhdGVNYXJrID0gdGFyZ2V0LmVsZW1lbnQgPyB0YXJnZXQuZW5kIDogdGFyZ2V0XG4gICAgICByZXR1cm4gc2lnbmFsXG4gICAgfVxuICAgIGVsc2UgaWYgKHRhcmdldC5lbGVtZW50KSB7XG4gICAgICBkZXN0LmVsZW1lbnQuaW5zZXJ0QmVmb3JlKHRhcmdldC5zdGFydCwgYmVmb3JlKVxuICAgICAgZGVzdC5lbGVtZW50Lmluc2VydEJlZm9yZSh0YXJnZXQuZW5kLCBiZWZvcmUpXG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgcmV0dXJuIGRlc3QuZWxlbWVudC5pbnNlcnRCZWZvcmUodGFyZ2V0LCBiZWZvcmUpXG4gICAgfVxuICB9XG4gIGVsc2Uge1xuICAgIGlmICh0YXJnZXQuZWxlbWVudCkge1xuICAgICAgZGVzdC5hcHBlbmRDaGlsZCh0YXJnZXQuc3RhcnQpXG4gICAgICBkZXN0LmFwcGVuZENoaWxkKHRhcmdldC5lbmQpXG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgcmV0dXJuIGRlc3QuYXBwZW5kQ2hpbGQodGFyZ2V0KVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIE1vdmUgdGFyZ2V0IGJlZm9yZSBhIGNlcnRhaW4gZWxlbWVudC4gVGhlIHRhcmdldCBtYXliZSBibG9jayBvciBlbGVtZW50LlxuICpcbiAqIEBwYXJhbSAge29iamVjdH0gdGFyZ2V0XG4gKiBAcGFyYW0gIHtvYmplY3R9IGJlZm9yZVxuICovXG5leHBvcnQgZnVuY3Rpb24gbW92ZVRhcmdldCAodm0sIHRhcmdldCwgYWZ0ZXIpIHtcbiAgaWYgKHRhcmdldC5lbGVtZW50KSB7XG4gICAgcmV0dXJuIG1vdmVCbG9jayh0YXJnZXQsIGFmdGVyKVxuICB9XG4gIHJldHVybiBtb3ZlRWxlbWVudCh0YXJnZXQsIGFmdGVyKVxufVxuXG4vKipcbiAqIE1vdmUgZWxlbWVudCBiZWZvcmUgYSBjZXJ0YWluIGVsZW1lbnQuXG4gKlxuICogQHBhcmFtICB7b2JqZWN0fSBlbGVtZW50XG4gKiBAcGFyYW0gIHtvYmplY3R9IGJlZm9yZVxuICovXG5mdW5jdGlvbiBtb3ZlRWxlbWVudCAoZWxlbWVudCwgYWZ0ZXIpIHtcbiAgY29uc3QgcGFyZW50ID0gYWZ0ZXIucGFyZW50Tm9kZVxuICBpZiAocGFyZW50KSB7XG4gICAgcmV0dXJuIHBhcmVudC5pbnNlcnRBZnRlcihlbGVtZW50LCBhZnRlcilcbiAgfVxufVxuXG4vKipcbiAqIE1vdmUgYWxsIGVsZW1lbnRzIG9mIHRoZSBibG9jayBiZWZvcmUgYSBjZXJ0YWluIGVsZW1lbnQuXG4gKlxuICogQHBhcmFtICB7b2JqZWN0fSBmcmFnQmxvY2tcbiAqIEBwYXJhbSAge29iamVjdH0gYmVmb3JlXG4gKi9cbmZ1bmN0aW9uIG1vdmVCbG9jayAoZnJhZ0Jsb2NrLCBhZnRlcikge1xuICBjb25zdCBwYXJlbnQgPSBhZnRlci5wYXJlbnROb2RlXG5cbiAgaWYgKHBhcmVudCkge1xuICAgIGxldCBlbCA9IGZyYWdCbG9jay5zdGFydFxuICAgIGxldCBzaWduYWxcbiAgICBjb25zdCBncm91cCA9IFtlbF1cblxuICAgIHdoaWxlIChlbCAmJiBlbCAhPT0gZnJhZ0Jsb2NrLmVuZCkge1xuICAgICAgZWwgPSBlbC5uZXh0U2libGluZ1xuICAgICAgZ3JvdXAucHVzaChlbClcbiAgICB9XG5cbiAgICBsZXQgdGVtcCA9IGFmdGVyXG4gICAgZ3JvdXAuZXZlcnkoKGVsKSA9PiB7XG4gICAgICBzaWduYWwgPSBwYXJlbnQuaW5zZXJ0QWZ0ZXIoZWwsIHRlbXApXG4gICAgICB0ZW1wID0gZWxcbiAgICAgIHJldHVybiBzaWduYWwgIT09IC0xXG4gICAgfSlcblxuICAgIHJldHVybiBzaWduYWxcbiAgfVxufVxuXG4vKipcbiAqIFJlbW92ZSB0YXJnZXQgZnJvbSBET00gdHJlZS5cbiAqIElmIHRoZSB0YXJnZXQgaXMgYSBmcmFnIGJsb2NrIHRoZW4gY2FsbCBfcmVtb3ZlQmxvY2tcbiAqXG4gKiBAcGFyYW0gIHtvYmplY3R9IHRhcmdldFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlVGFyZ2V0ICh2bSwgdGFyZ2V0LCBwcmVzZXJ2ZUJsb2NrID0gZmFsc2UpIHtcbiAgaWYgKHRhcmdldC5lbGVtZW50KSB7XG4gICAgcmVtb3ZlQmxvY2sodGFyZ2V0LCBwcmVzZXJ2ZUJsb2NrKVxuICB9XG4gIGVsc2Uge1xuICAgIHJlbW92ZUVsZW1lbnQodGFyZ2V0KVxuICB9XG4gIGlmICh0YXJnZXQuX3ZtKSB7XG4gICAgdGFyZ2V0Ll92bS4kZW1pdCgnaG9vazpkZXN0cm95ZWQnKVxuICB9XG59XG5cbi8qKlxuICogUmVtb3ZlIGEgY2VydGFpbiBlbGVtZW50LlxuICogVXNpbmcgdGhpcy5fYXBwLmRvY1xuICpcbiAqIEBwYXJhbSAge29iamVjdH0gdGFyZ2V0XG4gKi9cbmZ1bmN0aW9uIHJlbW92ZUVsZW1lbnQgKHRhcmdldCkge1xuICBjb25zdCBwYXJlbnQgPSB0YXJnZXQucGFyZW50Tm9kZVxuXG4gIGlmIChwYXJlbnQpIHtcbiAgICBwYXJlbnQucmVtb3ZlQ2hpbGQodGFyZ2V0KVxuICB9XG59XG5cbi8qKlxuICogUmVtb3ZlIGEgZnJhZyBibG9jay5cbiAqIFRoZSBzZWNvbmQgcGFyYW0gZGVjaWRlcyB3aGV0aGVyIHRoZSBibG9jayBzZWxmIHNob3VsZCBiZSByZW1vdmVkIHRvby5cbiAqXG4gKiBAcGFyYW0gIHtvYmplY3R9ICBmcmFnQmxvY2tcbiAqIEBwYXJhbSAge0Jvb2xlYW59IHByZXNlcnZlQmxvY2s9ZmFsc2VcbiAqL1xuZnVuY3Rpb24gcmVtb3ZlQmxvY2sgKGZyYWdCbG9jaywgcHJlc2VydmVCbG9jayA9IGZhbHNlKSB7XG4gIGNvbnN0IHJlc3VsdCA9IFtdXG4gIGxldCBlbCA9IGZyYWdCbG9jay5zdGFydC5uZXh0U2libGluZ1xuXG4gIHdoaWxlIChlbCAmJiBlbCAhPT0gZnJhZ0Jsb2NrLmVuZCkge1xuICAgIHJlc3VsdC5wdXNoKGVsKVxuICAgIGVsID0gZWwubmV4dFNpYmxpbmdcbiAgfVxuXG4gIGlmICghcHJlc2VydmVCbG9jaykge1xuICAgIHJlbW92ZUVsZW1lbnQoZnJhZ0Jsb2NrLnN0YXJ0KVxuICB9XG4gIHJlc3VsdC5mb3JFYWNoKChlbCkgPT4ge1xuICAgIHJlbW92ZUVsZW1lbnQoZWwpXG4gIH0pXG4gIGlmICghcHJlc2VydmVCbG9jaykge1xuICAgIHJlbW92ZUVsZW1lbnQoZnJhZ0Jsb2NrLmVuZClcbiAgfVxufVxuIiwiLypcbiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmVcbiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZVxuICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb25cbiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGVcbiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGVcbiAqIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZVxuICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLFxuICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW5cbiAqIFwiQVMgSVNcIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXG4gKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGVcbiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnNcbiAqIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG4vKipcbiAqIEBmaWxlT3ZlcnZpZXdcbiAqIFZpZXdNb2RlbCB0ZW1wbGF0ZSBwYXJzZXIgJiBkYXRhLWJpbmRpbmcgcHJvY2Vzc1xuICovXG5cbmltcG9ydCB7XG4gIGV4dGVuZCxcbiAgaXNPYmplY3QsXG4gIGJpbmRcbn0gZnJvbSAnLi4vdXRpbC9pbmRleCdcbmltcG9ydCB7XG4gIGluaXREYXRhLFxuICBpbml0Q29tcHV0ZWRcbn0gZnJvbSAnLi4vY29yZS9zdGF0ZSdcbmltcG9ydCB7XG4gIGJpbmRFbGVtZW50LFxuICBzZXRJZCxcbiAgYmluZFN1YlZtLFxuICBiaW5kU3ViVm1BZnRlckluaXRpYWxpemVkLFxuICBhcHBseU5haXR2ZUNvbXBvbmVudE9wdGlvbnMsXG4gIHdhdGNoXG59IGZyb20gJy4vZGlyZWN0aXZlJ1xuaW1wb3J0IHtcbiAgY3JlYXRlQmxvY2ssXG4gIGNyZWF0ZUJvZHksXG4gIGNyZWF0ZUVsZW1lbnQsXG4gIGF0dGFjaFRhcmdldCxcbiAgbW92ZVRhcmdldCxcbiAgcmVtb3ZlVGFyZ2V0XG59IGZyb20gJy4vZG9tLWhlbHBlcidcblxuLyoqXG4gKiBidWlsZCgpXG4gKiAgIGNvbXBpbGUodGVtcGxhdGUsIHBhcmVudE5vZGUpXG4gKiAgICAgaWYgKHR5cGUgaXMgY29udGVudCkgY3JlYXRlIGNvbnRlbnROb2RlXG4gKiAgICAgZWxzZSBpZiAoZGlycyBoYXZlIHYtZm9yKSBmb3JlYWNoIC0+IGNyZWF0ZSBjb250ZXh0XG4gKiAgICAgICAtPiBjb21waWxlKHRlbXBsYXRlV2l0aG91dEZvciwgcGFyZW50Tm9kZSk6IGRpZmYobGlzdCkgb25jaGFuZ2VcbiAqICAgICBlbHNlIGlmIChkaXJzIGhhdmUgdi1pZikgYXNzZXJ0XG4gKiAgICAgICAtPiBjb21waWxlKHRlbXBsYXRlV2l0aG91dElmLCBwYXJlbnROb2RlKTogdG9nZ2xlKHNob3duKSBvbmNoYW5nZVxuICogICAgIGVsc2UgaWYgKHR5cGUgaXMgZHluYW1pYylcbiAqICAgICAgIC0+IGNvbXBpbGUodGVtcGxhdGVXaXRob3V0RHluYW1pY1R5cGUsIHBhcmVudE5vZGUpOiB3YXRjaCh0eXBlKSBvbmNoYW5nZVxuICogICAgIGVsc2UgaWYgKHR5cGUgaXMgY3VzdG9tKVxuICogICAgICAgYWRkQ2hpbGRWbSh2bSwgcGFyZW50Vm0pXG4gKiAgICAgICBidWlsZChleHRlcm5hbERpcnMpXG4gKiAgICAgICBmb3JlYWNoIGNoaWxkTm9kZXMgLT4gY29tcGlsZShjaGlsZE5vZGUsIHRlbXBsYXRlKVxuICogICAgIGVsc2UgaWYgKHR5cGUgaXMgbmF0aXZlKVxuICogICAgICAgc2V0KGRpcnMpOiB1cGRhdGUoaWQvYXR0ci9zdHlsZS9jbGFzcykgb25jaGFuZ2VcbiAqICAgICAgIGFwcGVuZCh0ZW1wbGF0ZSwgcGFyZW50Tm9kZSlcbiAqICAgICAgIGZvcmVhY2ggY2hpbGROb2RlcyAtPiBjb21waWxlKGNoaWxkTm9kZSwgdGVtcGxhdGUpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZCAodm0pIHtcbiAgY29uc3Qgb3B0ID0gdm0uX29wdGlvbnMgfHwge31cbiAgY29uc3QgdGVtcGxhdGUgPSBvcHQudGVtcGxhdGUgfHwge31cblxuICBpZiAob3B0LnJlcGxhY2UpIHtcbiAgICBpZiAodGVtcGxhdGUuY2hpbGRyZW4gJiYgdGVtcGxhdGUuY2hpbGRyZW4ubGVuZ3RoID09PSAxKSB7XG4gICAgICBjb21waWxlKHZtLCB0ZW1wbGF0ZS5jaGlsZHJlblswXSwgdm0uX3BhcmVudEVsKVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGNvbXBpbGUodm0sIHRlbXBsYXRlLmNoaWxkcmVuLCB2bS5fcGFyZW50RWwpXG4gICAgfVxuICB9XG4gIGVsc2Uge1xuICAgIGNvbXBpbGUodm0sIHRlbXBsYXRlLCB2bS5fcGFyZW50RWwpXG4gIH1cblxuICBjb25zb2xlLmRlYnVnKGBbSlMgRnJhbWV3b3JrXSBcInJlYWR5XCIgbGlmZWN5Y2xlIGluIFZtKCR7dm0uX3R5cGV9KWApXG4gIHZtLiRlbWl0KCdob29rOnJlYWR5JylcbiAgdm0uX3JlYWR5ID0gdHJ1ZVxufVxuXG4vKipcbiAqIEdlbmVyYXRlIGVsZW1lbnRzIGJ5IGNoaWxkIG9yIGNoaWxkcmVuIGFuZCBhcHBlbmQgdG8gcGFyZW50IGVsZW1lbnRzLlxuICogUm9vdCBlbGVtZW50IGluZm8gd291bGQgYmUgbWVyZ2VkIGlmIGhhcy4gVGhlIGZpcnN0IGFyZ3VtZW50IG1heSBiZSBhbiBhcnJheVxuICogaWYgdGhlIHJvb3QgZWxlbWVudCB3aXRoIG9wdGlvbnMucmVwbGFjZSBoYXMgbm90IG9ubHkgb25lIGNoaWxkLlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fGFycmF5fSB0YXJnZXRcbiAqIEBwYXJhbSB7b2JqZWN0fSAgICAgICBkZXN0XG4gKiBAcGFyYW0ge29iamVjdH0gICAgICAgbWV0YVxuICovXG5mdW5jdGlvbiBjb21waWxlICh2bSwgdGFyZ2V0LCBkZXN0LCBtZXRhKSB7XG4gIGNvbnN0IGFwcCA9IHZtLl9hcHAgfHwge31cblxuICBpZiAoYXBwLmxhc3RTaWduYWwgPT09IC0xKSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICBpZiAodGFyZ2V0LmF0dHIgJiYgdGFyZ2V0LmF0dHIuaGFzT3duUHJvcGVydHkoJ3N0YXRpYycpKSB7XG4gICAgdm0uX3N0YXRpYyA9IHRydWVcbiAgfVxuXG4gIGlmICh0YXJnZXRJc0ZyYWdtZW50KHRhcmdldCkpIHtcbiAgICBjb21waWxlRnJhZ21lbnQodm0sIHRhcmdldCwgZGVzdCwgbWV0YSlcbiAgICByZXR1cm5cbiAgfVxuICBtZXRhID0gbWV0YSB8fCB7fVxuICBpZiAodGFyZ2V0SXNDb250ZW50KHRhcmdldCkpIHtcbiAgICBjb25zb2xlLmRlYnVnKCdbSlMgRnJhbWV3b3JrXSBjb21waWxlIFwiY29udGVudFwiIGJsb2NrIGJ5JywgdGFyZ2V0KVxuICAgIHZtLl9jb250ZW50ID0gY3JlYXRlQmxvY2sodm0sIGRlc3QpXG4gICAgcmV0dXJuXG4gIH1cblxuICBpZiAodGFyZ2V0TmVlZENoZWNrUmVwZWF0KHRhcmdldCwgbWV0YSkpIHtcbiAgICBjb25zb2xlLmRlYnVnKCdbSlMgRnJhbWV3b3JrXSBjb21waWxlIFwicmVwZWF0XCIgbG9naWMgYnknLCB0YXJnZXQpXG4gICAgaWYgKGRlc3QudHlwZSA9PT0gJ2RvY3VtZW50Jykge1xuICAgICAgY29uc29sZS53YXJuKCdbSlMgRnJhbWV3b3JrXSBUaGUgcm9vdCBlbGVtZW50IGRvZXNcXCd0IHN1cHBvcnQgYHJlcGVhdGAgZGlyZWN0aXZlIScpXG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgY29tcGlsZVJlcGVhdCh2bSwgdGFyZ2V0LCBkZXN0KVxuICAgIH1cbiAgICByZXR1cm5cbiAgfVxuICBpZiAodGFyZ2V0TmVlZENoZWNrU2hvd24odGFyZ2V0LCBtZXRhKSkge1xuICAgIGNvbnNvbGUuZGVidWcoJ1tKUyBGcmFtZXdvcmtdIGNvbXBpbGUgXCJpZlwiIGxvZ2ljIGJ5JywgdGFyZ2V0KVxuICAgIGlmIChkZXN0LnR5cGUgPT09ICdkb2N1bWVudCcpIHtcbiAgICAgIGNvbnNvbGUud2FybignW0pTIEZyYW1ld29ya10gVGhlIHJvb3QgZWxlbWVudCBkb2VzXFwndCBzdXBwb3J0IGBpZmAgZGlyZWN0aXZlIScpXG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgY29tcGlsZVNob3duKHZtLCB0YXJnZXQsIGRlc3QsIG1ldGEpXG4gICAgfVxuICAgIHJldHVyblxuICB9XG4gIGNvbnN0IHR5cGVHZXR0ZXIgPSBtZXRhLnR5cGUgfHwgdGFyZ2V0LnR5cGVcbiAgaWYgKHRhcmdldE5lZWRDaGVja1R5cGUodHlwZUdldHRlciwgbWV0YSkpIHtcbiAgICBjb21waWxlVHlwZSh2bSwgdGFyZ2V0LCBkZXN0LCB0eXBlR2V0dGVyLCBtZXRhKVxuICAgIHJldHVyblxuICB9XG4gIGNvbnN0IHR5cGUgPSB0eXBlR2V0dGVyXG4gIGNvbnN0IGNvbXBvbmVudCA9IHRhcmdldElzQ29tcG9zZWQodm0sIHRhcmdldCwgdHlwZSlcbiAgaWYgKGNvbXBvbmVudCkge1xuICAgIGNvbnNvbGUuZGVidWcoJ1tKUyBGcmFtZXdvcmtdIGNvbXBpbGUgY29tcG9zZWQgY29tcG9uZW50IGJ5JywgdGFyZ2V0KVxuICAgIGNvbXBpbGVDdXN0b21Db21wb25lbnQodm0sIGNvbXBvbmVudCwgdGFyZ2V0LCBkZXN0LCB0eXBlLCBtZXRhKVxuICAgIHJldHVyblxuICB9XG4gIGNvbnNvbGUuZGVidWcoJ1tKUyBGcmFtZXdvcmtdIGNvbXBpbGUgbmF0aXZlIGNvbXBvbmVudCBieScsIHRhcmdldClcbiAgY29tcGlsZU5hdGl2ZUNvbXBvbmVudCh2bSwgdGFyZ2V0LCBkZXN0LCB0eXBlKVxufVxuXG4vKipcbiAqIENoZWNrIGlmIHRhcmdldCBpcyBhIGZyYWdtZW50IChhbiBhcnJheSkuXG4gKlxuICogQHBhcmFtICB7b2JqZWN0fSAgdGFyZ2V0XG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5mdW5jdGlvbiB0YXJnZXRJc0ZyYWdtZW50ICh0YXJnZXQpIHtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkodGFyZ2V0KVxufVxuXG4vKipcbiAqIENoZWNrIGlmIHRhcmdldCB0eXBlIGlzIGNvbnRlbnQvc2xvdC5cbiAqXG4gKiBAcGFyYW0gIHtvYmplY3R9ICB0YXJnZXRcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIHRhcmdldElzQ29udGVudCAodGFyZ2V0KSB7XG4gIHJldHVybiB0YXJnZXQudHlwZSA9PT0gJ2NvbnRlbnQnIHx8IHRhcmdldC50eXBlID09PSAnc2xvdCdcbn1cblxuLyoqXG4gKiBDaGVjayBpZiB0YXJnZXQgbmVlZCB0byBjb21waWxlIGJ5IGEgbGlzdC5cbiAqXG4gKiBAcGFyYW0gIHtvYmplY3R9ICB0YXJnZXRcbiAqIEBwYXJhbSAge29iamVjdH0gIG1ldGFcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIHRhcmdldE5lZWRDaGVja1JlcGVhdCAodGFyZ2V0LCBtZXRhKSB7XG4gIHJldHVybiAhbWV0YS5oYXNPd25Qcm9wZXJ0eSgncmVwZWF0JykgJiYgdGFyZ2V0LnJlcGVhdFxufVxuXG4vKipcbiAqIENoZWNrIGlmIHRhcmdldCBuZWVkIHRvIGNvbXBpbGUgYnkgYSBib29sZWFuIHZhbHVlLlxuICpcbiAqIEBwYXJhbSAge29iamVjdH0gIHRhcmdldFxuICogQHBhcmFtICB7b2JqZWN0fSAgbWV0YVxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gdGFyZ2V0TmVlZENoZWNrU2hvd24gKHRhcmdldCwgbWV0YSkge1xuICByZXR1cm4gIW1ldGEuaGFzT3duUHJvcGVydHkoJ3Nob3duJykgJiYgdGFyZ2V0LnNob3duXG59XG5cbi8qKlxuICogQ2hlY2sgaWYgdGFyZ2V0IG5lZWQgdG8gY29tcGlsZSBieSBhIGR5bmFtaWMgdHlwZS5cbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd8ZnVuY3Rpb259IHR5cGVHZXR0ZXJcbiAqIEBwYXJhbSAge29iamVjdH0gICAgICAgICAgbWV0YVxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gdGFyZ2V0TmVlZENoZWNrVHlwZSAodHlwZUdldHRlciwgbWV0YSkge1xuICByZXR1cm4gKHR5cGVvZiB0eXBlR2V0dGVyID09PSAnZnVuY3Rpb24nKSAmJiAhbWV0YS5oYXNPd25Qcm9wZXJ0eSgndHlwZScpXG59XG5cbi8qKlxuICogQ2hlY2sgaWYgdGhpcyBraW5kIG9mIGNvbXBvbmVudCBpcyBjb21wb3NlZC5cbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd9ICB0eXBlXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5mdW5jdGlvbiB0YXJnZXRJc0NvbXBvc2VkICh2bSwgdGFyZ2V0LCB0eXBlKSB7XG4gIGxldCBjb21wb25lbnRcbiAgaWYgKHZtLl9hcHAgJiYgdm0uX2FwcC5jdXN0b21Db21wb25lbnRNYXApIHtcbiAgICBjb21wb25lbnQgPSB2bS5fYXBwLmN1c3RvbUNvbXBvbmVudE1hcFt0eXBlXVxuICB9XG4gIGlmICh2bS5fb3B0aW9ucyAmJiB2bS5fb3B0aW9ucy5jb21wb25lbnRzKSB7XG4gICAgY29tcG9uZW50ID0gdm0uX29wdGlvbnMuY29tcG9uZW50c1t0eXBlXVxuICB9XG4gIGlmICh0YXJnZXQuY29tcG9uZW50KSB7XG4gICAgY29tcG9uZW50ID0gY29tcG9uZW50IHx8IHt9XG4gIH1cbiAgcmV0dXJuIGNvbXBvbmVudFxufVxuXG4vKipcbiAqIENvbXBpbGUgYSBsaXN0IG9mIHRhcmdldHMuXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IHRhcmdldFxuICogQHBhcmFtIHtvYmplY3R9IGRlc3RcbiAqIEBwYXJhbSB7b2JqZWN0fSBtZXRhXG4gKi9cbmZ1bmN0aW9uIGNvbXBpbGVGcmFnbWVudCAodm0sIHRhcmdldCwgZGVzdCwgbWV0YSkge1xuICBjb25zdCBmcmFnQmxvY2sgPSBjcmVhdGVCbG9jayh2bSwgZGVzdClcbiAgdGFyZ2V0LmZvckVhY2goKGNoaWxkKSA9PiB7XG4gICAgY29tcGlsZSh2bSwgY2hpbGQsIGZyYWdCbG9jaywgbWV0YSlcbiAgfSlcbn1cblxuLyoqXG4gKiBDb21waWxlIGEgdGFyZ2V0IHdpdGggcmVwZWF0IGRpcmVjdGl2ZS5cbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gdGFyZ2V0XG4gKiBAcGFyYW0ge29iamVjdH0gZGVzdFxuICovXG5mdW5jdGlvbiBjb21waWxlUmVwZWF0ICh2bSwgdGFyZ2V0LCBkZXN0KSB7XG4gIGNvbnN0IHJlcGVhdCA9IHRhcmdldC5yZXBlYXRcbiAgY29uc3Qgb2xkU3R5bGUgPSB0eXBlb2YgcmVwZWF0ID09PSAnZnVuY3Rpb24nXG4gIGxldCBnZXR0ZXIgPSByZXBlYXQuZ2V0dGVyIHx8IHJlcGVhdC5leHByZXNzaW9uIHx8IHJlcGVhdFxuICBpZiAodHlwZW9mIGdldHRlciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIGdldHRlciA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIFtdIH1cbiAgfVxuICBjb25zdCBrZXkgPSByZXBlYXQua2V5IHx8ICckaW5kZXgnXG4gIGNvbnN0IHZhbHVlID0gcmVwZWF0LnZhbHVlIHx8ICckdmFsdWUnXG4gIGNvbnN0IHRyYWNrQnkgPSByZXBlYXQudHJhY2tCeSB8fCB0YXJnZXQudHJhY2tCeSB8fFxuICAgICh0YXJnZXQuYXR0ciAmJiB0YXJnZXQuYXR0ci50cmFja0J5KVxuXG4gIGNvbnN0IGZyYWdCbG9jayA9IGNyZWF0ZUJsb2NrKHZtLCBkZXN0KVxuICBmcmFnQmxvY2suY2hpbGRyZW4gPSBbXVxuICBmcmFnQmxvY2suZGF0YSA9IFtdXG4gIGZyYWdCbG9jay52bXMgPSBbXVxuXG4gIGJpbmRSZXBlYXQodm0sIHRhcmdldCwgZnJhZ0Jsb2NrLCB7IGdldHRlciwga2V5LCB2YWx1ZSwgdHJhY2tCeSwgb2xkU3R5bGUgfSlcbn1cblxuLyoqXG4gKiBDb21waWxlIGEgdGFyZ2V0IHdpdGggaWYgZGlyZWN0aXZlLlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSB0YXJnZXRcbiAqIEBwYXJhbSB7b2JqZWN0fSBkZXN0XG4gKiBAcGFyYW0ge29iamVjdH0gbWV0YVxuICovXG5mdW5jdGlvbiBjb21waWxlU2hvd24gKHZtLCB0YXJnZXQsIGRlc3QsIG1ldGEpIHtcbiAgY29uc3QgbmV3TWV0YSA9IHsgc2hvd246IHRydWUgfVxuICBjb25zdCBmcmFnQmxvY2sgPSBjcmVhdGVCbG9jayh2bSwgZGVzdClcblxuICBpZiAoZGVzdC5lbGVtZW50ICYmIGRlc3QuY2hpbGRyZW4pIHtcbiAgICBkZXN0LmNoaWxkcmVuLnB1c2goZnJhZ0Jsb2NrKVxuICB9XG5cbiAgaWYgKG1ldGEucmVwZWF0KSB7XG4gICAgbmV3TWV0YS5yZXBlYXQgPSBtZXRhLnJlcGVhdFxuICB9XG5cbiAgYmluZFNob3duKHZtLCB0YXJnZXQsIGZyYWdCbG9jaywgbmV3TWV0YSlcbn1cblxuLyoqXG4gKiBDb21waWxlIGEgdGFyZ2V0IHdpdGggZHluYW1pYyBjb21wb25lbnQgdHlwZS5cbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gICB0YXJnZXRcbiAqIEBwYXJhbSB7b2JqZWN0fSAgIGRlc3RcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IHR5cGVHZXR0ZXJcbiAqL1xuZnVuY3Rpb24gY29tcGlsZVR5cGUgKHZtLCB0YXJnZXQsIGRlc3QsIHR5cGVHZXR0ZXIsIG1ldGEpIHtcbiAgY29uc3QgdHlwZSA9IHR5cGVHZXR0ZXIuY2FsbCh2bSlcbiAgY29uc3QgbmV3TWV0YSA9IGV4dGVuZCh7IHR5cGUgfSwgbWV0YSlcbiAgY29uc3QgZnJhZ0Jsb2NrID0gY3JlYXRlQmxvY2sodm0sIGRlc3QpXG5cbiAgaWYgKGRlc3QuZWxlbWVudCAmJiBkZXN0LmNoaWxkcmVuKSB7XG4gICAgZGVzdC5jaGlsZHJlbi5wdXNoKGZyYWdCbG9jaylcbiAgfVxuXG4gIHdhdGNoKHZtLCB0eXBlR2V0dGVyLCAodmFsdWUpID0+IHtcbiAgICBjb25zdCBuZXdNZXRhID0gZXh0ZW5kKHsgdHlwZTogdmFsdWUgfSwgbWV0YSlcbiAgICByZW1vdmVUYXJnZXQodm0sIGZyYWdCbG9jaywgdHJ1ZSlcbiAgICBjb21waWxlKHZtLCB0YXJnZXQsIGZyYWdCbG9jaywgbmV3TWV0YSlcbiAgfSlcblxuICBjb21waWxlKHZtLCB0YXJnZXQsIGZyYWdCbG9jaywgbmV3TWV0YSlcbn1cblxuLyoqXG4gKiBDb21waWxlIGEgY29tcG9zZWQgY29tcG9uZW50LlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSB0YXJnZXRcbiAqIEBwYXJhbSB7b2JqZWN0fSBkZXN0XG4gKiBAcGFyYW0ge3N0cmluZ30gdHlwZVxuICovXG5mdW5jdGlvbiBjb21waWxlQ3VzdG9tQ29tcG9uZW50ICh2bSwgY29tcG9uZW50LCB0YXJnZXQsIGRlc3QsIHR5cGUsIG1ldGEpIHtcbiAgY29uc3QgQ3RvciA9IHZtLmNvbnN0cnVjdG9yXG4gIGNvbnN0IHN1YlZtID0gbmV3IEN0b3IodHlwZSwgY29tcG9uZW50LCB2bSwgZGVzdCwgdW5kZWZpbmVkLCB7XG4gICAgJ2hvb2s6aW5pdCc6IGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmICh2bS5fc3RhdGljKSB7XG4gICAgICAgIHRoaXMuX3N0YXRpYyA9IHZtLl9zdGF0aWNcbiAgICAgIH1cbiAgICAgIHNldElkKHZtLCBudWxsLCB0YXJnZXQuaWQsIHRoaXMpXG4gICAgICAvLyBiaW5kIHRlbXBsYXRlIGVhcmxpZXIgYmVjYXVzZSBvZiBsaWZlY3ljbGUgaXNzdWVzXG4gICAgICB0aGlzLl9leHRlcm5hbEJpbmRpbmcgPSB7XG4gICAgICAgIHBhcmVudDogdm0sXG4gICAgICAgIHRlbXBsYXRlOiB0YXJnZXRcbiAgICAgIH1cbiAgICB9LFxuICAgICdob29rOmNyZWF0ZWQnOiBmdW5jdGlvbiAoKSB7XG4gICAgICBiaW5kU3ViVm0odm0sIHRoaXMsIHRhcmdldCwgbWV0YS5yZXBlYXQpXG4gICAgfSxcbiAgICAnaG9vazpyZWFkeSc6IGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmICh0aGlzLl9jb250ZW50KSB7XG4gICAgICAgIGNvbXBpbGVDaGlsZHJlbih2bSwgdGFyZ2V0LCB0aGlzLl9jb250ZW50KVxuICAgICAgfVxuICAgIH1cbiAgfSlcbiAgYmluZFN1YlZtQWZ0ZXJJbml0aWFsaXplZCh2bSwgc3ViVm0sIHRhcmdldCwgZGVzdClcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZSBlbGVtZW50IGZyb20gdGVtcGxhdGUgYW5kIGF0dGFjaCB0byB0aGUgZGVzdCBpZiBuZWVkZWQuXG4gKiBUaGUgdGltZSB0byBhdHRhY2ggZGVwZW5kcyBvbiB3aGV0aGVyIHRoZSBtb2RlIHN0YXR1cyBpcyBub2RlIG9yIHRyZWUuXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IHRlbXBsYXRlXG4gKiBAcGFyYW0ge29iamVjdH0gZGVzdFxuICogQHBhcmFtIHtzdHJpbmd9IHR5cGVcbiAqL1xuZnVuY3Rpb24gY29tcGlsZU5hdGl2ZUNvbXBvbmVudCAodm0sIHRlbXBsYXRlLCBkZXN0LCB0eXBlKSB7XG4gIGFwcGx5TmFpdHZlQ29tcG9uZW50T3B0aW9ucyh0ZW1wbGF0ZSlcblxuICBsZXQgZWxlbWVudFxuICBpZiAoZGVzdC5yZWYgPT09ICdfZG9jdW1lbnRFbGVtZW50Jykge1xuICAgIC8vIGlmIGl0cyBwYXJlbnQgaXMgZG9jdW1lbnRFbGVtZW50IHRoZW4gaXQncyBhIGJvZHlcbiAgICBjb25zb2xlLmRlYnVnKGBbSlMgRnJhbWV3b3JrXSBjb21waWxlIHRvIGNyZWF0ZSBib2R5IGZvciAke3R5cGV9YClcbiAgICBlbGVtZW50ID0gY3JlYXRlQm9keSh2bSwgdHlwZSlcbiAgfVxuICBlbHNlIHtcbiAgICBjb25zb2xlLmRlYnVnKGBbSlMgRnJhbWV3b3JrXSBjb21waWxlIHRvIGNyZWF0ZSBlbGVtZW50IGZvciAke3R5cGV9YClcbiAgICBlbGVtZW50ID0gY3JlYXRlRWxlbWVudCh2bSwgdHlwZSlcbiAgfVxuXG4gIGlmICghdm0uX3Jvb3RFbCkge1xuICAgIHZtLl9yb290RWwgPSBlbGVtZW50XG4gICAgLy8gYmluZCBldmVudCBlYXJsaWVyIGJlY2F1c2Ugb2YgbGlmZWN5Y2xlIGlzc3Vlc1xuICAgIGNvbnN0IGJpbmRpbmcgPSB2bS5fZXh0ZXJuYWxCaW5kaW5nIHx8IHt9XG4gICAgY29uc3QgdGFyZ2V0ID0gYmluZGluZy50ZW1wbGF0ZVxuICAgIGNvbnN0IHBhcmVudFZtID0gYmluZGluZy5wYXJlbnRcbiAgICBpZiAodGFyZ2V0ICYmIHRhcmdldC5ldmVudHMgJiYgcGFyZW50Vm0gJiYgZWxlbWVudCkge1xuICAgICAgZm9yIChjb25zdCB0eXBlIGluIHRhcmdldC5ldmVudHMpIHtcbiAgICAgICAgY29uc3QgaGFuZGxlciA9IHBhcmVudFZtW3RhcmdldC5ldmVudHNbdHlwZV1dXG4gICAgICAgIGlmIChoYW5kbGVyKSB7XG4gICAgICAgICAgZWxlbWVudC5hZGRFdmVudCh0eXBlLCBiaW5kKGhhbmRsZXIsIHBhcmVudFZtKSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGJpbmRFbGVtZW50KHZtLCBlbGVtZW50LCB0ZW1wbGF0ZSlcblxuICBpZiAodGVtcGxhdGUuYXR0ciAmJiB0ZW1wbGF0ZS5hdHRyLmFwcGVuZCkgeyAvLyBiYWNrd2FyZCwgYXBwZW5kIHByb3AgaW4gYXR0clxuICAgIHRlbXBsYXRlLmFwcGVuZCA9IHRlbXBsYXRlLmF0dHIuYXBwZW5kXG4gIH1cblxuICBpZiAodGVtcGxhdGUuYXBwZW5kKSB7IC8vIGdpdmUgdGhlIGFwcGVuZCBhdHRyaWJ1dGUgZm9yIGlvcyBhZGFwdGF0aW9uXG4gICAgZWxlbWVudC5hdHRyID0gZWxlbWVudC5hdHRyIHx8IHt9XG4gICAgZWxlbWVudC5hdHRyLmFwcGVuZCA9IHRlbXBsYXRlLmFwcGVuZFxuICB9XG5cbiAgY29uc3QgdHJlZU1vZGUgPSB0ZW1wbGF0ZS5hcHBlbmQgPT09ICd0cmVlJ1xuICBjb25zdCBhcHAgPSB2bS5fYXBwIHx8IHt9XG4gIGlmIChhcHAubGFzdFNpZ25hbCAhPT0gLTEgJiYgIXRyZWVNb2RlKSB7XG4gICAgY29uc29sZS5kZWJ1ZygnW0pTIEZyYW1ld29ya10gY29tcGlsZSB0byBhcHBlbmQgc2luZ2xlIG5vZGUgZm9yJywgZWxlbWVudClcbiAgICBhcHAubGFzdFNpZ25hbCA9IGF0dGFjaFRhcmdldCh2bSwgZWxlbWVudCwgZGVzdClcbiAgfVxuICBpZiAoYXBwLmxhc3RTaWduYWwgIT09IC0xKSB7XG4gICAgY29tcGlsZUNoaWxkcmVuKHZtLCB0ZW1wbGF0ZSwgZWxlbWVudClcbiAgfVxuICBpZiAoYXBwLmxhc3RTaWduYWwgIT09IC0xICYmIHRyZWVNb2RlKSB7XG4gICAgY29uc29sZS5kZWJ1ZygnW0pTIEZyYW1ld29ya10gY29tcGlsZSB0byBhcHBlbmQgd2hvbGUgdHJlZSBmb3InLCBlbGVtZW50KVxuICAgIGFwcC5sYXN0U2lnbmFsID0gYXR0YWNoVGFyZ2V0KHZtLCBlbGVtZW50LCBkZXN0KVxuICB9XG59XG5cbi8qKlxuICogU2V0IGFsbCBjaGlsZHJlbiB0byBhIGNlcnRhaW4gcGFyZW50IGVsZW1lbnQuXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IHRlbXBsYXRlXG4gKiBAcGFyYW0ge29iamVjdH0gZGVzdFxuICovXG5mdW5jdGlvbiBjb21waWxlQ2hpbGRyZW4gKHZtLCB0ZW1wbGF0ZSwgZGVzdCkge1xuICBjb25zdCBhcHAgPSB2bS5fYXBwIHx8IHt9XG4gIGNvbnN0IGNoaWxkcmVuID0gdGVtcGxhdGUuY2hpbGRyZW5cbiAgaWYgKGNoaWxkcmVuICYmIGNoaWxkcmVuLmxlbmd0aCkge1xuICAgIGNoaWxkcmVuLmV2ZXJ5KChjaGlsZCkgPT4ge1xuICAgICAgY29tcGlsZSh2bSwgY2hpbGQsIGRlc3QpXG4gICAgICByZXR1cm4gYXBwLmxhc3RTaWduYWwgIT09IC0xXG4gICAgfSlcbiAgfVxufVxuXG4vKipcbiAqIFdhdGNoIHRoZSBsaXN0IHVwZGF0ZSBhbmQgcmVmcmVzaCB0aGUgY2hhbmdlcy5cbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gdGFyZ2V0XG4gKiBAcGFyYW0ge29iamVjdH0gZnJhZ0Jsb2NrIHt2bXMsIGRhdGEsIGNoaWxkcmVufVxuICogQHBhcmFtIHtvYmplY3R9IGluZm8gICAgICB7Z2V0dGVyLCBrZXksIHZhbHVlLCB0cmFja0J5LCBvbGRTdHlsZX1cbiAqL1xuZnVuY3Rpb24gYmluZFJlcGVhdCAodm0sIHRhcmdldCwgZnJhZ0Jsb2NrLCBpbmZvKSB7XG4gIGNvbnN0IHZtcyA9IGZyYWdCbG9jay52bXNcbiAgY29uc3QgY2hpbGRyZW4gPSBmcmFnQmxvY2suY2hpbGRyZW5cbiAgY29uc3QgeyBnZXR0ZXIsIHRyYWNrQnksIG9sZFN0eWxlIH0gPSBpbmZvXG4gIGNvbnN0IGtleU5hbWUgPSBpbmZvLmtleVxuICBjb25zdCB2YWx1ZU5hbWUgPSBpbmZvLnZhbHVlXG5cbiAgZnVuY3Rpb24gY29tcGlsZUl0ZW0gKGl0ZW0sIGluZGV4LCBjb250ZXh0KSB7XG4gICAgbGV0IG1lcmdlZERhdGFcbiAgICBpZiAob2xkU3R5bGUpIHtcbiAgICAgIG1lcmdlZERhdGEgPSBpdGVtXG4gICAgICBpZiAoaXNPYmplY3QoaXRlbSkpIHtcbiAgICAgICAgbWVyZ2VkRGF0YVtrZXlOYW1lXSA9IGluZGV4XG4gICAgICAgIGlmICghbWVyZ2VkRGF0YS5oYXNPd25Qcm9wZXJ0eSgnSU5ERVgnKSkge1xuICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShtZXJnZWREYXRhLCAnSU5ERVgnLCB7XG4gICAgICAgICAgICB2YWx1ZTogKCkgPT4ge1xuICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ1tKUyBGcmFtZXdvcmtdIFwiSU5ERVhcIiBpbiByZXBlYXQgaXMgZGVwcmVjYXRlZCwgJyArXG4gICAgICAgICAgICAgICAgJ3BsZWFzZSB1c2UgXCIkaW5kZXhcIiBpbnN0ZWFkJylcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgY29uc29sZS53YXJuKCdbSlMgRnJhbWV3b3JrXSBFYWNoIGxpc3QgaXRlbSBtdXN0IGJlIGFuIG9iamVjdCBpbiBvbGQtc3R5bGUgcmVwZWF0LCAnXG4gICAgICAgICAgKyAncGxlYXNlIHVzZSBgcmVwZWF0PXt7diBpbiBsaXN0fX1gIGluc3RlYWQuJylcbiAgICAgICAgbWVyZ2VkRGF0YSA9IHt9XG4gICAgICAgIG1lcmdlZERhdGFba2V5TmFtZV0gPSBpbmRleFxuICAgICAgICBtZXJnZWREYXRhW3ZhbHVlTmFtZV0gPSBpdGVtXG4gICAgICB9XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgbWVyZ2VkRGF0YSA9IHt9XG4gICAgICBtZXJnZWREYXRhW2tleU5hbWVdID0gaW5kZXhcbiAgICAgIG1lcmdlZERhdGFbdmFsdWVOYW1lXSA9IGl0ZW1cbiAgICB9XG4gICAgY29uc3QgbmV3Q29udGV4dCA9IG1lcmdlQ29udGV4dChjb250ZXh0LCBtZXJnZWREYXRhKVxuICAgIHZtcy5wdXNoKG5ld0NvbnRleHQpXG4gICAgY29tcGlsZShuZXdDb250ZXh0LCB0YXJnZXQsIGZyYWdCbG9jaywgeyByZXBlYXQ6IGl0ZW0gfSlcbiAgfVxuXG4gIGNvbnN0IGxpc3QgPSB3YXRjaEJsb2NrKHZtLCBmcmFnQmxvY2ssIGdldHRlciwgJ3JlcGVhdCcsXG4gICAgKGRhdGEpID0+IHtcbiAgICAgIGNvbnNvbGUuZGVidWcoJ1tKUyBGcmFtZXdvcmtdIHRoZSBcInJlcGVhdFwiIGl0ZW0gaGFzIGNoYW5nZWQnLCBkYXRhKVxuICAgICAgaWYgKCFmcmFnQmxvY2sgfHwgIWRhdGEpIHtcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG9sZENoaWxkcmVuID0gY2hpbGRyZW4uc2xpY2UoKVxuICAgICAgY29uc3Qgb2xkVm1zID0gdm1zLnNsaWNlKClcbiAgICAgIGNvbnN0IG9sZERhdGEgPSBmcmFnQmxvY2suZGF0YS5zbGljZSgpXG4gICAgICAvLyAxLiBjb2xsZWN0IGFsbCBuZXcgcmVmcyB0cmFjayBieVxuICAgICAgY29uc3QgdHJhY2tNYXAgPSB7fVxuICAgICAgY29uc3QgcmV1c2VkTWFwID0ge31cbiAgICAgIGRhdGEuZm9yRWFjaCgoaXRlbSwgaW5kZXgpID0+IHtcbiAgICAgICAgY29uc3Qga2V5ID0gdHJhY2tCeSA/IGl0ZW1bdHJhY2tCeV0gOiAob2xkU3R5bGUgPyBpdGVtW2tleU5hbWVdIDogaW5kZXgpXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgICAgICBpZiAoa2V5ID09IG51bGwgfHwga2V5ID09PSAnJykge1xuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG4gICAgICAgIHRyYWNrTWFwW2tleV0gPSBpdGVtXG4gICAgICB9KVxuXG4gICAgICAvLyAyLiByZW1vdmUgdW51c2VkIGVsZW1lbnQgZm9yZWFjaCBvbGQgaXRlbVxuICAgICAgY29uc3QgcmV1c2VkTGlzdCA9IFtdXG4gICAgICBvbGREYXRhLmZvckVhY2goKGl0ZW0sIGluZGV4KSA9PiB7XG4gICAgICAgIGNvbnN0IGtleSA9IHRyYWNrQnkgPyBpdGVtW3RyYWNrQnldIDogKG9sZFN0eWxlID8gaXRlbVtrZXlOYW1lXSA6IGluZGV4KVxuICAgICAgICBpZiAodHJhY2tNYXAuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgIHJldXNlZE1hcFtrZXldID0ge1xuICAgICAgICAgICAgaXRlbSwgaW5kZXgsIGtleSxcbiAgICAgICAgICAgIHRhcmdldDogb2xkQ2hpbGRyZW5baW5kZXhdLFxuICAgICAgICAgICAgdm06IG9sZFZtc1tpbmRleF1cbiAgICAgICAgICB9XG4gICAgICAgICAgcmV1c2VkTGlzdC5wdXNoKGl0ZW0pXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgcmVtb3ZlVGFyZ2V0KHZtLCBvbGRDaGlsZHJlbltpbmRleF0pXG4gICAgICAgIH1cbiAgICAgIH0pXG5cbiAgICAgIC8vIDMuIGNyZWF0ZSBuZXcgZWxlbWVudCBmb3JlYWNoIG5ldyBpdGVtXG4gICAgICBjaGlsZHJlbi5sZW5ndGggPSAwXG4gICAgICB2bXMubGVuZ3RoID0gMFxuICAgICAgZnJhZ0Jsb2NrLmRhdGEgPSBkYXRhLnNsaWNlKClcbiAgICAgIGZyYWdCbG9jay51cGRhdGVNYXJrID0gZnJhZ0Jsb2NrLnN0YXJ0XG5cbiAgICAgIGRhdGEuZm9yRWFjaCgoaXRlbSwgaW5kZXgpID0+IHtcbiAgICAgICAgY29uc3Qga2V5ID0gdHJhY2tCeSA/IGl0ZW1bdHJhY2tCeV0gOiAob2xkU3R5bGUgPyBpdGVtW2tleU5hbWVdIDogaW5kZXgpXG4gICAgICAgIGNvbnN0IHJldXNlZCA9IHJldXNlZE1hcFtrZXldXG4gICAgICAgIGlmIChyZXVzZWQpIHtcbiAgICAgICAgICBpZiAocmV1c2VkLml0ZW0gPT09IHJldXNlZExpc3RbMF0pIHtcbiAgICAgICAgICAgIHJldXNlZExpc3Quc2hpZnQoKVxuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldXNlZExpc3QuJHJlbW92ZShyZXVzZWQuaXRlbSlcbiAgICAgICAgICAgIG1vdmVUYXJnZXQodm0sIHJldXNlZC50YXJnZXQsIGZyYWdCbG9jay51cGRhdGVNYXJrLCB0cnVlKVxuICAgICAgICAgIH1cbiAgICAgICAgICBjaGlsZHJlbi5wdXNoKHJldXNlZC50YXJnZXQpXG4gICAgICAgICAgdm1zLnB1c2gocmV1c2VkLnZtKVxuICAgICAgICAgIGlmIChvbGRTdHlsZSkge1xuICAgICAgICAgICAgcmV1c2VkLnZtID0gaXRlbVxuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldXNlZC52bVt2YWx1ZU5hbWVdID0gaXRlbVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXVzZWQudm1ba2V5TmFtZV0gPSBpbmRleFxuICAgICAgICAgIGZyYWdCbG9jay51cGRhdGVNYXJrID0gcmV1c2VkLnRhcmdldFxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGNvbXBpbGVJdGVtKGl0ZW0sIGluZGV4LCB2bSlcbiAgICAgICAgfVxuICAgICAgfSlcblxuICAgICAgZGVsZXRlIGZyYWdCbG9jay51cGRhdGVNYXJrXG4gICAgfVxuICApXG5cbiAgZnJhZ0Jsb2NrLmRhdGEgPSBsaXN0LnNsaWNlKDApXG4gIGxpc3QuZm9yRWFjaCgoaXRlbSwgaW5kZXgpID0+IHtcbiAgICBjb21waWxlSXRlbShpdGVtLCBpbmRleCwgdm0pXG4gIH0pXG59XG5cbi8qKlxuICogV2F0Y2ggdGhlIGRpc3BsYXkgdXBkYXRlIGFuZCBhZGQvcmVtb3ZlIHRoZSBlbGVtZW50LlxuICpcbiAqIEBwYXJhbSAge29iamVjdH0gdGFyZ2V0XG4gKiBAcGFyYW0gIHtvYmplY3R9IGZyYWdCbG9ja1xuICogQHBhcmFtICB7b2JqZWN0fSBjb250ZXh0XG4gKi9cbmZ1bmN0aW9uIGJpbmRTaG93biAodm0sIHRhcmdldCwgZnJhZ0Jsb2NrLCBtZXRhKSB7XG4gIGNvbnN0IGRpc3BsYXkgPSB3YXRjaEJsb2NrKHZtLCBmcmFnQmxvY2ssIHRhcmdldC5zaG93biwgJ3Nob3duJyxcbiAgICAoZGlzcGxheSkgPT4ge1xuICAgICAgY29uc29sZS5kZWJ1ZygnW0pTIEZyYW1ld29ya10gdGhlIFwiaWZcIiBpdGVtIHdhcyBjaGFuZ2VkJywgZGlzcGxheSlcblxuICAgICAgaWYgKCFmcmFnQmxvY2sgfHwgISFmcmFnQmxvY2suZGlzcGxheSA9PT0gISFkaXNwbGF5KSB7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuICAgICAgZnJhZ0Jsb2NrLmRpc3BsYXkgPSAhIWRpc3BsYXlcbiAgICAgIGlmIChkaXNwbGF5KSB7XG4gICAgICAgIGNvbXBpbGUodm0sIHRhcmdldCwgZnJhZ0Jsb2NrLCBtZXRhKVxuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHJlbW92ZVRhcmdldCh2bSwgZnJhZ0Jsb2NrLCB0cnVlKVxuICAgICAgfVxuICAgIH1cbiAgKVxuXG4gIGZyYWdCbG9jay5kaXNwbGF5ID0gISFkaXNwbGF5XG4gIGlmIChkaXNwbGF5KSB7XG4gICAgY29tcGlsZSh2bSwgdGFyZ2V0LCBmcmFnQmxvY2ssIG1ldGEpXG4gIH1cbn1cblxuLyoqXG4gKiBXYXRjaCBjYWxjIHZhbHVlIGNoYW5nZXMgYW5kIGFwcGVuZCBjZXJ0YWluIHR5cGUgYWN0aW9uIHRvIGRpZmZlci5cbiAqIEl0IGlzIHVzZWQgZm9yIGlmIG9yIHJlcGVhdCBkYXRhLWJpbmRpbmcgZ2VuZXJhdG9yLlxuICpcbiAqIEBwYXJhbSAge29iamVjdH0gICBmcmFnQmxvY2tcbiAqIEBwYXJhbSAge2Z1bmN0aW9ufSBjYWxjXG4gKiBAcGFyYW0gIHtzdHJpbmd9ICAgdHlwZVxuICogQHBhcmFtICB7ZnVuY3Rpb259IGhhbmRsZXJcbiAqIEByZXR1cm4ge2FueX0gICAgICBpbml0IHZhbHVlIG9mIGNhbGNcbiAqL1xuZnVuY3Rpb24gd2F0Y2hCbG9jayAodm0sIGZyYWdCbG9jaywgY2FsYywgdHlwZSwgaGFuZGxlcikge1xuICBjb25zdCBkaWZmZXIgPSB2bSAmJiB2bS5fYXBwICYmIHZtLl9hcHAuZGlmZmVyXG4gIGNvbnN0IGNvbmZpZyA9IHt9XG4gIGNvbnN0IGRlcHRoID0gKGZyYWdCbG9jay5lbGVtZW50LmRlcHRoIHx8IDApICsgMVxuXG4gIHJldHVybiB3YXRjaCh2bSwgY2FsYywgKHZhbHVlKSA9PiB7XG4gICAgY29uZmlnLmxhdGVzdFZhbHVlID0gdmFsdWVcbiAgICBpZiAoZGlmZmVyICYmICFjb25maWcucmVjb3JkZWQpIHtcbiAgICAgIGRpZmZlci5hcHBlbmQodHlwZSwgZGVwdGgsIGZyYWdCbG9jay5ibG9ja0lkLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGxhdGVzdFZhbHVlID0gY29uZmlnLmxhdGVzdFZhbHVlXG4gICAgICAgIGhhbmRsZXIobGF0ZXN0VmFsdWUpXG4gICAgICAgIGNvbmZpZy5yZWNvcmRlZCA9IGZhbHNlXG4gICAgICAgIGNvbmZpZy5sYXRlc3RWYWx1ZSA9IHVuZGVmaW5lZFxuICAgICAgfSlcbiAgICB9XG4gICAgY29uZmlnLnJlY29yZGVkID0gdHJ1ZVxuICB9KVxufVxuXG4vKipcbiAqIENsb25lIGEgY29udGV4dCBhbmQgbWVyZ2UgY2VydGFpbiBkYXRhLlxuICpcbiAqIEBwYXJhbSAge29iamVjdH0gbWVyZ2VkRGF0YVxuICogQHJldHVybiB7b2JqZWN0fVxuICovXG5mdW5jdGlvbiBtZXJnZUNvbnRleHQgKGNvbnRleHQsIG1lcmdlZERhdGEpIHtcbiAgY29uc3QgbmV3Q29udGV4dCA9IE9iamVjdC5jcmVhdGUoY29udGV4dClcbiAgbmV3Q29udGV4dC5fZGF0YSA9IG1lcmdlZERhdGFcbiAgaW5pdERhdGEobmV3Q29udGV4dClcbiAgaW5pdENvbXB1dGVkKG5ld0NvbnRleHQpXG4gIG5ld0NvbnRleHQuX3JlYWxQYXJlbnQgPSBjb250ZXh0XG4gIGlmIChjb250ZXh0Ll9zdGF0aWMpIHtcbiAgICBuZXdDb250ZXh0Ll9zdGF0aWMgPSBjb250ZXh0Ll9zdGF0aWNcbiAgfVxuICByZXR1cm4gbmV3Q29udGV4dFxufVxuIiwiLypcbiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmVcbiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZVxuICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb25cbiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGVcbiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGVcbiAqIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZVxuICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLFxuICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW5cbiAqIFwiQVMgSVNcIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXG4gKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGVcbiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnNcbiAqIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG4vKipcbiAqIEBmaWxlT3ZlcnZpZXdcbiAqIEV2ZXJ5dGhpbmcgYWJvdXQgY29tcG9uZW50IGV2ZW50IHdoaWNoIGluY2x1ZGVzIGV2ZW50IG9iamVjdCwgZXZlbnQgbGlzdGVuZXIsXG4gKiBldmVudCBlbWl0dGVyIGFuZCBsaWZlY3ljbGUgaG9va3MuXG4gKi9cblxuLyoqXG4gKiBFdmVudCBvYmplY3QgZGVmaW5pdGlvbi4gQW4gZXZlbnQgb2JqZWN0IGhhcyBgdHlwZWAsIGB0aW1lc3RhbXBgIGFuZFxuICogYGRldGFpbGAgZnJvbSB3aGljaCBhIGNvbXBvbmVudCBlbWl0LiBUaGUgZXZlbnQgb2JqZWN0IGNvdWxkIGJlIGRpc3BhdGNoZWQgdG9cbiAqIHBhcmVudHMgb3IgYnJvYWRjYXN0ZWQgdG8gY2hpbGRyZW4gZXhjZXB0IGB0aGlzLnN0b3AoKWAgaXMgY2FsbGVkLlxuICogQHBhcmFtIHtzdHJpbmd9IHR5cGVcbiAqIEBwYXJhbSB7YW55fSAgICBkZXRhaWxcbiAqL1xuZnVuY3Rpb24gRXZ0ICh0eXBlLCBkZXRhaWwpIHtcbiAgaWYgKGRldGFpbCBpbnN0YW5jZW9mIEV2dCkge1xuICAgIHJldHVybiBkZXRhaWxcbiAgfVxuXG4gIHRoaXMudGltZXN0YW1wID0gRGF0ZS5ub3coKVxuICB0aGlzLmRldGFpbCA9IGRldGFpbFxuICB0aGlzLnR5cGUgPSB0eXBlXG5cbiAgbGV0IHNob3VsZFN0b3AgPSBmYWxzZVxuXG4gIC8qKlxuICAgKiBzdG9wIGRpc3BhdGNoIGFuZCBicm9hZGNhc3RcbiAgICovXG4gIHRoaXMuc3RvcCA9IGZ1bmN0aW9uICgpIHtcbiAgICBzaG91bGRTdG9wID0gdHJ1ZVxuICB9XG5cbiAgLyoqXG4gICAqIGNoZWNrIGlmIGl0IGNhbid0IGJlIGRpc3BhdGNoZWQgb3IgYnJvYWRjYXN0ZWRcbiAgICovXG4gIHRoaXMuaGFzU3RvcHBlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gc2hvdWxkU3RvcFxuICB9XG59XG5cbi8qKlxuICogRW1pdCBhbiBldmVudCBidXQgbm90IGJyb2FkY2FzdCBkb3duIG9yIGRpc3BhdGNoIHVwLlxuICogQHBhcmFtICB7c3RyaW5nfSB0eXBlXG4gKiBAcGFyYW0gIHthbnl9ICAgIGRldGFpbFxuICovXG5leHBvcnQgZnVuY3Rpb24gJGVtaXQgKHR5cGUsIGRldGFpbCkge1xuICBjb25zdCBldmVudHMgPSB0aGlzLl92bUV2ZW50c1xuICBjb25zdCBoYW5kbGVyTGlzdCA9IGV2ZW50c1t0eXBlXVxuICBpZiAoaGFuZGxlckxpc3QpIHtcbiAgICBjb25zdCBldnQgPSBuZXcgRXZ0KHR5cGUsIGRldGFpbClcbiAgICBoYW5kbGVyTGlzdC5mb3JFYWNoKChoYW5kbGVyKSA9PiB7XG4gICAgICBoYW5kbGVyLmNhbGwodGhpcywgZXZ0KVxuICAgIH0pXG4gIH1cbn1cblxuLyoqXG4gKiBFbWl0IGFuIGV2ZW50IGFuZCBkaXNwYXRjaCBpdCB1cC5cbiAqIEBwYXJhbSAge3N0cmluZ30gdHlwZVxuICogQHBhcmFtICB7YW55fSAgICBkZXRhaWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uICRkaXNwYXRjaCAodHlwZSwgZGV0YWlsKSB7XG4gIGNvbnN0IGV2dCA9IG5ldyBFdnQodHlwZSwgZGV0YWlsKVxuICB0aGlzLiRlbWl0KHR5cGUsIGV2dClcblxuICBpZiAoIWV2dC5oYXNTdG9wcGVkKCkgJiYgdGhpcy5fcGFyZW50ICYmIHRoaXMuX3BhcmVudC4kZGlzcGF0Y2gpIHtcbiAgICB0aGlzLl9wYXJlbnQuJGRpc3BhdGNoKHR5cGUsIGV2dClcbiAgfVxufVxuXG4vKipcbiAqIEVtaXQgYW4gZXZlbnQgYW5kIGJyb2FkY2FzdCBpdCBkb3duLlxuICogQHBhcmFtICB7c3RyaW5nfSB0eXBlXG4gKiBAcGFyYW0gIHthbnl9ICAgIGRldGFpbFxuICovXG5leHBvcnQgZnVuY3Rpb24gJGJyb2FkY2FzdCAodHlwZSwgZGV0YWlsKSB7XG4gIGNvbnN0IGV2dCA9IG5ldyBFdnQodHlwZSwgZGV0YWlsKVxuICB0aGlzLiRlbWl0KHR5cGUsIGV2dClcblxuICBpZiAoIWV2dC5oYXNTdG9wcGVkKCkgJiYgdGhpcy5fY2hpbGRyZW5WbXMpIHtcbiAgICB0aGlzLl9jaGlsZHJlblZtcy5mb3JFYWNoKChzdWJWbSkgPT4ge1xuICAgICAgc3ViVm0uJGJyb2FkY2FzdCh0eXBlLCBldnQpXG4gICAgfSlcbiAgfVxufVxuXG4vKipcbiAqIEFkZCBldmVudCBsaXN0ZW5lci5cbiAqIEBwYXJhbSAge3N0cmluZ30gICB0eXBlXG4gKiBAcGFyYW0gIHtmdW5jdGlvbn0gaGFuZGxlclxuICovXG5leHBvcnQgZnVuY3Rpb24gJG9uICh0eXBlLCBoYW5kbGVyKSB7XG4gIGlmICghdHlwZSB8fCB0eXBlb2YgaGFuZGxlciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVyblxuICB9XG4gIGNvbnN0IGV2ZW50cyA9IHRoaXMuX3ZtRXZlbnRzXG4gIGNvbnN0IGhhbmRsZXJMaXN0ID0gZXZlbnRzW3R5cGVdIHx8IFtdXG4gIGhhbmRsZXJMaXN0LnB1c2goaGFuZGxlcilcbiAgZXZlbnRzW3R5cGVdID0gaGFuZGxlckxpc3RcblxuICAvLyBmaXhlZCBvbGQgdmVyc2lvbiBsaWZlY3ljbGUgZGVzaWduXG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICBpZiAodHlwZSA9PT0gJ2hvb2s6cmVhZHknICYmIHRoaXMuX3JlYWR5KSB7XG4gICAgdGhpcy4kZW1pdCgnaG9vazpyZWFkeScpXG4gIH1cbn1cblxuLyoqXG4gKiBSZW1vdmUgZXZlbnQgbGlzdGVuZXIuXG4gKiBAcGFyYW0gIHtzdHJpbmd9ICAgdHlwZVxuICogQHBhcmFtICB7ZnVuY3Rpb259IGhhbmRsZXJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uICRvZmYgKHR5cGUsIGhhbmRsZXIpIHtcbiAgaWYgKCF0eXBlKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgY29uc3QgZXZlbnRzID0gdGhpcy5fdm1FdmVudHNcbiAgaWYgKCFoYW5kbGVyKSB7XG4gICAgZGVsZXRlIGV2ZW50c1t0eXBlXVxuICAgIHJldHVyblxuICB9XG4gIGNvbnN0IGhhbmRsZXJMaXN0ID0gZXZlbnRzW3R5cGVdXG4gIGlmICghaGFuZGxlckxpc3QpIHtcbiAgICByZXR1cm5cbiAgfVxuICBoYW5kbGVyTGlzdC4kcmVtb3ZlKGhhbmRsZXIpXG59XG5cbmNvbnN0IExJRkVfQ1lDTEVfVFlQRVMgPSBbJ2luaXQnLCAnY3JlYXRlZCcsICdyZWFkeScsICdkZXN0cm95ZWQnXVxuXG4vKipcbiAqIEluaXQgZXZlbnRzOlxuICogMS4gbGlzdGVuIGBldmVudHNgIGluIGNvbXBvbmVudCBvcHRpb25zICYgYGV4dGVybmFsRXZlbnRzYC5cbiAqIDIuIGJpbmQgbGlmZWN5Y2xlIGhvb2tzLlxuICogQHBhcmFtICB7Vm19ICAgICB2bVxuICogQHBhcmFtICB7b2JqZWN0fSBleHRlcm5hbEV2ZW50c1xuICovXG5leHBvcnQgZnVuY3Rpb24gaW5pdEV2ZW50cyAodm0sIGV4dGVybmFsRXZlbnRzKSB7XG4gIGNvbnN0IG9wdGlvbnMgPSB2bS5fb3B0aW9ucyB8fCB7fVxuICBjb25zdCBldmVudHMgPSBvcHRpb25zLmV2ZW50cyB8fCB7fVxuICBmb3IgKGNvbnN0IHR5cGUxIGluIGV2ZW50cykge1xuICAgIHZtLiRvbih0eXBlMSwgZXZlbnRzW3R5cGUxXSlcbiAgfVxuICBmb3IgKGNvbnN0IHR5cGUyIGluIGV4dGVybmFsRXZlbnRzKSB7XG4gICAgdm0uJG9uKHR5cGUyLCBleHRlcm5hbEV2ZW50c1t0eXBlMl0pXG4gIH1cbiAgTElGRV9DWUNMRV9UWVBFUy5mb3JFYWNoKCh0eXBlKSA9PiB7XG4gICAgdm0uJG9uKGBob29rOiR7dHlwZX1gLCBvcHRpb25zW3R5cGVdKVxuICB9KVxufVxuXG4vKipcbiAqIEJpbmQgZXZlbnQgcmVsYXRlZCBtZXRob2RzIHRvIFZpZXdNb2RlbCBpbnN0YW5jZS5cbiAqIEBwYXJhbSAge1ZtfSB2bVxuICovXG5leHBvcnQgZnVuY3Rpb24gbWl4aW5FdmVudHMgKHZtKSB7XG4gIHZtLiRlbWl0ID0gJGVtaXRcbiAgdm0uJGRpc3BhdGNoID0gJGRpc3BhdGNoXG4gIHZtLiRicm9hZGNhc3QgPSAkYnJvYWRjYXN0XG4gIHZtLiRvbiA9ICRvblxuICB2bS4kb2ZmID0gJG9mZlxufVxuIiwiLypcbiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmVcbiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZVxuICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb25cbiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGVcbiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGVcbiAqIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZVxuICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLFxuICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW5cbiAqIFwiQVMgSVNcIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXG4gKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGVcbiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnNcbiAqIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG4vKipcbiAqIEBmaWxlT3ZlcnZpZXdcbiAqIFZpZXdNb2RlbCBDb25zdHJ1Y3RvciAmIGRlZmluaXRpb25cbiAqL1xuXG5pbXBvcnQgeyBleHRlbmQgfSBmcm9tICcuLi91dGlsL2luZGV4J1xuaW1wb3J0IHtcbiAgaW5pdFN0YXRlXG59IGZyb20gJy4uL2NvcmUvc3RhdGUnXG5pbXBvcnQge1xuICBidWlsZFxufSBmcm9tICcuL2NvbXBpbGVyJ1xuaW1wb3J0IHtcbiAgc2V0LFxuICBkZWxcbn0gZnJvbSAnLi4vY29yZS9vYnNlcnZlcidcbmltcG9ydCB7XG4gIHdhdGNoXG59IGZyb20gJy4vZGlyZWN0aXZlJ1xuaW1wb3J0IHtcbiAgaW5pdEV2ZW50cyxcbiAgbWl4aW5FdmVudHNcbn0gZnJvbSAnLi9ldmVudHMnXG5cbi8qKlxuICogVmlld01vZGVsIGNvbnN0cnVjdG9yXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHR5cGVcbiAqIEBwYXJhbSB7b2JqZWN0fSBvcHRpb25zICAgIGNvbXBvbmVudCBvcHRpb25zXG4gKiBAcGFyYW0ge29iamVjdH0gcGFyZW50Vm0gICB3aGljaCBjb250YWlucyBfYXBwXG4gKiBAcGFyYW0ge29iamVjdH0gcGFyZW50RWwgICByb290IGVsZW1lbnQgb3IgZnJhZyBibG9ja1xuICogQHBhcmFtIHtvYmplY3R9IG1lcmdlZERhdGEgZXh0ZXJuYWwgZGF0YVxuICogQHBhcmFtIHtvYmplY3R9IGV4dGVybmFsRXZlbnRzIGV4dGVybmFsIGV2ZW50c1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBWbSAoXG4gIHR5cGUsXG4gIG9wdGlvbnMsXG4gIHBhcmVudFZtLFxuICBwYXJlbnRFbCxcbiAgbWVyZ2VkRGF0YSxcbiAgZXh0ZXJuYWxFdmVudHNcbikge1xuICBwYXJlbnRWbSA9IHBhcmVudFZtIHx8IHt9XG4gIHRoaXMuX3BhcmVudCA9IHBhcmVudFZtLl9yZWFsUGFyZW50ID8gcGFyZW50Vm0uX3JlYWxQYXJlbnQgOiBwYXJlbnRWbVxuICB0aGlzLl9hcHAgPSBwYXJlbnRWbS5fYXBwIHx8IHt9XG4gIHBhcmVudFZtLl9jaGlsZHJlblZtcyAmJiBwYXJlbnRWbS5fY2hpbGRyZW5WbXMucHVzaCh0aGlzKVxuXG4gIGlmICghb3B0aW9ucyAmJiB0aGlzLl9hcHAuY3VzdG9tQ29tcG9uZW50TWFwKSB7XG4gICAgb3B0aW9ucyA9IHRoaXMuX2FwcC5jdXN0b21Db21wb25lbnRNYXBbdHlwZV1cbiAgfVxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fVxuXG4gIGNvbnN0IGRhdGEgPSBvcHRpb25zLmRhdGEgfHwge31cblxuICB0aGlzLl9vcHRpb25zID0gb3B0aW9uc1xuICB0aGlzLl9tZXRob2RzID0gb3B0aW9ucy5tZXRob2RzIHx8IHt9XG4gIHRoaXMuX2NvbXB1dGVkID0gb3B0aW9ucy5jb21wdXRlZCB8fCB7fVxuICB0aGlzLl9jc3MgPSBvcHRpb25zLnN0eWxlIHx8IHt9XG4gIHRoaXMuX2lkcyA9IHt9XG4gIHRoaXMuX3ZtRXZlbnRzID0ge31cbiAgdGhpcy5fY2hpbGRyZW5WbXMgPSBbXVxuICB0aGlzLl90eXBlID0gdHlwZVxuXG4gIC8vIGJpbmQgZXZlbnRzIGFuZCBsaWZlY3ljbGVzXG4gIGluaXRFdmVudHModGhpcywgZXh0ZXJuYWxFdmVudHMpXG5cbiAgY29uc29sZS5kZWJ1ZyhgW0pTIEZyYW1ld29ya10gXCJpbml0XCIgbGlmZWN5Y2xlIGluIFZtKCR7dGhpcy5fdHlwZX0pYClcbiAgdGhpcy4kZW1pdCgnaG9vazppbml0JylcbiAgdGhpcy5faW5pdGVkID0gdHJ1ZVxuXG4gIC8vIHByb3h5IGRhdGEgYW5kIG1ldGhvZHNcbiAgLy8gb2JzZXJ2ZSBkYXRhIGFuZCBhZGQgdGhpcyB0byB2bXNcbiAgdGhpcy5fZGF0YSA9IHR5cGVvZiBkYXRhID09PSAnZnVuY3Rpb24nID8gZGF0YSgpIDogZGF0YVxuICBpZiAobWVyZ2VkRGF0YSkge1xuICAgIGV4dGVuZCh0aGlzLl9kYXRhLCBtZXJnZWREYXRhKVxuICB9XG4gIGluaXRTdGF0ZSh0aGlzKVxuXG4gIGNvbnNvbGUuZGVidWcoYFtKUyBGcmFtZXdvcmtdIFwiY3JlYXRlZFwiIGxpZmVjeWNsZSBpbiBWbSgke3RoaXMuX3R5cGV9KWApXG4gIHRoaXMuJGVtaXQoJ2hvb2s6Y3JlYXRlZCcpXG4gIHRoaXMuX2NyZWF0ZWQgPSB0cnVlXG5cbiAgLy8gYmFja3dhcmQgb2xkIHJlYWR5IGVudHJ5XG4gIGlmIChvcHRpb25zLm1ldGhvZHMgJiYgb3B0aW9ucy5tZXRob2RzLnJlYWR5KSB7XG4gICAgY29uc29sZS53YXJuKCdcImV4cG9ydHMubWV0aG9kcy5yZWFkeVwiIGlzIGRlcHJlY2F0ZWQsICcgK1xuICAgICAgJ3BsZWFzZSB1c2UgXCJleHBvcnRzLmNyZWF0ZWRcIiBpbnN0ZWFkJylcbiAgICBvcHRpb25zLm1ldGhvZHMucmVhZHkuY2FsbCh0aGlzKVxuICB9XG5cbiAgaWYgKCF0aGlzLl9hcHAuZG9jKSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICAvLyBpZiBubyBwYXJlbnRFbGVtZW50IHRoZW4gc3BlY2lmeSB0aGUgZG9jdW1lbnRFbGVtZW50XG4gIHRoaXMuX3BhcmVudEVsID0gcGFyZW50RWwgfHwgdGhpcy5fYXBwLmRvYy5kb2N1bWVudEVsZW1lbnRcbiAgYnVpbGQodGhpcylcbn1cblxubWl4aW5FdmVudHMoVm0ucHJvdG90eXBlKVxuXG4vKipcbiAqIFdhdGNoIGFuIGZ1bmN0aW9uIGFuZCBiaW5kIGFsbCB0aGUgZGF0YSBhcHBlYXJlZCBpbiBpdC4gV2hlbiB0aGUgcmVsYXRlZFxuICogZGF0YSBjaGFuZ2VzLCB0aGUgY2FsbGJhY2sgd2lsbCBiZSBjYWxsZWQgd2l0aCBuZXcgdmFsdWUgYXMgMXN0IHBhcmFtLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICovXG5WbS5wcm90b3R5cGUuJHdhdGNoID0gZnVuY3Rpb24gKGZuLCBjYWxsYmFjaykge1xuICB3YXRjaCh0aGlzLCBmbiwgY2FsbGJhY2spXG59XG5cblZtLnNldCA9IHNldFxuVm0uZGVsZXRlID0gZGVsXG4iLCIvKlxuICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZVxuICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlXG4gKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvblxuICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZVxuICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZVxuICogXCJMaWNlbnNlXCIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlXG4gKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsXG4gKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhblxuICogXCJBUyBJU1wiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTllcbiAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZVxuICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9uc1xuICogdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbmxldCBuYXRpdmVNb2R1bGVzID0ge31cblxuLy8gZm9yIHRlc3RpbmdcblxuLyoqXG4gKiBmb3IgdGVzdGluZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0TW9kdWxlIChtb2R1bGVOYW1lKSB7XG4gIHJldHVybiBuYXRpdmVNb2R1bGVzW21vZHVsZU5hbWVdXG59XG5cbi8qKlxuICogZm9yIHRlc3RpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsZWFyTW9kdWxlcyAoKSB7XG4gIG5hdGl2ZU1vZHVsZXMgPSB7fVxufVxuXG4vLyBmb3IgZnJhbWV3b3JrXG5cbi8qKlxuICogaW5pdCBtb2R1bGVzIGZvciBhbiBhcHAgaW5zdGFuY2VcbiAqIHRoZSBzZWNvbmQgcGFyYW0gZGV0ZXJtaW5lcyB3aGV0aGVyIHRvIHJlcGxhY2UgYW4gZXhpc3RlZCBtZXRob2RcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluaXRNb2R1bGVzIChtb2R1bGVzLCBpZlJlcGxhY2UpIHtcbiAgZm9yIChjb25zdCBtb2R1bGVOYW1lIGluIG1vZHVsZXMpIHtcbiAgICAvLyBpbml0IGBtb2R1bGVzW21vZHVsZU5hbWVdW11gXG4gICAgbGV0IG1ldGhvZHMgPSBuYXRpdmVNb2R1bGVzW21vZHVsZU5hbWVdXG4gICAgaWYgKCFtZXRob2RzKSB7XG4gICAgICBtZXRob2RzID0ge31cbiAgICAgIG5hdGl2ZU1vZHVsZXNbbW9kdWxlTmFtZV0gPSBtZXRob2RzXG4gICAgfVxuXG4gICAgLy8gcHVzaCBlYWNoIG5vbi1leGlzdGVkIG5ldyBtZXRob2RcbiAgICBtb2R1bGVzW21vZHVsZU5hbWVdLmZvckVhY2goZnVuY3Rpb24gKG1ldGhvZCkge1xuICAgICAgaWYgKHR5cGVvZiBtZXRob2QgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIG1ldGhvZCA9IHtcbiAgICAgICAgICBuYW1lOiBtZXRob2RcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoIW1ldGhvZHNbbWV0aG9kLm5hbWVdIHx8IGlmUmVwbGFjZSkge1xuICAgICAgICBtZXRob2RzW21ldGhvZC5uYW1lXSA9IG1ldGhvZFxuICAgICAgfVxuICAgIH0pXG4gIH1cbn1cblxuLyoqXG4gKiBpbml0IGFwcCBtZXRob2RzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbml0TWV0aG9kcyAoVm0sIGFwaXMpIHtcbiAgY29uc3QgcCA9IFZtLnByb3RvdHlwZVxuXG4gIGZvciAoY29uc3QgYXBpTmFtZSBpbiBhcGlzKSB7XG4gICAgaWYgKCFwLmhhc093blByb3BlcnR5KGFwaU5hbWUpKSB7XG4gICAgICBwW2FwaU5hbWVdID0gYXBpc1thcGlOYW1lXVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIGdldCBhIG1vZHVsZSBvZiBtZXRob2RzIGZvciBhbiBhcHAgaW5zdGFuY2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVNb2R1bGUgKGFwcCwgbmFtZSkge1xuICBjb25zdCBtZXRob2RzID0gbmF0aXZlTW9kdWxlc1tuYW1lXVxuICBjb25zdCB0YXJnZXQgPSB7fVxuICBmb3IgKGNvbnN0IG1ldGhvZE5hbWUgaW4gbWV0aG9kcykge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIG1ldGhvZE5hbWUsIHtcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICBnZXQ6IGZ1bmN0aW9uIG1vZHVsZUdldHRlciAoKSB7XG4gICAgICAgIHJldHVybiAoLi4uYXJncykgPT4gYXBwLmNhbGxUYXNrcyh7XG4gICAgICAgICAgbW9kdWxlOiBuYW1lLFxuICAgICAgICAgIG1ldGhvZDogbWV0aG9kTmFtZSxcbiAgICAgICAgICBhcmdzOiBhcmdzXG4gICAgICAgIH0pXG4gICAgICB9LFxuICAgICAgc2V0OiBmdW5jdGlvbiBtb2R1bGVTZXR0ZXIgKHZhbHVlKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICByZXR1cm4gYXBwLmNhbGxUYXNrcyh7XG4gICAgICAgICAgICBtb2R1bGU6IG5hbWUsXG4gICAgICAgICAgICBtZXRob2Q6IG1ldGhvZE5hbWUsXG4gICAgICAgICAgICBhcmdzOiBbdmFsdWVdXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pXG4gIH1cbiAgcmV0dXJuIHRhcmdldFxufVxuXG4vKipcbiAqIGdldCBhIGN1c3RvbSBjb21wb25lbnQgb3B0aW9uc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZUN1c3RvbUNvbXBvbmVudCAoYXBwLCBuYW1lKSB7XG4gIGNvbnN0IHsgY3VzdG9tQ29tcG9uZW50TWFwIH0gPSBhcHBcbiAgcmV0dXJuIGN1c3RvbUNvbXBvbmVudE1hcFtuYW1lXVxufVxuXG4vKipcbiAqIHJlZ2lzdGVyIGEgY3VzdG9tIGNvbXBvbmVudCBvcHRpb25zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWdpc3RlckN1c3RvbUNvbXBvbmVudCAoYXBwLCBuYW1lLCBkZWYpIHtcbiAgY29uc3QgeyBjdXN0b21Db21wb25lbnRNYXAgfSA9IGFwcFxuXG4gIGlmIChjdXN0b21Db21wb25lbnRNYXBbbmFtZV0pIHtcbiAgICBjb25zb2xlLmVycm9yKGBbSlMgRnJhbWV3b3JrXSBkZWZpbmUgYSBjb21wb25lbnQoJHtuYW1lfSkgdGhhdCBhbHJlYWR5IGV4aXN0c2ApXG4gICAgcmV0dXJuXG4gIH1cblxuICBjdXN0b21Db21wb25lbnRNYXBbbmFtZV0gPSBkZWZcbn1cbiIsImV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IFNlbVZlcjtcblxuLy8gVGhlIGRlYnVnIGZ1bmN0aW9uIGlzIGV4Y2x1ZGVkIGVudGlyZWx5IGZyb20gdGhlIG1pbmlmaWVkIHZlcnNpb24uXG4vKiBub21pbiAqLyB2YXIgZGVidWc7XG4vKiBub21pbiAqLyBpZiAodHlwZW9mIHByb2Nlc3MgPT09ICdvYmplY3QnICYmXG4gICAgLyogbm9taW4gKi8gcHJvY2Vzcy5lbnYgJiZcbiAgICAvKiBub21pbiAqLyBwcm9jZXNzLmVudi5OT0RFX0RFQlVHICYmXG4gICAgLyogbm9taW4gKi8gL1xcYnNlbXZlclxcYi9pLnRlc3QocHJvY2Vzcy5lbnYuTk9ERV9ERUJVRykpXG4gIC8qIG5vbWluICovIGRlYnVnID0gZnVuY3Rpb24oKSB7XG4gICAgLyogbm9taW4gKi8gdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApO1xuICAgIC8qIG5vbWluICovIGFyZ3MudW5zaGlmdCgnU0VNVkVSJyk7XG4gICAgLyogbm9taW4gKi8gY29uc29sZS5sb2cuYXBwbHkoY29uc29sZSwgYXJncyk7XG4gICAgLyogbm9taW4gKi8gfTtcbi8qIG5vbWluICovIGVsc2VcbiAgLyogbm9taW4gKi8gZGVidWcgPSBmdW5jdGlvbigpIHt9O1xuXG4vLyBOb3RlOiB0aGlzIGlzIHRoZSBzZW12ZXIub3JnIHZlcnNpb24gb2YgdGhlIHNwZWMgdGhhdCBpdCBpbXBsZW1lbnRzXG4vLyBOb3QgbmVjZXNzYXJpbHkgdGhlIHBhY2thZ2UgdmVyc2lvbiBvZiB0aGlzIGNvZGUuXG5leHBvcnRzLlNFTVZFUl9TUEVDX1ZFUlNJT04gPSAnMi4wLjAnO1xuXG52YXIgTUFYX0xFTkdUSCA9IDI1NjtcbnZhciBNQVhfU0FGRV9JTlRFR0VSID0gTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIgfHwgOTAwNzE5OTI1NDc0MDk5MTtcblxuLy8gVGhlIGFjdHVhbCByZWdleHBzIGdvIG9uIGV4cG9ydHMucmVcbnZhciByZSA9IGV4cG9ydHMucmUgPSBbXTtcbnZhciBzcmMgPSBleHBvcnRzLnNyYyA9IFtdO1xudmFyIFIgPSAwO1xuXG4vLyBUaGUgZm9sbG93aW5nIFJlZ3VsYXIgRXhwcmVzc2lvbnMgY2FuIGJlIHVzZWQgZm9yIHRva2VuaXppbmcsXG4vLyB2YWxpZGF0aW5nLCBhbmQgcGFyc2luZyBTZW1WZXIgdmVyc2lvbiBzdHJpbmdzLlxuXG4vLyAjIyBOdW1lcmljIElkZW50aWZpZXJcbi8vIEEgc2luZ2xlIGAwYCwgb3IgYSBub24temVybyBkaWdpdCBmb2xsb3dlZCBieSB6ZXJvIG9yIG1vcmUgZGlnaXRzLlxuXG52YXIgTlVNRVJJQ0lERU5USUZJRVIgPSBSKys7XG5zcmNbTlVNRVJJQ0lERU5USUZJRVJdID0gJzB8WzEtOV1cXFxcZConO1xudmFyIE5VTUVSSUNJREVOVElGSUVSTE9PU0UgPSBSKys7XG5zcmNbTlVNRVJJQ0lERU5USUZJRVJMT09TRV0gPSAnWzAtOV0rJztcblxuXG4vLyAjIyBOb24tbnVtZXJpYyBJZGVudGlmaWVyXG4vLyBaZXJvIG9yIG1vcmUgZGlnaXRzLCBmb2xsb3dlZCBieSBhIGxldHRlciBvciBoeXBoZW4sIGFuZCB0aGVuIHplcm8gb3Jcbi8vIG1vcmUgbGV0dGVycywgZGlnaXRzLCBvciBoeXBoZW5zLlxuXG52YXIgTk9OTlVNRVJJQ0lERU5USUZJRVIgPSBSKys7XG5zcmNbTk9OTlVNRVJJQ0lERU5USUZJRVJdID0gJ1xcXFxkKlthLXpBLVotXVthLXpBLVowLTktXSonO1xuXG5cbi8vICMjIE1haW4gVmVyc2lvblxuLy8gVGhyZWUgZG90LXNlcGFyYXRlZCBudW1lcmljIGlkZW50aWZpZXJzLlxuXG52YXIgTUFJTlZFUlNJT04gPSBSKys7XG5zcmNbTUFJTlZFUlNJT05dID0gJygnICsgc3JjW05VTUVSSUNJREVOVElGSUVSXSArICcpXFxcXC4nICtcbiAgICAgICAgICAgICAgICAgICAnKCcgKyBzcmNbTlVNRVJJQ0lERU5USUZJRVJdICsgJylcXFxcLicgK1xuICAgICAgICAgICAgICAgICAgICcoJyArIHNyY1tOVU1FUklDSURFTlRJRklFUl0gKyAnKSc7XG5cbnZhciBNQUlOVkVSU0lPTkxPT1NFID0gUisrO1xuc3JjW01BSU5WRVJTSU9OTE9PU0VdID0gJygnICsgc3JjW05VTUVSSUNJREVOVElGSUVSTE9PU0VdICsgJylcXFxcLicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJygnICsgc3JjW05VTUVSSUNJREVOVElGSUVSTE9PU0VdICsgJylcXFxcLicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJygnICsgc3JjW05VTUVSSUNJREVOVElGSUVSTE9PU0VdICsgJyknO1xuXG4vLyAjIyBQcmUtcmVsZWFzZSBWZXJzaW9uIElkZW50aWZpZXJcbi8vIEEgbnVtZXJpYyBpZGVudGlmaWVyLCBvciBhIG5vbi1udW1lcmljIGlkZW50aWZpZXIuXG5cbnZhciBQUkVSRUxFQVNFSURFTlRJRklFUiA9IFIrKztcbnNyY1tQUkVSRUxFQVNFSURFTlRJRklFUl0gPSAnKD86JyArIHNyY1tOVU1FUklDSURFTlRJRklFUl0gK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd8JyArIHNyY1tOT05OVU1FUklDSURFTlRJRklFUl0gKyAnKSc7XG5cbnZhciBQUkVSRUxFQVNFSURFTlRJRklFUkxPT1NFID0gUisrO1xuc3JjW1BSRVJFTEVBU0VJREVOVElGSUVSTE9PU0VdID0gJyg/OicgKyBzcmNbTlVNRVJJQ0lERU5USUZJRVJMT09TRV0gK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3wnICsgc3JjW05PTk5VTUVSSUNJREVOVElGSUVSXSArICcpJztcblxuXG4vLyAjIyBQcmUtcmVsZWFzZSBWZXJzaW9uXG4vLyBIeXBoZW4sIGZvbGxvd2VkIGJ5IG9uZSBvciBtb3JlIGRvdC1zZXBhcmF0ZWQgcHJlLXJlbGVhc2UgdmVyc2lvblxuLy8gaWRlbnRpZmllcnMuXG5cbnZhciBQUkVSRUxFQVNFID0gUisrO1xuc3JjW1BSRVJFTEVBU0VdID0gJyg/Oi0oJyArIHNyY1tQUkVSRUxFQVNFSURFTlRJRklFUl0gK1xuICAgICAgICAgICAgICAgICAgJyg/OlxcXFwuJyArIHNyY1tQUkVSRUxFQVNFSURFTlRJRklFUl0gKyAnKSopKSc7XG5cbnZhciBQUkVSRUxFQVNFTE9PU0UgPSBSKys7XG5zcmNbUFJFUkVMRUFTRUxPT1NFXSA9ICcoPzotPygnICsgc3JjW1BSRVJFTEVBU0VJREVOVElGSUVSTE9PU0VdICtcbiAgICAgICAgICAgICAgICAgICAgICAgJyg/OlxcXFwuJyArIHNyY1tQUkVSRUxFQVNFSURFTlRJRklFUkxPT1NFXSArICcpKikpJztcblxuLy8gIyMgQnVpbGQgTWV0YWRhdGEgSWRlbnRpZmllclxuLy8gQW55IGNvbWJpbmF0aW9uIG9mIGRpZ2l0cywgbGV0dGVycywgb3IgaHlwaGVucy5cblxudmFyIEJVSUxESURFTlRJRklFUiA9IFIrKztcbnNyY1tCVUlMRElERU5USUZJRVJdID0gJ1swLTlBLVphLXotXSsnO1xuXG4vLyAjIyBCdWlsZCBNZXRhZGF0YVxuLy8gUGx1cyBzaWduLCBmb2xsb3dlZCBieSBvbmUgb3IgbW9yZSBwZXJpb2Qtc2VwYXJhdGVkIGJ1aWxkIG1ldGFkYXRhXG4vLyBpZGVudGlmaWVycy5cblxudmFyIEJVSUxEID0gUisrO1xuc3JjW0JVSUxEXSA9ICcoPzpcXFxcKygnICsgc3JjW0JVSUxESURFTlRJRklFUl0gK1xuICAgICAgICAgICAgICcoPzpcXFxcLicgKyBzcmNbQlVJTERJREVOVElGSUVSXSArICcpKikpJztcblxuXG4vLyAjIyBGdWxsIFZlcnNpb24gU3RyaW5nXG4vLyBBIG1haW4gdmVyc2lvbiwgZm9sbG93ZWQgb3B0aW9uYWxseSBieSBhIHByZS1yZWxlYXNlIHZlcnNpb24gYW5kXG4vLyBidWlsZCBtZXRhZGF0YS5cblxuLy8gTm90ZSB0aGF0IHRoZSBvbmx5IG1ham9yLCBtaW5vciwgcGF0Y2gsIGFuZCBwcmUtcmVsZWFzZSBzZWN0aW9ucyBvZlxuLy8gdGhlIHZlcnNpb24gc3RyaW5nIGFyZSBjYXB0dXJpbmcgZ3JvdXBzLiAgVGhlIGJ1aWxkIG1ldGFkYXRhIGlzIG5vdCBhXG4vLyBjYXB0dXJpbmcgZ3JvdXAsIGJlY2F1c2UgaXQgc2hvdWxkIG5vdCBldmVyIGJlIHVzZWQgaW4gdmVyc2lvblxuLy8gY29tcGFyaXNvbi5cblxudmFyIEZVTEwgPSBSKys7XG52YXIgRlVMTFBMQUlOID0gJ3Y/JyArIHNyY1tNQUlOVkVSU0lPTl0gK1xuICAgICAgICAgICAgICAgIHNyY1tQUkVSRUxFQVNFXSArICc/JyArXG4gICAgICAgICAgICAgICAgc3JjW0JVSUxEXSArICc/Jztcblxuc3JjW0ZVTExdID0gJ14nICsgRlVMTFBMQUlOICsgJyQnO1xuXG4vLyBsaWtlIGZ1bGwsIGJ1dCBhbGxvd3MgdjEuMi4zIGFuZCA9MS4yLjMsIHdoaWNoIHBlb3BsZSBkbyBzb21ldGltZXMuXG4vLyBhbHNvLCAxLjAuMGFscGhhMSAocHJlcmVsZWFzZSB3aXRob3V0IHRoZSBoeXBoZW4pIHdoaWNoIGlzIHByZXR0eVxuLy8gY29tbW9uIGluIHRoZSBucG0gcmVnaXN0cnkuXG52YXIgTE9PU0VQTEFJTiA9ICdbdj1cXFxcc10qJyArIHNyY1tNQUlOVkVSU0lPTkxPT1NFXSArXG4gICAgICAgICAgICAgICAgIHNyY1tQUkVSRUxFQVNFTE9PU0VdICsgJz8nICtcbiAgICAgICAgICAgICAgICAgc3JjW0JVSUxEXSArICc/JztcblxudmFyIExPT1NFID0gUisrO1xuc3JjW0xPT1NFXSA9ICdeJyArIExPT1NFUExBSU4gKyAnJCc7XG5cbnZhciBHVExUID0gUisrO1xuc3JjW0dUTFRdID0gJygoPzo8fD4pPz0/KSc7XG5cbi8vIFNvbWV0aGluZyBsaWtlIFwiMi4qXCIgb3IgXCIxLjIueFwiLlxuLy8gTm90ZSB0aGF0IFwieC54XCIgaXMgYSB2YWxpZCB4UmFuZ2UgaWRlbnRpZmVyLCBtZWFuaW5nIFwiYW55IHZlcnNpb25cIlxuLy8gT25seSB0aGUgZmlyc3QgaXRlbSBpcyBzdHJpY3RseSByZXF1aXJlZC5cbnZhciBYUkFOR0VJREVOVElGSUVSTE9PU0UgPSBSKys7XG5zcmNbWFJBTkdFSURFTlRJRklFUkxPT1NFXSA9IHNyY1tOVU1FUklDSURFTlRJRklFUkxPT1NFXSArICd8eHxYfFxcXFwqJztcbnZhciBYUkFOR0VJREVOVElGSUVSID0gUisrO1xuc3JjW1hSQU5HRUlERU5USUZJRVJdID0gc3JjW05VTUVSSUNJREVOVElGSUVSXSArICd8eHxYfFxcXFwqJztcblxudmFyIFhSQU5HRVBMQUlOID0gUisrO1xuc3JjW1hSQU5HRVBMQUlOXSA9ICdbdj1cXFxcc10qKCcgKyBzcmNbWFJBTkdFSURFTlRJRklFUl0gKyAnKScgK1xuICAgICAgICAgICAgICAgICAgICcoPzpcXFxcLignICsgc3JjW1hSQU5HRUlERU5USUZJRVJdICsgJyknICtcbiAgICAgICAgICAgICAgICAgICAnKD86XFxcXC4oJyArIHNyY1tYUkFOR0VJREVOVElGSUVSXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgJyg/OicgKyBzcmNbUFJFUkVMRUFTRV0gKyAnKT8nICtcbiAgICAgICAgICAgICAgICAgICBzcmNbQlVJTERdICsgJz8nICtcbiAgICAgICAgICAgICAgICAgICAnKT8pPyc7XG5cbnZhciBYUkFOR0VQTEFJTkxPT1NFID0gUisrO1xuc3JjW1hSQU5HRVBMQUlOTE9PU0VdID0gJ1t2PVxcXFxzXSooJyArIHNyY1tYUkFOR0VJREVOVElGSUVSTE9PU0VdICsgJyknICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcoPzpcXFxcLignICsgc3JjW1hSQU5HRUlERU5USUZJRVJMT09TRV0gKyAnKScgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJyg/OlxcXFwuKCcgKyBzcmNbWFJBTkdFSURFTlRJRklFUkxPT1NFXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKD86JyArIHNyY1tQUkVSRUxFQVNFTE9PU0VdICsgJyk/JyArXG4gICAgICAgICAgICAgICAgICAgICAgICBzcmNbQlVJTERdICsgJz8nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcpPyk/JztcblxudmFyIFhSQU5HRSA9IFIrKztcbnNyY1tYUkFOR0VdID0gJ14nICsgc3JjW0dUTFRdICsgJ1xcXFxzKicgKyBzcmNbWFJBTkdFUExBSU5dICsgJyQnO1xudmFyIFhSQU5HRUxPT1NFID0gUisrO1xuc3JjW1hSQU5HRUxPT1NFXSA9ICdeJyArIHNyY1tHVExUXSArICdcXFxccyonICsgc3JjW1hSQU5HRVBMQUlOTE9PU0VdICsgJyQnO1xuXG4vLyBUaWxkZSByYW5nZXMuXG4vLyBNZWFuaW5nIGlzIFwicmVhc29uYWJseSBhdCBvciBncmVhdGVyIHRoYW5cIlxudmFyIExPTkVUSUxERSA9IFIrKztcbnNyY1tMT05FVElMREVdID0gJyg/On4+PyknO1xuXG52YXIgVElMREVUUklNID0gUisrO1xuc3JjW1RJTERFVFJJTV0gPSAnKFxcXFxzKiknICsgc3JjW0xPTkVUSUxERV0gKyAnXFxcXHMrJztcbnJlW1RJTERFVFJJTV0gPSBuZXcgUmVnRXhwKHNyY1tUSUxERVRSSU1dLCAnZycpO1xudmFyIHRpbGRlVHJpbVJlcGxhY2UgPSAnJDF+JztcblxudmFyIFRJTERFID0gUisrO1xuc3JjW1RJTERFXSA9ICdeJyArIHNyY1tMT05FVElMREVdICsgc3JjW1hSQU5HRVBMQUlOXSArICckJztcbnZhciBUSUxERUxPT1NFID0gUisrO1xuc3JjW1RJTERFTE9PU0VdID0gJ14nICsgc3JjW0xPTkVUSUxERV0gKyBzcmNbWFJBTkdFUExBSU5MT09TRV0gKyAnJCc7XG5cbi8vIENhcmV0IHJhbmdlcy5cbi8vIE1lYW5pbmcgaXMgXCJhdCBsZWFzdCBhbmQgYmFja3dhcmRzIGNvbXBhdGlibGUgd2l0aFwiXG52YXIgTE9ORUNBUkVUID0gUisrO1xuc3JjW0xPTkVDQVJFVF0gPSAnKD86XFxcXF4pJztcblxudmFyIENBUkVUVFJJTSA9IFIrKztcbnNyY1tDQVJFVFRSSU1dID0gJyhcXFxccyopJyArIHNyY1tMT05FQ0FSRVRdICsgJ1xcXFxzKyc7XG5yZVtDQVJFVFRSSU1dID0gbmV3IFJlZ0V4cChzcmNbQ0FSRVRUUklNXSwgJ2cnKTtcbnZhciBjYXJldFRyaW1SZXBsYWNlID0gJyQxXic7XG5cbnZhciBDQVJFVCA9IFIrKztcbnNyY1tDQVJFVF0gPSAnXicgKyBzcmNbTE9ORUNBUkVUXSArIHNyY1tYUkFOR0VQTEFJTl0gKyAnJCc7XG52YXIgQ0FSRVRMT09TRSA9IFIrKztcbnNyY1tDQVJFVExPT1NFXSA9ICdeJyArIHNyY1tMT05FQ0FSRVRdICsgc3JjW1hSQU5HRVBMQUlOTE9PU0VdICsgJyQnO1xuXG4vLyBBIHNpbXBsZSBndC9sdC9lcSB0aGluZywgb3IganVzdCBcIlwiIHRvIGluZGljYXRlIFwiYW55IHZlcnNpb25cIlxudmFyIENPTVBBUkFUT1JMT09TRSA9IFIrKztcbnNyY1tDT01QQVJBVE9STE9PU0VdID0gJ14nICsgc3JjW0dUTFRdICsgJ1xcXFxzKignICsgTE9PU0VQTEFJTiArICcpJHxeJCc7XG52YXIgQ09NUEFSQVRPUiA9IFIrKztcbnNyY1tDT01QQVJBVE9SXSA9ICdeJyArIHNyY1tHVExUXSArICdcXFxccyooJyArIEZVTExQTEFJTiArICcpJHxeJCc7XG5cblxuLy8gQW4gZXhwcmVzc2lvbiB0byBzdHJpcCBhbnkgd2hpdGVzcGFjZSBiZXR3ZWVuIHRoZSBndGx0IGFuZCB0aGUgdGhpbmdcbi8vIGl0IG1vZGlmaWVzLCBzbyB0aGF0IGA+IDEuMi4zYCA9PT4gYD4xLjIuM2BcbnZhciBDT01QQVJBVE9SVFJJTSA9IFIrKztcbnNyY1tDT01QQVJBVE9SVFJJTV0gPSAnKFxcXFxzKiknICsgc3JjW0dUTFRdICtcbiAgICAgICAgICAgICAgICAgICAgICAnXFxcXHMqKCcgKyBMT09TRVBMQUlOICsgJ3wnICsgc3JjW1hSQU5HRVBMQUlOXSArICcpJztcblxuLy8gdGhpcyBvbmUgaGFzIHRvIHVzZSB0aGUgL2cgZmxhZ1xucmVbQ09NUEFSQVRPUlRSSU1dID0gbmV3IFJlZ0V4cChzcmNbQ09NUEFSQVRPUlRSSU1dLCAnZycpO1xudmFyIGNvbXBhcmF0b3JUcmltUmVwbGFjZSA9ICckMSQyJDMnO1xuXG5cbi8vIFNvbWV0aGluZyBsaWtlIGAxLjIuMyAtIDEuMi40YFxuLy8gTm90ZSB0aGF0IHRoZXNlIGFsbCB1c2UgdGhlIGxvb3NlIGZvcm0sIGJlY2F1c2UgdGhleSdsbCBiZVxuLy8gY2hlY2tlZCBhZ2FpbnN0IGVpdGhlciB0aGUgc3RyaWN0IG9yIGxvb3NlIGNvbXBhcmF0b3IgZm9ybVxuLy8gbGF0ZXIuXG52YXIgSFlQSEVOUkFOR0UgPSBSKys7XG5zcmNbSFlQSEVOUkFOR0VdID0gJ15cXFxccyooJyArIHNyY1tYUkFOR0VQTEFJTl0gKyAnKScgK1xuICAgICAgICAgICAgICAgICAgICdcXFxccystXFxcXHMrJyArXG4gICAgICAgICAgICAgICAgICAgJygnICsgc3JjW1hSQU5HRVBMQUlOXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgJ1xcXFxzKiQnO1xuXG52YXIgSFlQSEVOUkFOR0VMT09TRSA9IFIrKztcbnNyY1tIWVBIRU5SQU5HRUxPT1NFXSA9ICdeXFxcXHMqKCcgKyBzcmNbWFJBTkdFUExBSU5MT09TRV0gKyAnKScgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJ1xcXFxzKy1cXFxccysnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcoJyArIHNyY1tYUkFOR0VQTEFJTkxPT1NFXSArICcpJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnXFxcXHMqJCc7XG5cbi8vIFN0YXIgcmFuZ2VzIGJhc2ljYWxseSBqdXN0IGFsbG93IGFueXRoaW5nIGF0IGFsbC5cbnZhciBTVEFSID0gUisrO1xuc3JjW1NUQVJdID0gJyg8fD4pPz0/XFxcXHMqXFxcXConO1xuXG4vLyBDb21waWxlIHRvIGFjdHVhbCByZWdleHAgb2JqZWN0cy5cbi8vIEFsbCBhcmUgZmxhZy1mcmVlLCB1bmxlc3MgdGhleSB3ZXJlIGNyZWF0ZWQgYWJvdmUgd2l0aCBhIGZsYWcuXG5mb3IgKHZhciBpID0gMDsgaSA8IFI7IGkrKykge1xuICBkZWJ1ZyhpLCBzcmNbaV0pO1xuICBpZiAoIXJlW2ldKVxuICAgIHJlW2ldID0gbmV3IFJlZ0V4cChzcmNbaV0pO1xufVxuXG5leHBvcnRzLnBhcnNlID0gcGFyc2U7XG5mdW5jdGlvbiBwYXJzZSh2ZXJzaW9uLCBsb29zZSkge1xuICBpZiAodmVyc2lvbiBpbnN0YW5jZW9mIFNlbVZlcilcbiAgICByZXR1cm4gdmVyc2lvbjtcblxuICBpZiAodHlwZW9mIHZlcnNpb24gIT09ICdzdHJpbmcnKVxuICAgIHJldHVybiBudWxsO1xuXG4gIGlmICh2ZXJzaW9uLmxlbmd0aCA+IE1BWF9MRU5HVEgpXG4gICAgcmV0dXJuIG51bGw7XG5cbiAgdmFyIHIgPSBsb29zZSA/IHJlW0xPT1NFXSA6IHJlW0ZVTExdO1xuICBpZiAoIXIudGVzdCh2ZXJzaW9uKSlcbiAgICByZXR1cm4gbnVsbDtcblxuICB0cnkge1xuICAgIHJldHVybiBuZXcgU2VtVmVyKHZlcnNpb24sIGxvb3NlKTtcbiAgfSBjYXRjaCAoZXIpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG5leHBvcnRzLnZhbGlkID0gdmFsaWQ7XG5mdW5jdGlvbiB2YWxpZCh2ZXJzaW9uLCBsb29zZSkge1xuICB2YXIgdiA9IHBhcnNlKHZlcnNpb24sIGxvb3NlKTtcbiAgcmV0dXJuIHYgPyB2LnZlcnNpb24gOiBudWxsO1xufVxuXG5cbmV4cG9ydHMuY2xlYW4gPSBjbGVhbjtcbmZ1bmN0aW9uIGNsZWFuKHZlcnNpb24sIGxvb3NlKSB7XG4gIHZhciBzID0gcGFyc2UodmVyc2lvbi50cmltKCkucmVwbGFjZSgvXls9dl0rLywgJycpLCBsb29zZSk7XG4gIHJldHVybiBzID8gcy52ZXJzaW9uIDogbnVsbDtcbn1cblxuZXhwb3J0cy5TZW1WZXIgPSBTZW1WZXI7XG5cbmZ1bmN0aW9uIFNlbVZlcih2ZXJzaW9uLCBsb29zZSkge1xuICBpZiAodmVyc2lvbiBpbnN0YW5jZW9mIFNlbVZlcikge1xuICAgIGlmICh2ZXJzaW9uLmxvb3NlID09PSBsb29zZSlcbiAgICAgIHJldHVybiB2ZXJzaW9uO1xuICAgIGVsc2VcbiAgICAgIHZlcnNpb24gPSB2ZXJzaW9uLnZlcnNpb247XG4gIH0gZWxzZSBpZiAodHlwZW9mIHZlcnNpb24gIT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBWZXJzaW9uOiAnICsgdmVyc2lvbik7XG4gIH1cblxuICBpZiAodmVyc2lvbi5sZW5ndGggPiBNQVhfTEVOR1RIKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3ZlcnNpb24gaXMgbG9uZ2VyIHRoYW4gJyArIE1BWF9MRU5HVEggKyAnIGNoYXJhY3RlcnMnKVxuXG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTZW1WZXIpKVxuICAgIHJldHVybiBuZXcgU2VtVmVyKHZlcnNpb24sIGxvb3NlKTtcblxuICBkZWJ1ZygnU2VtVmVyJywgdmVyc2lvbiwgbG9vc2UpO1xuICB0aGlzLmxvb3NlID0gbG9vc2U7XG4gIHZhciBtID0gdmVyc2lvbi50cmltKCkubWF0Y2gobG9vc2UgPyByZVtMT09TRV0gOiByZVtGVUxMXSk7XG5cbiAgaWYgKCFtKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgVmVyc2lvbjogJyArIHZlcnNpb24pO1xuXG4gIHRoaXMucmF3ID0gdmVyc2lvbjtcblxuICAvLyB0aGVzZSBhcmUgYWN0dWFsbHkgbnVtYmVyc1xuICB0aGlzLm1ham9yID0gK21bMV07XG4gIHRoaXMubWlub3IgPSArbVsyXTtcbiAgdGhpcy5wYXRjaCA9ICttWzNdO1xuXG4gIGlmICh0aGlzLm1ham9yID4gTUFYX1NBRkVfSU5URUdFUiB8fCB0aGlzLm1ham9yIDwgMClcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG1ham9yIHZlcnNpb24nKVxuXG4gIGlmICh0aGlzLm1pbm9yID4gTUFYX1NBRkVfSU5URUdFUiB8fCB0aGlzLm1pbm9yIDwgMClcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG1pbm9yIHZlcnNpb24nKVxuXG4gIGlmICh0aGlzLnBhdGNoID4gTUFYX1NBRkVfSU5URUdFUiB8fCB0aGlzLnBhdGNoIDwgMClcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIHBhdGNoIHZlcnNpb24nKVxuXG4gIC8vIG51bWJlcmlmeSBhbnkgcHJlcmVsZWFzZSBudW1lcmljIGlkc1xuICBpZiAoIW1bNF0pXG4gICAgdGhpcy5wcmVyZWxlYXNlID0gW107XG4gIGVsc2VcbiAgICB0aGlzLnByZXJlbGVhc2UgPSBtWzRdLnNwbGl0KCcuJykubWFwKGZ1bmN0aW9uKGlkKSB7XG4gICAgICBpZiAoL15bMC05XSskLy50ZXN0KGlkKSkge1xuICAgICAgICB2YXIgbnVtID0gK2lkO1xuICAgICAgICBpZiAobnVtID49IDAgJiYgbnVtIDwgTUFYX1NBRkVfSU5URUdFUilcbiAgICAgICAgICByZXR1cm4gbnVtO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGlkO1xuICAgIH0pO1xuXG4gIHRoaXMuYnVpbGQgPSBtWzVdID8gbVs1XS5zcGxpdCgnLicpIDogW107XG4gIHRoaXMuZm9ybWF0KCk7XG59XG5cblNlbVZlci5wcm90b3R5cGUuZm9ybWF0ID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMudmVyc2lvbiA9IHRoaXMubWFqb3IgKyAnLicgKyB0aGlzLm1pbm9yICsgJy4nICsgdGhpcy5wYXRjaDtcbiAgaWYgKHRoaXMucHJlcmVsZWFzZS5sZW5ndGgpXG4gICAgdGhpcy52ZXJzaW9uICs9ICctJyArIHRoaXMucHJlcmVsZWFzZS5qb2luKCcuJyk7XG4gIHJldHVybiB0aGlzLnZlcnNpb247XG59O1xuXG5TZW1WZXIucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLnZlcnNpb247XG59O1xuXG5TZW1WZXIucHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbihvdGhlcikge1xuICBkZWJ1ZygnU2VtVmVyLmNvbXBhcmUnLCB0aGlzLnZlcnNpb24sIHRoaXMubG9vc2UsIG90aGVyKTtcbiAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBTZW1WZXIpKVxuICAgIG90aGVyID0gbmV3IFNlbVZlcihvdGhlciwgdGhpcy5sb29zZSk7XG5cbiAgcmV0dXJuIHRoaXMuY29tcGFyZU1haW4ob3RoZXIpIHx8IHRoaXMuY29tcGFyZVByZShvdGhlcik7XG59O1xuXG5TZW1WZXIucHJvdG90eXBlLmNvbXBhcmVNYWluID0gZnVuY3Rpb24ob3RoZXIpIHtcbiAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBTZW1WZXIpKVxuICAgIG90aGVyID0gbmV3IFNlbVZlcihvdGhlciwgdGhpcy5sb29zZSk7XG5cbiAgcmV0dXJuIGNvbXBhcmVJZGVudGlmaWVycyh0aGlzLm1ham9yLCBvdGhlci5tYWpvcikgfHxcbiAgICAgICAgIGNvbXBhcmVJZGVudGlmaWVycyh0aGlzLm1pbm9yLCBvdGhlci5taW5vcikgfHxcbiAgICAgICAgIGNvbXBhcmVJZGVudGlmaWVycyh0aGlzLnBhdGNoLCBvdGhlci5wYXRjaCk7XG59O1xuXG5TZW1WZXIucHJvdG90eXBlLmNvbXBhcmVQcmUgPSBmdW5jdGlvbihvdGhlcikge1xuICBpZiAoIShvdGhlciBpbnN0YW5jZW9mIFNlbVZlcikpXG4gICAgb3RoZXIgPSBuZXcgU2VtVmVyKG90aGVyLCB0aGlzLmxvb3NlKTtcblxuICAvLyBOT1QgaGF2aW5nIGEgcHJlcmVsZWFzZSBpcyA+IGhhdmluZyBvbmVcbiAgaWYgKHRoaXMucHJlcmVsZWFzZS5sZW5ndGggJiYgIW90aGVyLnByZXJlbGVhc2UubGVuZ3RoKVxuICAgIHJldHVybiAtMTtcbiAgZWxzZSBpZiAoIXRoaXMucHJlcmVsZWFzZS5sZW5ndGggJiYgb3RoZXIucHJlcmVsZWFzZS5sZW5ndGgpXG4gICAgcmV0dXJuIDE7XG4gIGVsc2UgaWYgKCF0aGlzLnByZXJlbGVhc2UubGVuZ3RoICYmICFvdGhlci5wcmVyZWxlYXNlLmxlbmd0aClcbiAgICByZXR1cm4gMDtcblxuICB2YXIgaSA9IDA7XG4gIGRvIHtcbiAgICB2YXIgYSA9IHRoaXMucHJlcmVsZWFzZVtpXTtcbiAgICB2YXIgYiA9IG90aGVyLnByZXJlbGVhc2VbaV07XG4gICAgZGVidWcoJ3ByZXJlbGVhc2UgY29tcGFyZScsIGksIGEsIGIpO1xuICAgIGlmIChhID09PSB1bmRlZmluZWQgJiYgYiA9PT0gdW5kZWZpbmVkKVxuICAgICAgcmV0dXJuIDA7XG4gICAgZWxzZSBpZiAoYiA9PT0gdW5kZWZpbmVkKVxuICAgICAgcmV0dXJuIDE7XG4gICAgZWxzZSBpZiAoYSA9PT0gdW5kZWZpbmVkKVxuICAgICAgcmV0dXJuIC0xO1xuICAgIGVsc2UgaWYgKGEgPT09IGIpXG4gICAgICBjb250aW51ZTtcbiAgICBlbHNlXG4gICAgICByZXR1cm4gY29tcGFyZUlkZW50aWZpZXJzKGEsIGIpO1xuICB9IHdoaWxlICgrK2kpO1xufTtcblxuLy8gcHJlbWlub3Igd2lsbCBidW1wIHRoZSB2ZXJzaW9uIHVwIHRvIHRoZSBuZXh0IG1pbm9yIHJlbGVhc2UsIGFuZCBpbW1lZGlhdGVseVxuLy8gZG93biB0byBwcmUtcmVsZWFzZS4gcHJlbWFqb3IgYW5kIHByZXBhdGNoIHdvcmsgdGhlIHNhbWUgd2F5LlxuU2VtVmVyLnByb3RvdHlwZS5pbmMgPSBmdW5jdGlvbihyZWxlYXNlLCBpZGVudGlmaWVyKSB7XG4gIHN3aXRjaCAocmVsZWFzZSkge1xuICAgIGNhc2UgJ3ByZW1ham9yJzpcbiAgICAgIHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPSAwO1xuICAgICAgdGhpcy5wYXRjaCA9IDA7XG4gICAgICB0aGlzLm1pbm9yID0gMDtcbiAgICAgIHRoaXMubWFqb3IrKztcbiAgICAgIHRoaXMuaW5jKCdwcmUnLCBpZGVudGlmaWVyKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3ByZW1pbm9yJzpcbiAgICAgIHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPSAwO1xuICAgICAgdGhpcy5wYXRjaCA9IDA7XG4gICAgICB0aGlzLm1pbm9yKys7XG4gICAgICB0aGlzLmluYygncHJlJywgaWRlbnRpZmllcik7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdwcmVwYXRjaCc6XG4gICAgICAvLyBJZiB0aGlzIGlzIGFscmVhZHkgYSBwcmVyZWxlYXNlLCBpdCB3aWxsIGJ1bXAgdG8gdGhlIG5leHQgdmVyc2lvblxuICAgICAgLy8gZHJvcCBhbnkgcHJlcmVsZWFzZXMgdGhhdCBtaWdodCBhbHJlYWR5IGV4aXN0LCBzaW5jZSB0aGV5IGFyZSBub3RcbiAgICAgIC8vIHJlbGV2YW50IGF0IHRoaXMgcG9pbnQuXG4gICAgICB0aGlzLnByZXJlbGVhc2UubGVuZ3RoID0gMDtcbiAgICAgIHRoaXMuaW5jKCdwYXRjaCcsIGlkZW50aWZpZXIpO1xuICAgICAgdGhpcy5pbmMoJ3ByZScsIGlkZW50aWZpZXIpO1xuICAgICAgYnJlYWs7XG4gICAgLy8gSWYgdGhlIGlucHV0IGlzIGEgbm9uLXByZXJlbGVhc2UgdmVyc2lvbiwgdGhpcyBhY3RzIHRoZSBzYW1lIGFzXG4gICAgLy8gcHJlcGF0Y2guXG4gICAgY2FzZSAncHJlcmVsZWFzZSc6XG4gICAgICBpZiAodGhpcy5wcmVyZWxlYXNlLmxlbmd0aCA9PT0gMClcbiAgICAgICAgdGhpcy5pbmMoJ3BhdGNoJywgaWRlbnRpZmllcik7XG4gICAgICB0aGlzLmluYygncHJlJywgaWRlbnRpZmllcik7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ21ham9yJzpcbiAgICAgIC8vIElmIHRoaXMgaXMgYSBwcmUtbWFqb3IgdmVyc2lvbiwgYnVtcCB1cCB0byB0aGUgc2FtZSBtYWpvciB2ZXJzaW9uLlxuICAgICAgLy8gT3RoZXJ3aXNlIGluY3JlbWVudCBtYWpvci5cbiAgICAgIC8vIDEuMC4wLTUgYnVtcHMgdG8gMS4wLjBcbiAgICAgIC8vIDEuMS4wIGJ1bXBzIHRvIDIuMC4wXG4gICAgICBpZiAodGhpcy5taW5vciAhPT0gMCB8fCB0aGlzLnBhdGNoICE9PSAwIHx8IHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPT09IDApXG4gICAgICAgIHRoaXMubWFqb3IrKztcbiAgICAgIHRoaXMubWlub3IgPSAwO1xuICAgICAgdGhpcy5wYXRjaCA9IDA7XG4gICAgICB0aGlzLnByZXJlbGVhc2UgPSBbXTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ21pbm9yJzpcbiAgICAgIC8vIElmIHRoaXMgaXMgYSBwcmUtbWlub3IgdmVyc2lvbiwgYnVtcCB1cCB0byB0aGUgc2FtZSBtaW5vciB2ZXJzaW9uLlxuICAgICAgLy8gT3RoZXJ3aXNlIGluY3JlbWVudCBtaW5vci5cbiAgICAgIC8vIDEuMi4wLTUgYnVtcHMgdG8gMS4yLjBcbiAgICAgIC8vIDEuMi4xIGJ1bXBzIHRvIDEuMy4wXG4gICAgICBpZiAodGhpcy5wYXRjaCAhPT0gMCB8fCB0aGlzLnByZXJlbGVhc2UubGVuZ3RoID09PSAwKVxuICAgICAgICB0aGlzLm1pbm9yKys7XG4gICAgICB0aGlzLnBhdGNoID0gMDtcbiAgICAgIHRoaXMucHJlcmVsZWFzZSA9IFtdO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAncGF0Y2gnOlxuICAgICAgLy8gSWYgdGhpcyBpcyBub3QgYSBwcmUtcmVsZWFzZSB2ZXJzaW9uLCBpdCB3aWxsIGluY3JlbWVudCB0aGUgcGF0Y2guXG4gICAgICAvLyBJZiBpdCBpcyBhIHByZS1yZWxlYXNlIGl0IHdpbGwgYnVtcCB1cCB0byB0aGUgc2FtZSBwYXRjaCB2ZXJzaW9uLlxuICAgICAgLy8gMS4yLjAtNSBwYXRjaGVzIHRvIDEuMi4wXG4gICAgICAvLyAxLjIuMCBwYXRjaGVzIHRvIDEuMi4xXG4gICAgICBpZiAodGhpcy5wcmVyZWxlYXNlLmxlbmd0aCA9PT0gMClcbiAgICAgICAgdGhpcy5wYXRjaCsrO1xuICAgICAgdGhpcy5wcmVyZWxlYXNlID0gW107XG4gICAgICBicmVhaztcbiAgICAvLyBUaGlzIHByb2JhYmx5IHNob3VsZG4ndCBiZSB1c2VkIHB1YmxpY2x5LlxuICAgIC8vIDEuMC4wIFwicHJlXCIgd291bGQgYmVjb21lIDEuMC4wLTAgd2hpY2ggaXMgdGhlIHdyb25nIGRpcmVjdGlvbi5cbiAgICBjYXNlICdwcmUnOlxuICAgICAgaWYgKHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPT09IDApXG4gICAgICAgIHRoaXMucHJlcmVsZWFzZSA9IFswXTtcbiAgICAgIGVsc2Uge1xuICAgICAgICB2YXIgaSA9IHRoaXMucHJlcmVsZWFzZS5sZW5ndGg7XG4gICAgICAgIHdoaWxlICgtLWkgPj0gMCkge1xuICAgICAgICAgIGlmICh0eXBlb2YgdGhpcy5wcmVyZWxlYXNlW2ldID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgdGhpcy5wcmVyZWxlYXNlW2ldKys7XG4gICAgICAgICAgICBpID0gLTI7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChpID09PSAtMSkgLy8gZGlkbid0IGluY3JlbWVudCBhbnl0aGluZ1xuICAgICAgICAgIHRoaXMucHJlcmVsZWFzZS5wdXNoKDApO1xuICAgICAgfVxuICAgICAgaWYgKGlkZW50aWZpZXIpIHtcbiAgICAgICAgLy8gMS4yLjAtYmV0YS4xIGJ1bXBzIHRvIDEuMi4wLWJldGEuMixcbiAgICAgICAgLy8gMS4yLjAtYmV0YS5mb29ibHogb3IgMS4yLjAtYmV0YSBidW1wcyB0byAxLjIuMC1iZXRhLjBcbiAgICAgICAgaWYgKHRoaXMucHJlcmVsZWFzZVswXSA9PT0gaWRlbnRpZmllcikge1xuICAgICAgICAgIGlmIChpc05hTih0aGlzLnByZXJlbGVhc2VbMV0pKVxuICAgICAgICAgICAgdGhpcy5wcmVyZWxlYXNlID0gW2lkZW50aWZpZXIsIDBdO1xuICAgICAgICB9IGVsc2VcbiAgICAgICAgICB0aGlzLnByZXJlbGVhc2UgPSBbaWRlbnRpZmllciwgMF07XG4gICAgICB9XG4gICAgICBicmVhaztcblxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgaW5jcmVtZW50IGFyZ3VtZW50OiAnICsgcmVsZWFzZSk7XG4gIH1cbiAgdGhpcy5mb3JtYXQoKTtcbiAgdGhpcy5yYXcgPSB0aGlzLnZlcnNpb247XG4gIHJldHVybiB0aGlzO1xufTtcblxuZXhwb3J0cy5pbmMgPSBpbmM7XG5mdW5jdGlvbiBpbmModmVyc2lvbiwgcmVsZWFzZSwgbG9vc2UsIGlkZW50aWZpZXIpIHtcbiAgaWYgKHR5cGVvZihsb29zZSkgPT09ICdzdHJpbmcnKSB7XG4gICAgaWRlbnRpZmllciA9IGxvb3NlO1xuICAgIGxvb3NlID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgdHJ5IHtcbiAgICByZXR1cm4gbmV3IFNlbVZlcih2ZXJzaW9uLCBsb29zZSkuaW5jKHJlbGVhc2UsIGlkZW50aWZpZXIpLnZlcnNpb247XG4gIH0gY2F0Y2ggKGVyKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuZXhwb3J0cy5kaWZmID0gZGlmZjtcbmZ1bmN0aW9uIGRpZmYodmVyc2lvbjEsIHZlcnNpb24yKSB7XG4gIGlmIChlcSh2ZXJzaW9uMSwgdmVyc2lvbjIpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH0gZWxzZSB7XG4gICAgdmFyIHYxID0gcGFyc2UodmVyc2lvbjEpO1xuICAgIHZhciB2MiA9IHBhcnNlKHZlcnNpb24yKTtcbiAgICBpZiAodjEucHJlcmVsZWFzZS5sZW5ndGggfHwgdjIucHJlcmVsZWFzZS5sZW5ndGgpIHtcbiAgICAgIGZvciAodmFyIGtleSBpbiB2MSkge1xuICAgICAgICBpZiAoa2V5ID09PSAnbWFqb3InIHx8IGtleSA9PT0gJ21pbm9yJyB8fCBrZXkgPT09ICdwYXRjaCcpIHtcbiAgICAgICAgICBpZiAodjFba2V5XSAhPT0gdjJba2V5XSkge1xuICAgICAgICAgICAgcmV0dXJuICdwcmUnK2tleTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiAncHJlcmVsZWFzZSc7XG4gICAgfVxuICAgIGZvciAodmFyIGtleSBpbiB2MSkge1xuICAgICAgaWYgKGtleSA9PT0gJ21ham9yJyB8fCBrZXkgPT09ICdtaW5vcicgfHwga2V5ID09PSAncGF0Y2gnKSB7XG4gICAgICAgIGlmICh2MVtrZXldICE9PSB2MltrZXldKSB7XG4gICAgICAgICAgcmV0dXJuIGtleTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnRzLmNvbXBhcmVJZGVudGlmaWVycyA9IGNvbXBhcmVJZGVudGlmaWVycztcblxudmFyIG51bWVyaWMgPSAvXlswLTldKyQvO1xuZnVuY3Rpb24gY29tcGFyZUlkZW50aWZpZXJzKGEsIGIpIHtcbiAgdmFyIGFudW0gPSBudW1lcmljLnRlc3QoYSk7XG4gIHZhciBibnVtID0gbnVtZXJpYy50ZXN0KGIpO1xuXG4gIGlmIChhbnVtICYmIGJudW0pIHtcbiAgICBhID0gK2E7XG4gICAgYiA9ICtiO1xuICB9XG5cbiAgcmV0dXJuIChhbnVtICYmICFibnVtKSA/IC0xIDpcbiAgICAgICAgIChibnVtICYmICFhbnVtKSA/IDEgOlxuICAgICAgICAgYSA8IGIgPyAtMSA6XG4gICAgICAgICBhID4gYiA/IDEgOlxuICAgICAgICAgMDtcbn1cblxuZXhwb3J0cy5yY29tcGFyZUlkZW50aWZpZXJzID0gcmNvbXBhcmVJZGVudGlmaWVycztcbmZ1bmN0aW9uIHJjb21wYXJlSWRlbnRpZmllcnMoYSwgYikge1xuICByZXR1cm4gY29tcGFyZUlkZW50aWZpZXJzKGIsIGEpO1xufVxuXG5leHBvcnRzLm1ham9yID0gbWFqb3I7XG5mdW5jdGlvbiBtYWpvcihhLCBsb29zZSkge1xuICByZXR1cm4gbmV3IFNlbVZlcihhLCBsb29zZSkubWFqb3I7XG59XG5cbmV4cG9ydHMubWlub3IgPSBtaW5vcjtcbmZ1bmN0aW9uIG1pbm9yKGEsIGxvb3NlKSB7XG4gIHJldHVybiBuZXcgU2VtVmVyKGEsIGxvb3NlKS5taW5vcjtcbn1cblxuZXhwb3J0cy5wYXRjaCA9IHBhdGNoO1xuZnVuY3Rpb24gcGF0Y2goYSwgbG9vc2UpIHtcbiAgcmV0dXJuIG5ldyBTZW1WZXIoYSwgbG9vc2UpLnBhdGNoO1xufVxuXG5leHBvcnRzLmNvbXBhcmUgPSBjb21wYXJlO1xuZnVuY3Rpb24gY29tcGFyZShhLCBiLCBsb29zZSkge1xuICByZXR1cm4gbmV3IFNlbVZlcihhLCBsb29zZSkuY29tcGFyZShuZXcgU2VtVmVyKGIsIGxvb3NlKSk7XG59XG5cbmV4cG9ydHMuY29tcGFyZUxvb3NlID0gY29tcGFyZUxvb3NlO1xuZnVuY3Rpb24gY29tcGFyZUxvb3NlKGEsIGIpIHtcbiAgcmV0dXJuIGNvbXBhcmUoYSwgYiwgdHJ1ZSk7XG59XG5cbmV4cG9ydHMucmNvbXBhcmUgPSByY29tcGFyZTtcbmZ1bmN0aW9uIHJjb21wYXJlKGEsIGIsIGxvb3NlKSB7XG4gIHJldHVybiBjb21wYXJlKGIsIGEsIGxvb3NlKTtcbn1cblxuZXhwb3J0cy5zb3J0ID0gc29ydDtcbmZ1bmN0aW9uIHNvcnQobGlzdCwgbG9vc2UpIHtcbiAgcmV0dXJuIGxpc3Quc29ydChmdW5jdGlvbihhLCBiKSB7XG4gICAgcmV0dXJuIGV4cG9ydHMuY29tcGFyZShhLCBiLCBsb29zZSk7XG4gIH0pO1xufVxuXG5leHBvcnRzLnJzb3J0ID0gcnNvcnQ7XG5mdW5jdGlvbiByc29ydChsaXN0LCBsb29zZSkge1xuICByZXR1cm4gbGlzdC5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcbiAgICByZXR1cm4gZXhwb3J0cy5yY29tcGFyZShhLCBiLCBsb29zZSk7XG4gIH0pO1xufVxuXG5leHBvcnRzLmd0ID0gZ3Q7XG5mdW5jdGlvbiBndChhLCBiLCBsb29zZSkge1xuICByZXR1cm4gY29tcGFyZShhLCBiLCBsb29zZSkgPiAwO1xufVxuXG5leHBvcnRzLmx0ID0gbHQ7XG5mdW5jdGlvbiBsdChhLCBiLCBsb29zZSkge1xuICByZXR1cm4gY29tcGFyZShhLCBiLCBsb29zZSkgPCAwO1xufVxuXG5leHBvcnRzLmVxID0gZXE7XG5mdW5jdGlvbiBlcShhLCBiLCBsb29zZSkge1xuICByZXR1cm4gY29tcGFyZShhLCBiLCBsb29zZSkgPT09IDA7XG59XG5cbmV4cG9ydHMubmVxID0gbmVxO1xuZnVuY3Rpb24gbmVxKGEsIGIsIGxvb3NlKSB7XG4gIHJldHVybiBjb21wYXJlKGEsIGIsIGxvb3NlKSAhPT0gMDtcbn1cblxuZXhwb3J0cy5ndGUgPSBndGU7XG5mdW5jdGlvbiBndGUoYSwgYiwgbG9vc2UpIHtcbiAgcmV0dXJuIGNvbXBhcmUoYSwgYiwgbG9vc2UpID49IDA7XG59XG5cbmV4cG9ydHMubHRlID0gbHRlO1xuZnVuY3Rpb24gbHRlKGEsIGIsIGxvb3NlKSB7XG4gIHJldHVybiBjb21wYXJlKGEsIGIsIGxvb3NlKSA8PSAwO1xufVxuXG5leHBvcnRzLmNtcCA9IGNtcDtcbmZ1bmN0aW9uIGNtcChhLCBvcCwgYiwgbG9vc2UpIHtcbiAgdmFyIHJldDtcbiAgc3dpdGNoIChvcCkge1xuICAgIGNhc2UgJz09PSc6XG4gICAgICBpZiAodHlwZW9mIGEgPT09ICdvYmplY3QnKSBhID0gYS52ZXJzaW9uO1xuICAgICAgaWYgKHR5cGVvZiBiID09PSAnb2JqZWN0JykgYiA9IGIudmVyc2lvbjtcbiAgICAgIHJldCA9IGEgPT09IGI7XG4gICAgICBicmVhaztcbiAgICBjYXNlICchPT0nOlxuICAgICAgaWYgKHR5cGVvZiBhID09PSAnb2JqZWN0JykgYSA9IGEudmVyc2lvbjtcbiAgICAgIGlmICh0eXBlb2YgYiA9PT0gJ29iamVjdCcpIGIgPSBiLnZlcnNpb247XG4gICAgICByZXQgPSBhICE9PSBiO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnJzogY2FzZSAnPSc6IGNhc2UgJz09JzogcmV0ID0gZXEoYSwgYiwgbG9vc2UpOyBicmVhaztcbiAgICBjYXNlICchPSc6IHJldCA9IG5lcShhLCBiLCBsb29zZSk7IGJyZWFrO1xuICAgIGNhc2UgJz4nOiByZXQgPSBndChhLCBiLCBsb29zZSk7IGJyZWFrO1xuICAgIGNhc2UgJz49JzogcmV0ID0gZ3RlKGEsIGIsIGxvb3NlKTsgYnJlYWs7XG4gICAgY2FzZSAnPCc6IHJldCA9IGx0KGEsIGIsIGxvb3NlKTsgYnJlYWs7XG4gICAgY2FzZSAnPD0nOiByZXQgPSBsdGUoYSwgYiwgbG9vc2UpOyBicmVhaztcbiAgICBkZWZhdWx0OiB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG9wZXJhdG9yOiAnICsgb3ApO1xuICB9XG4gIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydHMuQ29tcGFyYXRvciA9IENvbXBhcmF0b3I7XG5mdW5jdGlvbiBDb21wYXJhdG9yKGNvbXAsIGxvb3NlKSB7XG4gIGlmIChjb21wIGluc3RhbmNlb2YgQ29tcGFyYXRvcikge1xuICAgIGlmIChjb21wLmxvb3NlID09PSBsb29zZSlcbiAgICAgIHJldHVybiBjb21wO1xuICAgIGVsc2VcbiAgICAgIGNvbXAgPSBjb21wLnZhbHVlO1xuICB9XG5cbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIENvbXBhcmF0b3IpKVxuICAgIHJldHVybiBuZXcgQ29tcGFyYXRvcihjb21wLCBsb29zZSk7XG5cbiAgZGVidWcoJ2NvbXBhcmF0b3InLCBjb21wLCBsb29zZSk7XG4gIHRoaXMubG9vc2UgPSBsb29zZTtcbiAgdGhpcy5wYXJzZShjb21wKTtcblxuICBpZiAodGhpcy5zZW12ZXIgPT09IEFOWSlcbiAgICB0aGlzLnZhbHVlID0gJyc7XG4gIGVsc2VcbiAgICB0aGlzLnZhbHVlID0gdGhpcy5vcGVyYXRvciArIHRoaXMuc2VtdmVyLnZlcnNpb247XG5cbiAgZGVidWcoJ2NvbXAnLCB0aGlzKTtcbn1cblxudmFyIEFOWSA9IHt9O1xuQ29tcGFyYXRvci5wcm90b3R5cGUucGFyc2UgPSBmdW5jdGlvbihjb21wKSB7XG4gIHZhciByID0gdGhpcy5sb29zZSA/IHJlW0NPTVBBUkFUT1JMT09TRV0gOiByZVtDT01QQVJBVE9SXTtcbiAgdmFyIG0gPSBjb21wLm1hdGNoKHIpO1xuXG4gIGlmICghbSlcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIGNvbXBhcmF0b3I6ICcgKyBjb21wKTtcblxuICB0aGlzLm9wZXJhdG9yID0gbVsxXTtcbiAgaWYgKHRoaXMub3BlcmF0b3IgPT09ICc9JylcbiAgICB0aGlzLm9wZXJhdG9yID0gJyc7XG5cbiAgLy8gaWYgaXQgbGl0ZXJhbGx5IGlzIGp1c3QgJz4nIG9yICcnIHRoZW4gYWxsb3cgYW55dGhpbmcuXG4gIGlmICghbVsyXSlcbiAgICB0aGlzLnNlbXZlciA9IEFOWTtcbiAgZWxzZVxuICAgIHRoaXMuc2VtdmVyID0gbmV3IFNlbVZlcihtWzJdLCB0aGlzLmxvb3NlKTtcbn07XG5cbkNvbXBhcmF0b3IucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLnZhbHVlO1xufTtcblxuQ29tcGFyYXRvci5wcm90b3R5cGUudGVzdCA9IGZ1bmN0aW9uKHZlcnNpb24pIHtcbiAgZGVidWcoJ0NvbXBhcmF0b3IudGVzdCcsIHZlcnNpb24sIHRoaXMubG9vc2UpO1xuXG4gIGlmICh0aGlzLnNlbXZlciA9PT0gQU5ZKVxuICAgIHJldHVybiB0cnVlO1xuXG4gIGlmICh0eXBlb2YgdmVyc2lvbiA9PT0gJ3N0cmluZycpXG4gICAgdmVyc2lvbiA9IG5ldyBTZW1WZXIodmVyc2lvbiwgdGhpcy5sb29zZSk7XG5cbiAgcmV0dXJuIGNtcCh2ZXJzaW9uLCB0aGlzLm9wZXJhdG9yLCB0aGlzLnNlbXZlciwgdGhpcy5sb29zZSk7XG59O1xuXG5Db21wYXJhdG9yLnByb3RvdHlwZS5pbnRlcnNlY3RzID0gZnVuY3Rpb24oY29tcCwgbG9vc2UpIHtcbiAgaWYgKCEoY29tcCBpbnN0YW5jZW9mIENvbXBhcmF0b3IpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignYSBDb21wYXJhdG9yIGlzIHJlcXVpcmVkJyk7XG4gIH1cblxuICB2YXIgcmFuZ2VUbXA7XG5cbiAgaWYgKHRoaXMub3BlcmF0b3IgPT09ICcnKSB7XG4gICAgcmFuZ2VUbXAgPSBuZXcgUmFuZ2UoY29tcC52YWx1ZSwgbG9vc2UpO1xuICAgIHJldHVybiBzYXRpc2ZpZXModGhpcy52YWx1ZSwgcmFuZ2VUbXAsIGxvb3NlKTtcbiAgfSBlbHNlIGlmIChjb21wLm9wZXJhdG9yID09PSAnJykge1xuICAgIHJhbmdlVG1wID0gbmV3IFJhbmdlKHRoaXMudmFsdWUsIGxvb3NlKTtcbiAgICByZXR1cm4gc2F0aXNmaWVzKGNvbXAuc2VtdmVyLCByYW5nZVRtcCwgbG9vc2UpO1xuICB9XG5cbiAgdmFyIHNhbWVEaXJlY3Rpb25JbmNyZWFzaW5nID1cbiAgICAodGhpcy5vcGVyYXRvciA9PT0gJz49JyB8fCB0aGlzLm9wZXJhdG9yID09PSAnPicpICYmXG4gICAgKGNvbXAub3BlcmF0b3IgPT09ICc+PScgfHwgY29tcC5vcGVyYXRvciA9PT0gJz4nKTtcbiAgdmFyIHNhbWVEaXJlY3Rpb25EZWNyZWFzaW5nID1cbiAgICAodGhpcy5vcGVyYXRvciA9PT0gJzw9JyB8fCB0aGlzLm9wZXJhdG9yID09PSAnPCcpICYmXG4gICAgKGNvbXAub3BlcmF0b3IgPT09ICc8PScgfHwgY29tcC5vcGVyYXRvciA9PT0gJzwnKTtcbiAgdmFyIHNhbWVTZW1WZXIgPSB0aGlzLnNlbXZlci52ZXJzaW9uID09PSBjb21wLnNlbXZlci52ZXJzaW9uO1xuICB2YXIgZGlmZmVyZW50RGlyZWN0aW9uc0luY2x1c2l2ZSA9XG4gICAgKHRoaXMub3BlcmF0b3IgPT09ICc+PScgfHwgdGhpcy5vcGVyYXRvciA9PT0gJzw9JykgJiZcbiAgICAoY29tcC5vcGVyYXRvciA9PT0gJz49JyB8fCBjb21wLm9wZXJhdG9yID09PSAnPD0nKTtcbiAgdmFyIG9wcG9zaXRlRGlyZWN0aW9uc0xlc3NUaGFuID1cbiAgICBjbXAodGhpcy5zZW12ZXIsICc8JywgY29tcC5zZW12ZXIsIGxvb3NlKSAmJlxuICAgICgodGhpcy5vcGVyYXRvciA9PT0gJz49JyB8fCB0aGlzLm9wZXJhdG9yID09PSAnPicpICYmXG4gICAgKGNvbXAub3BlcmF0b3IgPT09ICc8PScgfHwgY29tcC5vcGVyYXRvciA9PT0gJzwnKSk7XG4gIHZhciBvcHBvc2l0ZURpcmVjdGlvbnNHcmVhdGVyVGhhbiA9XG4gICAgY21wKHRoaXMuc2VtdmVyLCAnPicsIGNvbXAuc2VtdmVyLCBsb29zZSkgJiZcbiAgICAoKHRoaXMub3BlcmF0b3IgPT09ICc8PScgfHwgdGhpcy5vcGVyYXRvciA9PT0gJzwnKSAmJlxuICAgIChjb21wLm9wZXJhdG9yID09PSAnPj0nIHx8IGNvbXAub3BlcmF0b3IgPT09ICc+JykpO1xuXG4gIHJldHVybiBzYW1lRGlyZWN0aW9uSW5jcmVhc2luZyB8fCBzYW1lRGlyZWN0aW9uRGVjcmVhc2luZyB8fFxuICAgIChzYW1lU2VtVmVyICYmIGRpZmZlcmVudERpcmVjdGlvbnNJbmNsdXNpdmUpIHx8XG4gICAgb3Bwb3NpdGVEaXJlY3Rpb25zTGVzc1RoYW4gfHwgb3Bwb3NpdGVEaXJlY3Rpb25zR3JlYXRlclRoYW47XG59O1xuXG5cbmV4cG9ydHMuUmFuZ2UgPSBSYW5nZTtcbmZ1bmN0aW9uIFJhbmdlKHJhbmdlLCBsb29zZSkge1xuICBpZiAocmFuZ2UgaW5zdGFuY2VvZiBSYW5nZSkge1xuICAgIGlmIChyYW5nZS5sb29zZSA9PT0gbG9vc2UpIHtcbiAgICAgIHJldHVybiByYW5nZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG5ldyBSYW5nZShyYW5nZS5yYXcsIGxvb3NlKTtcbiAgICB9XG4gIH1cblxuICBpZiAocmFuZ2UgaW5zdGFuY2VvZiBDb21wYXJhdG9yKSB7XG4gICAgcmV0dXJuIG5ldyBSYW5nZShyYW5nZS52YWx1ZSwgbG9vc2UpO1xuICB9XG5cbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFJhbmdlKSlcbiAgICByZXR1cm4gbmV3IFJhbmdlKHJhbmdlLCBsb29zZSk7XG5cbiAgdGhpcy5sb29zZSA9IGxvb3NlO1xuXG4gIC8vIEZpcnN0LCBzcGxpdCBiYXNlZCBvbiBib29sZWFuIG9yIHx8XG4gIHRoaXMucmF3ID0gcmFuZ2U7XG4gIHRoaXMuc2V0ID0gcmFuZ2Uuc3BsaXQoL1xccypcXHxcXHxcXHMqLykubWFwKGZ1bmN0aW9uKHJhbmdlKSB7XG4gICAgcmV0dXJuIHRoaXMucGFyc2VSYW5nZShyYW5nZS50cmltKCkpO1xuICB9LCB0aGlzKS5maWx0ZXIoZnVuY3Rpb24oYykge1xuICAgIC8vIHRocm93IG91dCBhbnkgdGhhdCBhcmUgbm90IHJlbGV2YW50IGZvciB3aGF0ZXZlciByZWFzb25cbiAgICByZXR1cm4gYy5sZW5ndGg7XG4gIH0pO1xuXG4gIGlmICghdGhpcy5zZXQubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBTZW1WZXIgUmFuZ2U6ICcgKyByYW5nZSk7XG4gIH1cblxuICB0aGlzLmZvcm1hdCgpO1xufVxuXG5SYW5nZS5wcm90b3R5cGUuZm9ybWF0ID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMucmFuZ2UgPSB0aGlzLnNldC5tYXAoZnVuY3Rpb24oY29tcHMpIHtcbiAgICByZXR1cm4gY29tcHMuam9pbignICcpLnRyaW0oKTtcbiAgfSkuam9pbignfHwnKS50cmltKCk7XG4gIHJldHVybiB0aGlzLnJhbmdlO1xufTtcblxuUmFuZ2UucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLnJhbmdlO1xufTtcblxuUmFuZ2UucHJvdG90eXBlLnBhcnNlUmFuZ2UgPSBmdW5jdGlvbihyYW5nZSkge1xuICB2YXIgbG9vc2UgPSB0aGlzLmxvb3NlO1xuICByYW5nZSA9IHJhbmdlLnRyaW0oKTtcbiAgZGVidWcoJ3JhbmdlJywgcmFuZ2UsIGxvb3NlKTtcbiAgLy8gYDEuMi4zIC0gMS4yLjRgID0+IGA+PTEuMi4zIDw9MS4yLjRgXG4gIHZhciBociA9IGxvb3NlID8gcmVbSFlQSEVOUkFOR0VMT09TRV0gOiByZVtIWVBIRU5SQU5HRV07XG4gIHJhbmdlID0gcmFuZ2UucmVwbGFjZShociwgaHlwaGVuUmVwbGFjZSk7XG4gIGRlYnVnKCdoeXBoZW4gcmVwbGFjZScsIHJhbmdlKTtcbiAgLy8gYD4gMS4yLjMgPCAxLjIuNWAgPT4gYD4xLjIuMyA8MS4yLjVgXG4gIHJhbmdlID0gcmFuZ2UucmVwbGFjZShyZVtDT01QQVJBVE9SVFJJTV0sIGNvbXBhcmF0b3JUcmltUmVwbGFjZSk7XG4gIGRlYnVnKCdjb21wYXJhdG9yIHRyaW0nLCByYW5nZSwgcmVbQ09NUEFSQVRPUlRSSU1dKTtcblxuICAvLyBgfiAxLjIuM2AgPT4gYH4xLjIuM2BcbiAgcmFuZ2UgPSByYW5nZS5yZXBsYWNlKHJlW1RJTERFVFJJTV0sIHRpbGRlVHJpbVJlcGxhY2UpO1xuXG4gIC8vIGBeIDEuMi4zYCA9PiBgXjEuMi4zYFxuICByYW5nZSA9IHJhbmdlLnJlcGxhY2UocmVbQ0FSRVRUUklNXSwgY2FyZXRUcmltUmVwbGFjZSk7XG5cbiAgLy8gbm9ybWFsaXplIHNwYWNlc1xuICByYW5nZSA9IHJhbmdlLnNwbGl0KC9cXHMrLykuam9pbignICcpO1xuXG4gIC8vIEF0IHRoaXMgcG9pbnQsIHRoZSByYW5nZSBpcyBjb21wbGV0ZWx5IHRyaW1tZWQgYW5kXG4gIC8vIHJlYWR5IHRvIGJlIHNwbGl0IGludG8gY29tcGFyYXRvcnMuXG5cbiAgdmFyIGNvbXBSZSA9IGxvb3NlID8gcmVbQ09NUEFSQVRPUkxPT1NFXSA6IHJlW0NPTVBBUkFUT1JdO1xuICB2YXIgc2V0ID0gcmFuZ2Uuc3BsaXQoJyAnKS5tYXAoZnVuY3Rpb24oY29tcCkge1xuICAgIHJldHVybiBwYXJzZUNvbXBhcmF0b3IoY29tcCwgbG9vc2UpO1xuICB9KS5qb2luKCcgJykuc3BsaXQoL1xccysvKTtcbiAgaWYgKHRoaXMubG9vc2UpIHtcbiAgICAvLyBpbiBsb29zZSBtb2RlLCB0aHJvdyBvdXQgYW55IHRoYXQgYXJlIG5vdCB2YWxpZCBjb21wYXJhdG9yc1xuICAgIHNldCA9IHNldC5maWx0ZXIoZnVuY3Rpb24oY29tcCkge1xuICAgICAgcmV0dXJuICEhY29tcC5tYXRjaChjb21wUmUpO1xuICAgIH0pO1xuICB9XG4gIHNldCA9IHNldC5tYXAoZnVuY3Rpb24oY29tcCkge1xuICAgIHJldHVybiBuZXcgQ29tcGFyYXRvcihjb21wLCBsb29zZSk7XG4gIH0pO1xuXG4gIHJldHVybiBzZXQ7XG59O1xuXG5SYW5nZS5wcm90b3R5cGUuaW50ZXJzZWN0cyA9IGZ1bmN0aW9uKHJhbmdlLCBsb29zZSkge1xuICBpZiAoIShyYW5nZSBpbnN0YW5jZW9mIFJhbmdlKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2EgUmFuZ2UgaXMgcmVxdWlyZWQnKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLnNldC5zb21lKGZ1bmN0aW9uKHRoaXNDb21wYXJhdG9ycykge1xuICAgIHJldHVybiB0aGlzQ29tcGFyYXRvcnMuZXZlcnkoZnVuY3Rpb24odGhpc0NvbXBhcmF0b3IpIHtcbiAgICAgIHJldHVybiByYW5nZS5zZXQuc29tZShmdW5jdGlvbihyYW5nZUNvbXBhcmF0b3JzKSB7XG4gICAgICAgIHJldHVybiByYW5nZUNvbXBhcmF0b3JzLmV2ZXJ5KGZ1bmN0aW9uKHJhbmdlQ29tcGFyYXRvcikge1xuICAgICAgICAgIHJldHVybiB0aGlzQ29tcGFyYXRvci5pbnRlcnNlY3RzKHJhbmdlQ29tcGFyYXRvciwgbG9vc2UpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbn07XG5cbi8vIE1vc3RseSBqdXN0IGZvciB0ZXN0aW5nIGFuZCBsZWdhY3kgQVBJIHJlYXNvbnNcbmV4cG9ydHMudG9Db21wYXJhdG9ycyA9IHRvQ29tcGFyYXRvcnM7XG5mdW5jdGlvbiB0b0NvbXBhcmF0b3JzKHJhbmdlLCBsb29zZSkge1xuICByZXR1cm4gbmV3IFJhbmdlKHJhbmdlLCBsb29zZSkuc2V0Lm1hcChmdW5jdGlvbihjb21wKSB7XG4gICAgcmV0dXJuIGNvbXAubWFwKGZ1bmN0aW9uKGMpIHtcbiAgICAgIHJldHVybiBjLnZhbHVlO1xuICAgIH0pLmpvaW4oJyAnKS50cmltKCkuc3BsaXQoJyAnKTtcbiAgfSk7XG59XG5cbi8vIGNvbXByaXNlZCBvZiB4cmFuZ2VzLCB0aWxkZXMsIHN0YXJzLCBhbmQgZ3RsdCdzIGF0IHRoaXMgcG9pbnQuXG4vLyBhbHJlYWR5IHJlcGxhY2VkIHRoZSBoeXBoZW4gcmFuZ2VzXG4vLyB0dXJuIGludG8gYSBzZXQgb2YgSlVTVCBjb21wYXJhdG9ycy5cbmZ1bmN0aW9uIHBhcnNlQ29tcGFyYXRvcihjb21wLCBsb29zZSkge1xuICBkZWJ1ZygnY29tcCcsIGNvbXApO1xuICBjb21wID0gcmVwbGFjZUNhcmV0cyhjb21wLCBsb29zZSk7XG4gIGRlYnVnKCdjYXJldCcsIGNvbXApO1xuICBjb21wID0gcmVwbGFjZVRpbGRlcyhjb21wLCBsb29zZSk7XG4gIGRlYnVnKCd0aWxkZXMnLCBjb21wKTtcbiAgY29tcCA9IHJlcGxhY2VYUmFuZ2VzKGNvbXAsIGxvb3NlKTtcbiAgZGVidWcoJ3hyYW5nZScsIGNvbXApO1xuICBjb21wID0gcmVwbGFjZVN0YXJzKGNvbXAsIGxvb3NlKTtcbiAgZGVidWcoJ3N0YXJzJywgY29tcCk7XG4gIHJldHVybiBjb21wO1xufVxuXG5mdW5jdGlvbiBpc1goaWQpIHtcbiAgcmV0dXJuICFpZCB8fCBpZC50b0xvd2VyQ2FzZSgpID09PSAneCcgfHwgaWQgPT09ICcqJztcbn1cblxuLy8gfiwgfj4gLS0+ICogKGFueSwga2luZGEgc2lsbHkpXG4vLyB+MiwgfjIueCwgfjIueC54LCB+PjIsIH4+Mi54IH4+Mi54LnggLS0+ID49Mi4wLjAgPDMuMC4wXG4vLyB+Mi4wLCB+Mi4wLngsIH4+Mi4wLCB+PjIuMC54IC0tPiA+PTIuMC4wIDwyLjEuMFxuLy8gfjEuMiwgfjEuMi54LCB+PjEuMiwgfj4xLjIueCAtLT4gPj0xLjIuMCA8MS4zLjBcbi8vIH4xLjIuMywgfj4xLjIuMyAtLT4gPj0xLjIuMyA8MS4zLjBcbi8vIH4xLjIuMCwgfj4xLjIuMCAtLT4gPj0xLjIuMCA8MS4zLjBcbmZ1bmN0aW9uIHJlcGxhY2VUaWxkZXMoY29tcCwgbG9vc2UpIHtcbiAgcmV0dXJuIGNvbXAudHJpbSgpLnNwbGl0KC9cXHMrLykubWFwKGZ1bmN0aW9uKGNvbXApIHtcbiAgICByZXR1cm4gcmVwbGFjZVRpbGRlKGNvbXAsIGxvb3NlKTtcbiAgfSkuam9pbignICcpO1xufVxuXG5mdW5jdGlvbiByZXBsYWNlVGlsZGUoY29tcCwgbG9vc2UpIHtcbiAgdmFyIHIgPSBsb29zZSA/IHJlW1RJTERFTE9PU0VdIDogcmVbVElMREVdO1xuICByZXR1cm4gY29tcC5yZXBsYWNlKHIsIGZ1bmN0aW9uKF8sIE0sIG0sIHAsIHByKSB7XG4gICAgZGVidWcoJ3RpbGRlJywgY29tcCwgXywgTSwgbSwgcCwgcHIpO1xuICAgIHZhciByZXQ7XG5cbiAgICBpZiAoaXNYKE0pKVxuICAgICAgcmV0ID0gJyc7XG4gICAgZWxzZSBpZiAoaXNYKG0pKVxuICAgICAgcmV0ID0gJz49JyArIE0gKyAnLjAuMCA8JyArICgrTSArIDEpICsgJy4wLjAnO1xuICAgIGVsc2UgaWYgKGlzWChwKSlcbiAgICAgIC8vIH4xLjIgPT0gPj0xLjIuMCA8MS4zLjBcbiAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuMCA8JyArIE0gKyAnLicgKyAoK20gKyAxKSArICcuMCc7XG4gICAgZWxzZSBpZiAocHIpIHtcbiAgICAgIGRlYnVnKCdyZXBsYWNlVGlsZGUgcHInLCBwcik7XG4gICAgICBpZiAocHIuY2hhckF0KDApICE9PSAnLScpXG4gICAgICAgIHByID0gJy0nICsgcHI7XG4gICAgICByZXQgPSAnPj0nICsgTSArICcuJyArIG0gKyAnLicgKyBwICsgcHIgK1xuICAgICAgICAgICAgJyA8JyArIE0gKyAnLicgKyAoK20gKyAxKSArICcuMCc7XG4gICAgfSBlbHNlXG4gICAgICAvLyB+MS4yLjMgPT0gPj0xLjIuMyA8MS4zLjBcbiAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuJyArIHAgK1xuICAgICAgICAgICAgJyA8JyArIE0gKyAnLicgKyAoK20gKyAxKSArICcuMCc7XG5cbiAgICBkZWJ1ZygndGlsZGUgcmV0dXJuJywgcmV0KTtcbiAgICByZXR1cm4gcmV0O1xuICB9KTtcbn1cblxuLy8gXiAtLT4gKiAoYW55LCBraW5kYSBzaWxseSlcbi8vIF4yLCBeMi54LCBeMi54LnggLS0+ID49Mi4wLjAgPDMuMC4wXG4vLyBeMi4wLCBeMi4wLnggLS0+ID49Mi4wLjAgPDMuMC4wXG4vLyBeMS4yLCBeMS4yLnggLS0+ID49MS4yLjAgPDIuMC4wXG4vLyBeMS4yLjMgLS0+ID49MS4yLjMgPDIuMC4wXG4vLyBeMS4yLjAgLS0+ID49MS4yLjAgPDIuMC4wXG5mdW5jdGlvbiByZXBsYWNlQ2FyZXRzKGNvbXAsIGxvb3NlKSB7XG4gIHJldHVybiBjb21wLnRyaW0oKS5zcGxpdCgvXFxzKy8pLm1hcChmdW5jdGlvbihjb21wKSB7XG4gICAgcmV0dXJuIHJlcGxhY2VDYXJldChjb21wLCBsb29zZSk7XG4gIH0pLmpvaW4oJyAnKTtcbn1cblxuZnVuY3Rpb24gcmVwbGFjZUNhcmV0KGNvbXAsIGxvb3NlKSB7XG4gIGRlYnVnKCdjYXJldCcsIGNvbXAsIGxvb3NlKTtcbiAgdmFyIHIgPSBsb29zZSA/IHJlW0NBUkVUTE9PU0VdIDogcmVbQ0FSRVRdO1xuICByZXR1cm4gY29tcC5yZXBsYWNlKHIsIGZ1bmN0aW9uKF8sIE0sIG0sIHAsIHByKSB7XG4gICAgZGVidWcoJ2NhcmV0JywgY29tcCwgXywgTSwgbSwgcCwgcHIpO1xuICAgIHZhciByZXQ7XG5cbiAgICBpZiAoaXNYKE0pKVxuICAgICAgcmV0ID0gJyc7XG4gICAgZWxzZSBpZiAoaXNYKG0pKVxuICAgICAgcmV0ID0gJz49JyArIE0gKyAnLjAuMCA8JyArICgrTSArIDEpICsgJy4wLjAnO1xuICAgIGVsc2UgaWYgKGlzWChwKSkge1xuICAgICAgaWYgKE0gPT09ICcwJylcbiAgICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4wIDwnICsgTSArICcuJyArICgrbSArIDEpICsgJy4wJztcbiAgICAgIGVsc2VcbiAgICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4wIDwnICsgKCtNICsgMSkgKyAnLjAuMCc7XG4gICAgfSBlbHNlIGlmIChwcikge1xuICAgICAgZGVidWcoJ3JlcGxhY2VDYXJldCBwcicsIHByKTtcbiAgICAgIGlmIChwci5jaGFyQXQoMCkgIT09ICctJylcbiAgICAgICAgcHIgPSAnLScgKyBwcjtcbiAgICAgIGlmIChNID09PSAnMCcpIHtcbiAgICAgICAgaWYgKG0gPT09ICcwJylcbiAgICAgICAgICByZXQgPSAnPj0nICsgTSArICcuJyArIG0gKyAnLicgKyBwICsgcHIgK1xuICAgICAgICAgICAgICAgICcgPCcgKyBNICsgJy4nICsgbSArICcuJyArICgrcCArIDEpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4nICsgcCArIHByICtcbiAgICAgICAgICAgICAgICAnIDwnICsgTSArICcuJyArICgrbSArIDEpICsgJy4wJztcbiAgICAgIH0gZWxzZVxuICAgICAgICByZXQgPSAnPj0nICsgTSArICcuJyArIG0gKyAnLicgKyBwICsgcHIgK1xuICAgICAgICAgICAgICAnIDwnICsgKCtNICsgMSkgKyAnLjAuMCc7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlYnVnKCdubyBwcicpO1xuICAgICAgaWYgKE0gPT09ICcwJykge1xuICAgICAgICBpZiAobSA9PT0gJzAnKVxuICAgICAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuJyArIHAgK1xuICAgICAgICAgICAgICAgICcgPCcgKyBNICsgJy4nICsgbSArICcuJyArICgrcCArIDEpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4nICsgcCArXG4gICAgICAgICAgICAgICAgJyA8JyArIE0gKyAnLicgKyAoK20gKyAxKSArICcuMCc7XG4gICAgICB9IGVsc2VcbiAgICAgICAgcmV0ID0gJz49JyArIE0gKyAnLicgKyBtICsgJy4nICsgcCArXG4gICAgICAgICAgICAgICcgPCcgKyAoK00gKyAxKSArICcuMC4wJztcbiAgICB9XG5cbiAgICBkZWJ1ZygnY2FyZXQgcmV0dXJuJywgcmV0KTtcbiAgICByZXR1cm4gcmV0O1xuICB9KTtcbn1cblxuZnVuY3Rpb24gcmVwbGFjZVhSYW5nZXMoY29tcCwgbG9vc2UpIHtcbiAgZGVidWcoJ3JlcGxhY2VYUmFuZ2VzJywgY29tcCwgbG9vc2UpO1xuICByZXR1cm4gY29tcC5zcGxpdCgvXFxzKy8pLm1hcChmdW5jdGlvbihjb21wKSB7XG4gICAgcmV0dXJuIHJlcGxhY2VYUmFuZ2UoY29tcCwgbG9vc2UpO1xuICB9KS5qb2luKCcgJyk7XG59XG5cbmZ1bmN0aW9uIHJlcGxhY2VYUmFuZ2UoY29tcCwgbG9vc2UpIHtcbiAgY29tcCA9IGNvbXAudHJpbSgpO1xuICB2YXIgciA9IGxvb3NlID8gcmVbWFJBTkdFTE9PU0VdIDogcmVbWFJBTkdFXTtcbiAgcmV0dXJuIGNvbXAucmVwbGFjZShyLCBmdW5jdGlvbihyZXQsIGd0bHQsIE0sIG0sIHAsIHByKSB7XG4gICAgZGVidWcoJ3hSYW5nZScsIGNvbXAsIHJldCwgZ3RsdCwgTSwgbSwgcCwgcHIpO1xuICAgIHZhciB4TSA9IGlzWChNKTtcbiAgICB2YXIgeG0gPSB4TSB8fCBpc1gobSk7XG4gICAgdmFyIHhwID0geG0gfHwgaXNYKHApO1xuICAgIHZhciBhbnlYID0geHA7XG5cbiAgICBpZiAoZ3RsdCA9PT0gJz0nICYmIGFueVgpXG4gICAgICBndGx0ID0gJyc7XG5cbiAgICBpZiAoeE0pIHtcbiAgICAgIGlmIChndGx0ID09PSAnPicgfHwgZ3RsdCA9PT0gJzwnKSB7XG4gICAgICAgIC8vIG5vdGhpbmcgaXMgYWxsb3dlZFxuICAgICAgICByZXQgPSAnPDAuMC4wJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG5vdGhpbmcgaXMgZm9yYmlkZGVuXG4gICAgICAgIHJldCA9ICcqJztcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGd0bHQgJiYgYW55WCkge1xuICAgICAgLy8gcmVwbGFjZSBYIHdpdGggMFxuICAgICAgaWYgKHhtKVxuICAgICAgICBtID0gMDtcbiAgICAgIGlmICh4cClcbiAgICAgICAgcCA9IDA7XG5cbiAgICAgIGlmIChndGx0ID09PSAnPicpIHtcbiAgICAgICAgLy8gPjEgPT4gPj0yLjAuMFxuICAgICAgICAvLyA+MS4yID0+ID49MS4zLjBcbiAgICAgICAgLy8gPjEuMi4zID0+ID49IDEuMi40XG4gICAgICAgIGd0bHQgPSAnPj0nO1xuICAgICAgICBpZiAoeG0pIHtcbiAgICAgICAgICBNID0gK00gKyAxO1xuICAgICAgICAgIG0gPSAwO1xuICAgICAgICAgIHAgPSAwO1xuICAgICAgICB9IGVsc2UgaWYgKHhwKSB7XG4gICAgICAgICAgbSA9ICttICsgMTtcbiAgICAgICAgICBwID0gMDtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChndGx0ID09PSAnPD0nKSB7XG4gICAgICAgIC8vIDw9MC43LnggaXMgYWN0dWFsbHkgPDAuOC4wLCBzaW5jZSBhbnkgMC43Lnggc2hvdWxkXG4gICAgICAgIC8vIHBhc3MuICBTaW1pbGFybHksIDw9Ny54IGlzIGFjdHVhbGx5IDw4LjAuMCwgZXRjLlxuICAgICAgICBndGx0ID0gJzwnO1xuICAgICAgICBpZiAoeG0pXG4gICAgICAgICAgTSA9ICtNICsgMTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgIG0gPSArbSArIDE7XG4gICAgICB9XG5cbiAgICAgIHJldCA9IGd0bHQgKyBNICsgJy4nICsgbSArICcuJyArIHA7XG4gICAgfSBlbHNlIGlmICh4bSkge1xuICAgICAgcmV0ID0gJz49JyArIE0gKyAnLjAuMCA8JyArICgrTSArIDEpICsgJy4wLjAnO1xuICAgIH0gZWxzZSBpZiAoeHApIHtcbiAgICAgIHJldCA9ICc+PScgKyBNICsgJy4nICsgbSArICcuMCA8JyArIE0gKyAnLicgKyAoK20gKyAxKSArICcuMCc7XG4gICAgfVxuXG4gICAgZGVidWcoJ3hSYW5nZSByZXR1cm4nLCByZXQpO1xuXG4gICAgcmV0dXJuIHJldDtcbiAgfSk7XG59XG5cbi8vIEJlY2F1c2UgKiBpcyBBTkQtZWQgd2l0aCBldmVyeXRoaW5nIGVsc2UgaW4gdGhlIGNvbXBhcmF0b3IsXG4vLyBhbmQgJycgbWVhbnMgXCJhbnkgdmVyc2lvblwiLCBqdXN0IHJlbW92ZSB0aGUgKnMgZW50aXJlbHkuXG5mdW5jdGlvbiByZXBsYWNlU3RhcnMoY29tcCwgbG9vc2UpIHtcbiAgZGVidWcoJ3JlcGxhY2VTdGFycycsIGNvbXAsIGxvb3NlKTtcbiAgLy8gTG9vc2VuZXNzIGlzIGlnbm9yZWQgaGVyZS4gIHN0YXIgaXMgYWx3YXlzIGFzIGxvb3NlIGFzIGl0IGdldHMhXG4gIHJldHVybiBjb21wLnRyaW0oKS5yZXBsYWNlKHJlW1NUQVJdLCAnJyk7XG59XG5cbi8vIFRoaXMgZnVuY3Rpb24gaXMgcGFzc2VkIHRvIHN0cmluZy5yZXBsYWNlKHJlW0hZUEhFTlJBTkdFXSlcbi8vIE0sIG0sIHBhdGNoLCBwcmVyZWxlYXNlLCBidWlsZFxuLy8gMS4yIC0gMy40LjUgPT4gPj0xLjIuMCA8PTMuNC41XG4vLyAxLjIuMyAtIDMuNCA9PiA+PTEuMi4wIDwzLjUuMCBBbnkgMy40Lnggd2lsbCBkb1xuLy8gMS4yIC0gMy40ID0+ID49MS4yLjAgPDMuNS4wXG5mdW5jdGlvbiBoeXBoZW5SZXBsYWNlKCQwLFxuICAgICAgICAgICAgICAgICAgICAgICBmcm9tLCBmTSwgZm0sIGZwLCBmcHIsIGZiLFxuICAgICAgICAgICAgICAgICAgICAgICB0bywgdE0sIHRtLCB0cCwgdHByLCB0Yikge1xuXG4gIGlmIChpc1goZk0pKVxuICAgIGZyb20gPSAnJztcbiAgZWxzZSBpZiAoaXNYKGZtKSlcbiAgICBmcm9tID0gJz49JyArIGZNICsgJy4wLjAnO1xuICBlbHNlIGlmIChpc1goZnApKVxuICAgIGZyb20gPSAnPj0nICsgZk0gKyAnLicgKyBmbSArICcuMCc7XG4gIGVsc2VcbiAgICBmcm9tID0gJz49JyArIGZyb207XG5cbiAgaWYgKGlzWCh0TSkpXG4gICAgdG8gPSAnJztcbiAgZWxzZSBpZiAoaXNYKHRtKSlcbiAgICB0byA9ICc8JyArICgrdE0gKyAxKSArICcuMC4wJztcbiAgZWxzZSBpZiAoaXNYKHRwKSlcbiAgICB0byA9ICc8JyArIHRNICsgJy4nICsgKCt0bSArIDEpICsgJy4wJztcbiAgZWxzZSBpZiAodHByKVxuICAgIHRvID0gJzw9JyArIHRNICsgJy4nICsgdG0gKyAnLicgKyB0cCArICctJyArIHRwcjtcbiAgZWxzZVxuICAgIHRvID0gJzw9JyArIHRvO1xuXG4gIHJldHVybiAoZnJvbSArICcgJyArIHRvKS50cmltKCk7XG59XG5cblxuLy8gaWYgQU5ZIG9mIHRoZSBzZXRzIG1hdGNoIEFMTCBvZiBpdHMgY29tcGFyYXRvcnMsIHRoZW4gcGFzc1xuUmFuZ2UucHJvdG90eXBlLnRlc3QgPSBmdW5jdGlvbih2ZXJzaW9uKSB7XG4gIGlmICghdmVyc2lvbilcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgaWYgKHR5cGVvZiB2ZXJzaW9uID09PSAnc3RyaW5nJylcbiAgICB2ZXJzaW9uID0gbmV3IFNlbVZlcih2ZXJzaW9uLCB0aGlzLmxvb3NlKTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuc2V0Lmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHRlc3RTZXQodGhpcy5zZXRbaV0sIHZlcnNpb24pKVxuICAgICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuZnVuY3Rpb24gdGVzdFNldChzZXQsIHZlcnNpb24pIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzZXQubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoIXNldFtpXS50ZXN0KHZlcnNpb24pKVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKHZlcnNpb24ucHJlcmVsZWFzZS5sZW5ndGgpIHtcbiAgICAvLyBGaW5kIHRoZSBzZXQgb2YgdmVyc2lvbnMgdGhhdCBhcmUgYWxsb3dlZCB0byBoYXZlIHByZXJlbGVhc2VzXG4gICAgLy8gRm9yIGV4YW1wbGUsIF4xLjIuMy1wci4xIGRlc3VnYXJzIHRvID49MS4yLjMtcHIuMSA8Mi4wLjBcbiAgICAvLyBUaGF0IHNob3VsZCBhbGxvdyBgMS4yLjMtcHIuMmAgdG8gcGFzcy5cbiAgICAvLyBIb3dldmVyLCBgMS4yLjQtYWxwaGEubm90cmVhZHlgIHNob3VsZCBOT1QgYmUgYWxsb3dlZCxcbiAgICAvLyBldmVuIHRob3VnaCBpdCdzIHdpdGhpbiB0aGUgcmFuZ2Ugc2V0IGJ5IHRoZSBjb21wYXJhdG9ycy5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNldC5sZW5ndGg7IGkrKykge1xuICAgICAgZGVidWcoc2V0W2ldLnNlbXZlcik7XG4gICAgICBpZiAoc2V0W2ldLnNlbXZlciA9PT0gQU5ZKVxuICAgICAgICBjb250aW51ZTtcblxuICAgICAgaWYgKHNldFtpXS5zZW12ZXIucHJlcmVsZWFzZS5sZW5ndGggPiAwKSB7XG4gICAgICAgIHZhciBhbGxvd2VkID0gc2V0W2ldLnNlbXZlcjtcbiAgICAgICAgaWYgKGFsbG93ZWQubWFqb3IgPT09IHZlcnNpb24ubWFqb3IgJiZcbiAgICAgICAgICAgIGFsbG93ZWQubWlub3IgPT09IHZlcnNpb24ubWlub3IgJiZcbiAgICAgICAgICAgIGFsbG93ZWQucGF0Y2ggPT09IHZlcnNpb24ucGF0Y2gpXG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gVmVyc2lvbiBoYXMgYSAtcHJlLCBidXQgaXQncyBub3Qgb25lIG9mIHRoZSBvbmVzIHdlIGxpa2UuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmV4cG9ydHMuc2F0aXNmaWVzID0gc2F0aXNmaWVzO1xuZnVuY3Rpb24gc2F0aXNmaWVzKHZlcnNpb24sIHJhbmdlLCBsb29zZSkge1xuICB0cnkge1xuICAgIHJhbmdlID0gbmV3IFJhbmdlKHJhbmdlLCBsb29zZSk7XG4gIH0gY2F0Y2ggKGVyKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiByYW5nZS50ZXN0KHZlcnNpb24pO1xufVxuXG5leHBvcnRzLm1heFNhdGlzZnlpbmcgPSBtYXhTYXRpc2Z5aW5nO1xuZnVuY3Rpb24gbWF4U2F0aXNmeWluZyh2ZXJzaW9ucywgcmFuZ2UsIGxvb3NlKSB7XG4gIHZhciBtYXggPSBudWxsO1xuICB2YXIgbWF4U1YgPSBudWxsO1xuICB0cnkge1xuICAgIHZhciByYW5nZU9iaiA9IG5ldyBSYW5nZShyYW5nZSwgbG9vc2UpO1xuICB9IGNhdGNoIChlcikge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHZlcnNpb25zLmZvckVhY2goZnVuY3Rpb24gKHYpIHtcbiAgICBpZiAocmFuZ2VPYmoudGVzdCh2KSkgeyAvLyBzYXRpc2ZpZXModiwgcmFuZ2UsIGxvb3NlKVxuICAgICAgaWYgKCFtYXggfHwgbWF4U1YuY29tcGFyZSh2KSA9PT0gLTEpIHsgLy8gY29tcGFyZShtYXgsIHYsIHRydWUpXG4gICAgICAgIG1heCA9IHY7XG4gICAgICAgIG1heFNWID0gbmV3IFNlbVZlcihtYXgsIGxvb3NlKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pXG4gIHJldHVybiBtYXg7XG59XG5cbmV4cG9ydHMubWluU2F0aXNmeWluZyA9IG1pblNhdGlzZnlpbmc7XG5mdW5jdGlvbiBtaW5TYXRpc2Z5aW5nKHZlcnNpb25zLCByYW5nZSwgbG9vc2UpIHtcbiAgdmFyIG1pbiA9IG51bGw7XG4gIHZhciBtaW5TViA9IG51bGw7XG4gIHRyeSB7XG4gICAgdmFyIHJhbmdlT2JqID0gbmV3IFJhbmdlKHJhbmdlLCBsb29zZSk7XG4gIH0gY2F0Y2ggKGVyKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgdmVyc2lvbnMuZm9yRWFjaChmdW5jdGlvbiAodikge1xuICAgIGlmIChyYW5nZU9iai50ZXN0KHYpKSB7IC8vIHNhdGlzZmllcyh2LCByYW5nZSwgbG9vc2UpXG4gICAgICBpZiAoIW1pbiB8fCBtaW5TVi5jb21wYXJlKHYpID09PSAxKSB7IC8vIGNvbXBhcmUobWluLCB2LCB0cnVlKVxuICAgICAgICBtaW4gPSB2O1xuICAgICAgICBtaW5TViA9IG5ldyBTZW1WZXIobWluLCBsb29zZSk7XG4gICAgICB9XG4gICAgfVxuICB9KVxuICByZXR1cm4gbWluO1xufVxuXG5leHBvcnRzLnZhbGlkUmFuZ2UgPSB2YWxpZFJhbmdlO1xuZnVuY3Rpb24gdmFsaWRSYW5nZShyYW5nZSwgbG9vc2UpIHtcbiAgdHJ5IHtcbiAgICAvLyBSZXR1cm4gJyonIGluc3RlYWQgb2YgJycgc28gdGhhdCB0cnV0aGluZXNzIHdvcmtzLlxuICAgIC8vIFRoaXMgd2lsbCB0aHJvdyBpZiBpdCdzIGludmFsaWQgYW55d2F5XG4gICAgcmV0dXJuIG5ldyBSYW5nZShyYW5nZSwgbG9vc2UpLnJhbmdlIHx8ICcqJztcbiAgfSBjYXRjaCAoZXIpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG4vLyBEZXRlcm1pbmUgaWYgdmVyc2lvbiBpcyBsZXNzIHRoYW4gYWxsIHRoZSB2ZXJzaW9ucyBwb3NzaWJsZSBpbiB0aGUgcmFuZ2VcbmV4cG9ydHMubHRyID0gbHRyO1xuZnVuY3Rpb24gbHRyKHZlcnNpb24sIHJhbmdlLCBsb29zZSkge1xuICByZXR1cm4gb3V0c2lkZSh2ZXJzaW9uLCByYW5nZSwgJzwnLCBsb29zZSk7XG59XG5cbi8vIERldGVybWluZSBpZiB2ZXJzaW9uIGlzIGdyZWF0ZXIgdGhhbiBhbGwgdGhlIHZlcnNpb25zIHBvc3NpYmxlIGluIHRoZSByYW5nZS5cbmV4cG9ydHMuZ3RyID0gZ3RyO1xuZnVuY3Rpb24gZ3RyKHZlcnNpb24sIHJhbmdlLCBsb29zZSkge1xuICByZXR1cm4gb3V0c2lkZSh2ZXJzaW9uLCByYW5nZSwgJz4nLCBsb29zZSk7XG59XG5cbmV4cG9ydHMub3V0c2lkZSA9IG91dHNpZGU7XG5mdW5jdGlvbiBvdXRzaWRlKHZlcnNpb24sIHJhbmdlLCBoaWxvLCBsb29zZSkge1xuICB2ZXJzaW9uID0gbmV3IFNlbVZlcih2ZXJzaW9uLCBsb29zZSk7XG4gIHJhbmdlID0gbmV3IFJhbmdlKHJhbmdlLCBsb29zZSk7XG5cbiAgdmFyIGd0Zm4sIGx0ZWZuLCBsdGZuLCBjb21wLCBlY29tcDtcbiAgc3dpdGNoIChoaWxvKSB7XG4gICAgY2FzZSAnPic6XG4gICAgICBndGZuID0gZ3Q7XG4gICAgICBsdGVmbiA9IGx0ZTtcbiAgICAgIGx0Zm4gPSBsdDtcbiAgICAgIGNvbXAgPSAnPic7XG4gICAgICBlY29tcCA9ICc+PSc7XG4gICAgICBicmVhaztcbiAgICBjYXNlICc8JzpcbiAgICAgIGd0Zm4gPSBsdDtcbiAgICAgIGx0ZWZuID0gZ3RlO1xuICAgICAgbHRmbiA9IGd0O1xuICAgICAgY29tcCA9ICc8JztcbiAgICAgIGVjb21wID0gJzw9JztcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdNdXN0IHByb3ZpZGUgYSBoaWxvIHZhbCBvZiBcIjxcIiBvciBcIj5cIicpO1xuICB9XG5cbiAgLy8gSWYgaXQgc2F0aXNpZmVzIHRoZSByYW5nZSBpdCBpcyBub3Qgb3V0c2lkZVxuICBpZiAoc2F0aXNmaWVzKHZlcnNpb24sIHJhbmdlLCBsb29zZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvLyBGcm9tIG5vdyBvbiwgdmFyaWFibGUgdGVybXMgYXJlIGFzIGlmIHdlJ3JlIGluIFwiZ3RyXCIgbW9kZS5cbiAgLy8gYnV0IG5vdGUgdGhhdCBldmVyeXRoaW5nIGlzIGZsaXBwZWQgZm9yIHRoZSBcImx0clwiIGZ1bmN0aW9uLlxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcmFuZ2Uuc2V0Lmxlbmd0aDsgKytpKSB7XG4gICAgdmFyIGNvbXBhcmF0b3JzID0gcmFuZ2Uuc2V0W2ldO1xuXG4gICAgdmFyIGhpZ2ggPSBudWxsO1xuICAgIHZhciBsb3cgPSBudWxsO1xuXG4gICAgY29tcGFyYXRvcnMuZm9yRWFjaChmdW5jdGlvbihjb21wYXJhdG9yKSB7XG4gICAgICBpZiAoY29tcGFyYXRvci5zZW12ZXIgPT09IEFOWSkge1xuICAgICAgICBjb21wYXJhdG9yID0gbmV3IENvbXBhcmF0b3IoJz49MC4wLjAnKVxuICAgICAgfVxuICAgICAgaGlnaCA9IGhpZ2ggfHwgY29tcGFyYXRvcjtcbiAgICAgIGxvdyA9IGxvdyB8fCBjb21wYXJhdG9yO1xuICAgICAgaWYgKGd0Zm4oY29tcGFyYXRvci5zZW12ZXIsIGhpZ2guc2VtdmVyLCBsb29zZSkpIHtcbiAgICAgICAgaGlnaCA9IGNvbXBhcmF0b3I7XG4gICAgICB9IGVsc2UgaWYgKGx0Zm4oY29tcGFyYXRvci5zZW12ZXIsIGxvdy5zZW12ZXIsIGxvb3NlKSkge1xuICAgICAgICBsb3cgPSBjb21wYXJhdG9yO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gSWYgdGhlIGVkZ2UgdmVyc2lvbiBjb21wYXJhdG9yIGhhcyBhIG9wZXJhdG9yIHRoZW4gb3VyIHZlcnNpb25cbiAgICAvLyBpc24ndCBvdXRzaWRlIGl0XG4gICAgaWYgKGhpZ2gub3BlcmF0b3IgPT09IGNvbXAgfHwgaGlnaC5vcGVyYXRvciA9PT0gZWNvbXApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBJZiB0aGUgbG93ZXN0IHZlcnNpb24gY29tcGFyYXRvciBoYXMgYW4gb3BlcmF0b3IgYW5kIG91ciB2ZXJzaW9uXG4gICAgLy8gaXMgbGVzcyB0aGFuIGl0IHRoZW4gaXQgaXNuJ3QgaGlnaGVyIHRoYW4gdGhlIHJhbmdlXG4gICAgaWYgKCghbG93Lm9wZXJhdG9yIHx8IGxvdy5vcGVyYXRvciA9PT0gY29tcCkgJiZcbiAgICAgICAgbHRlZm4odmVyc2lvbiwgbG93LnNlbXZlcikpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9IGVsc2UgaWYgKGxvdy5vcGVyYXRvciA9PT0gZWNvbXAgJiYgbHRmbih2ZXJzaW9uLCBsb3cuc2VtdmVyKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZXhwb3J0cy5wcmVyZWxlYXNlID0gcHJlcmVsZWFzZTtcbmZ1bmN0aW9uIHByZXJlbGVhc2UodmVyc2lvbiwgbG9vc2UpIHtcbiAgdmFyIHBhcnNlZCA9IHBhcnNlKHZlcnNpb24sIGxvb3NlKTtcbiAgcmV0dXJuIChwYXJzZWQgJiYgcGFyc2VkLnByZXJlbGVhc2UubGVuZ3RoKSA/IHBhcnNlZC5wcmVyZWxlYXNlIDogbnVsbDtcbn1cblxuZXhwb3J0cy5pbnRlcnNlY3RzID0gaW50ZXJzZWN0cztcbmZ1bmN0aW9uIGludGVyc2VjdHMocjEsIHIyLCBsb29zZSkge1xuICByMSA9IG5ldyBSYW5nZShyMSwgbG9vc2UpXG4gIHIyID0gbmV3IFJhbmdlKHIyLCBsb29zZSlcbiAgcmV0dXJuIHIxLmludGVyc2VjdHMocjIpXG59XG4iLCIvKlxuICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZVxuICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlXG4gKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvblxuICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZVxuICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZVxuICogXCJMaWNlbnNlXCIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlXG4gKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsXG4gKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhblxuICogXCJBUyBJU1wiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTllcbiAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZVxuICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9uc1xuICogdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbmltcG9ydCBzZW12ZXIgZnJvbSAnc2VtdmVyJ1xuaW1wb3J0IHsgaXNQbGFpbk9iamVjdCwgdHlwb2YgfSBmcm9tICcuLi91dGlsL2luZGV4J1xuXG4vKipcbiAqIE5vcm1hbGl6ZSBhIHZlcnNpb24gc3RyaW5nLlxuICogQHBhcmFtICB7U3RyaW5nfSBWZXJzaW9uLiBpZTogMSwgMS4wLCAxLjAuMFxuICogQHJldHVybiB7U3RyaW5nfSBWZXJzaW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVWZXJzaW9uICh2KSB7XG4gIGNvbnN0IGlzVmFsaWQgPSBzZW12ZXIudmFsaWQodilcbiAgaWYgKGlzVmFsaWQpIHtcbiAgICByZXR1cm4gdlxuICB9XG5cbiAgdiA9IHR5cGVvZiAodikgPT09ICdzdHJpbmcnID8gdiA6ICcnXG4gIGNvbnN0IHNwbGl0ID0gdi5zcGxpdCgnLicpXG4gIGxldCBpID0gMFxuICBjb25zdCByZXN1bHQgPSBbXVxuXG4gIHdoaWxlIChpIDwgMykge1xuICAgIGNvbnN0IHMgPSB0eXBlb2YgKHNwbGl0W2ldKSA9PT0gJ3N0cmluZycgJiYgc3BsaXRbaV0gPyBzcGxpdFtpXSA6ICcwJ1xuICAgIHJlc3VsdC5wdXNoKHMpXG4gICAgaSsrXG4gIH1cblxuICByZXR1cm4gcmVzdWx0LmpvaW4oJy4nKVxufVxuXG4vKipcbiAqIEdldCBpbmZvcm1hdGlvbnMgZnJvbSBkaWZmZXJlbnQgZXJyb3Iga2V5LiBMaWtlOlxuICogLSBjb2RlXG4gKiAtIGVycm9yTWVzc2FnZVxuICogLSBlcnJvclR5cGVcbiAqIC0gaXNEb3duZ3JhZGVcbiAqIEBwYXJhbSAge3N0cmluZ30ga2V5XG4gKiBAcGFyYW0gIHtzdHJpbmd9IHZhbFxuICogQHBhcmFtICB7c3RyaW5nfSBjcml0ZXJpYVxuICogQHJldHVybiB7b2JqZWN0fVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RXJyb3IgKGtleSwgdmFsLCBjcml0ZXJpYSkge1xuICBjb25zdCByZXN1bHQgPSB7XG4gICAgaXNEb3duZ3JhZGU6IHRydWUsXG4gICAgZXJyb3JUeXBlOiAxLFxuICAgIGNvZGU6IDEwMDBcbiAgfVxuICBjb25zdCBnZXRNc2cgPSBmdW5jdGlvbiAoa2V5LCB2YWwsIGNyaXRlcmlhKSB7XG4gICAgcmV0dXJuICdEb3duZ3JhZGVbJyArIGtleSArICddIDo6IGRldmljZUluZm8gJ1xuICAgICAgKyB2YWwgKyAnIG1hdGNoZWQgY3JpdGVyaWEgJyArIGNyaXRlcmlhXG4gIH1cbiAgY29uc3QgX2tleSA9IGtleS50b0xvd2VyQ2FzZSgpXG5cbiAgcmVzdWx0LmVycm9yTWVzc2FnZSA9IGdldE1zZyhrZXksIHZhbCwgY3JpdGVyaWEpXG5cbiAgaWYgKF9rZXkuaW5kZXhPZignb3N2ZXJzaW9uJykgPj0gMCkge1xuICAgIHJlc3VsdC5jb2RlID0gMTAwMVxuICB9XG4gIGVsc2UgaWYgKF9rZXkuaW5kZXhPZignYXBwdmVyc2lvbicpID49IDApIHtcbiAgICByZXN1bHQuY29kZSA9IDEwMDJcbiAgfVxuICBlbHNlIGlmIChfa2V5LmluZGV4T2YoJ3dlZXh2ZXJzaW9uJykgPj0gMCkge1xuICAgIHJlc3VsdC5jb2RlID0gMTAwM1xuICB9XG4gIGVsc2UgaWYgKF9rZXkuaW5kZXhPZignZGV2aWNlbW9kZWwnKSA+PSAwKSB7XG4gICAgcmVzdWx0LmNvZGUgPSAxMDA0XG4gIH1cblxuICByZXR1cm4gcmVzdWx0XG59XG5cbi8qKlxuICogV0VFWCBmcmFtZXdvcmsgaW5wdXQoZGV2aWNlSW5mbylcbiAqIHtcbiAqICAgcGxhdGZvcm06ICdpT1MnIG9yICdhbmRyb2lkJ1xuICogICBvc1ZlcnNpb246ICcxLjAuMCcgb3IgJzEuMCcgb3IgJzEnXG4gKiAgIGFwcFZlcnNpb246ICcxLjAuMCcgb3IgJzEuMCcgb3IgJzEnXG4gKiAgIHdlZXhWZXJzaW9uOiAnMS4wLjAnIG9yICcxLjAnIG9yICcxJ1xuICogICBkRGV2aWNlTW9kZWw6ICdNT0RFTF9OQU1FJ1xuICogfVxuICpcbiAqIGRvd25ncmFkZSBjb25maWcoY29uZmlnKVxuICoge1xuICogICBpb3M6IHtcbiAqICAgICBvc1ZlcnNpb246ICc+MS4wLjAnIG9yICc+PTEuMC4wJyBvciAnPDEuMC4wJyBvciAnPD0xLjAuMCcgb3IgJzEuMC4wJ1xuICogICAgIGFwcFZlcnNpb246ICc+MS4wLjAnIG9yICc+PTEuMC4wJyBvciAnPDEuMC4wJyBvciAnPD0xLjAuMCcgb3IgJzEuMC4wJ1xuICogICAgIHdlZXhWZXJzaW9uOiAnPjEuMC4wJyBvciAnPj0xLjAuMCcgb3IgJzwxLjAuMCcgb3IgJzw9MS4wLjAnIG9yICcxLjAuMCdcbiAqICAgICBkZXZpY2VNb2RlbDogWydtb2RlbEEnLCAnbW9kZWxCJywgLi4uXVxuICogICB9LFxuICogICBhbmRyb2lkOiB7XG4gKiAgICAgb3NWZXJzaW9uOiAnPjEuMC4wJyBvciAnPj0xLjAuMCcgb3IgJzwxLjAuMCcgb3IgJzw9MS4wLjAnIG9yICcxLjAuMCdcbiAqICAgICBhcHBWZXJzaW9uOiAnPjEuMC4wJyBvciAnPj0xLjAuMCcgb3IgJzwxLjAuMCcgb3IgJzw9MS4wLjAnIG9yICcxLjAuMCdcbiAqICAgICB3ZWV4VmVyc2lvbjogJz4xLjAuMCcgb3IgJz49MS4wLjAnIG9yICc8MS4wLjAnIG9yICc8PTEuMC4wJyBvciAnMS4wLjAnXG4gKiAgICAgZGV2aWNlTW9kZWw6IFsnbW9kZWxBJywgJ21vZGVsQicsIC4uLl1cbiAqICAgfVxuICogfVxuICpcbiAqXG4gKiBAcGFyYW0gIHtvYmplY3R9IGRldmljZUluZm8gV2VleCBTREsgZnJhbWV3b3JrIGlucHV0XG4gKiBAcGFyYW0gIHtvYmplY3R9IGNvbmZpZyAgICAgdXNlciBpbnB1dFxuICogQHJldHVybiB7T2JqZWN0fSAgICAgICAgICAgIHsgaXNEb3duZ3JhZGU6IHRydWUvZmFsc2UsIGVycm9yTWVzc2FnZS4uLiB9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjaGVjayAoY29uZmlnLCBkZXZpY2VJbmZvKSB7XG4gIGRldmljZUluZm8gPSBkZXZpY2VJbmZvIHx8IGdsb2JhbC5XWEVudmlyb25tZW50XG4gIGRldmljZUluZm8gPSBpc1BsYWluT2JqZWN0KGRldmljZUluZm8pID8gZGV2aWNlSW5mbyA6IHt9XG5cbiAgbGV0IHJlc3VsdCA9IHtcbiAgICBpc0Rvd25ncmFkZTogZmFsc2UgLy8gZGVmYXV0bCBpcyBwYXNzXG4gIH1cblxuICBpZiAodHlwb2YoY29uZmlnKSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGxldCBjdXN0b21Eb3duZ3JhZGUgPSBjb25maWcuY2FsbCh0aGlzLCBkZXZpY2VJbmZvLCB7XG4gICAgICBzZW12ZXI6IHNlbXZlcixcbiAgICAgIG5vcm1hbGl6ZVZlcnNpb25cbiAgICB9KVxuXG4gICAgY3VzdG9tRG93bmdyYWRlID0gISFjdXN0b21Eb3duZ3JhZGVcblxuICAgIHJlc3VsdCA9IGN1c3RvbURvd25ncmFkZSA/IGdldEVycm9yKCdjdXN0b20nLCAnJywgJ2N1c3RvbSBwYXJhbXMnKSA6IHJlc3VsdFxuICB9XG4gIGVsc2Uge1xuICAgIGNvbmZpZyA9IGlzUGxhaW5PYmplY3QoY29uZmlnKSA/IGNvbmZpZyA6IHt9XG5cbiAgICBjb25zdCBwbGF0Zm9ybSA9IGRldmljZUluZm8ucGxhdGZvcm0gfHwgJ3Vua25vdydcbiAgICBjb25zdCBkUGxhdGZvcm0gPSBwbGF0Zm9ybS50b0xvd2VyQ2FzZSgpXG4gICAgY29uc3QgY09iaiA9IGNvbmZpZ1tkUGxhdGZvcm1dIHx8IHt9XG5cbiAgICBmb3IgKGNvbnN0IGkgaW4gZGV2aWNlSW5mbykge1xuICAgICAgY29uc3Qga2V5ID0gaVxuICAgICAgY29uc3Qga2V5TG93ZXIgPSBrZXkudG9Mb3dlckNhc2UoKVxuICAgICAgY29uc3QgdmFsID0gZGV2aWNlSW5mb1tpXVxuICAgICAgY29uc3QgaXNWZXJzaW9uID0ga2V5TG93ZXIuaW5kZXhPZigndmVyc2lvbicpID49IDBcbiAgICAgIGNvbnN0IGlzRGV2aWNlTW9kZWwgPSBrZXlMb3dlci5pbmRleE9mKCdkZXZpY2Vtb2RlbCcpID49IDBcbiAgICAgIGNvbnN0IGNyaXRlcmlhID0gY09ialtpXVxuXG4gICAgICBpZiAoY3JpdGVyaWEgJiYgaXNWZXJzaW9uKSB7XG4gICAgICAgIGNvbnN0IGMgPSBub3JtYWxpemVWZXJzaW9uKGNyaXRlcmlhKVxuICAgICAgICBjb25zdCBkID0gbm9ybWFsaXplVmVyc2lvbihkZXZpY2VJbmZvW2ldKVxuXG4gICAgICAgIGlmIChzZW12ZXIuc2F0aXNmaWVzKGQsIGMpKSB7XG4gICAgICAgICAgcmVzdWx0ID0gZ2V0RXJyb3Ioa2V5LCB2YWwsIGNyaXRlcmlhKVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKGlzRGV2aWNlTW9kZWwpIHtcbiAgICAgICAgY29uc3QgX2NyaXRlcmlhID0gdHlwb2YoY3JpdGVyaWEpID09PSAnYXJyYXknID8gY3JpdGVyaWEgOiBbY3JpdGVyaWFdXG4gICAgICAgIGlmIChfY3JpdGVyaWEuaW5kZXhPZih2YWwpID49IDApIHtcbiAgICAgICAgICByZXN1bHQgPSBnZXRFcnJvcihrZXksIHZhbCwgY3JpdGVyaWEpXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXN1bHRcbn1cbiIsIi8qXG4gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lXG4gKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGVcbiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uXG4gKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlXG4gKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlXG4gKiBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2VcbiAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZyxcbiAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuXG4gKiBcIkFTIElTXCIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWVxuICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlXG4gKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zXG4gKiB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldFZpZXdwb3J0IChhcHAsIGNvbmZpZ3MgPSB7fSkge1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAnZGV2ZWxvcG1lbnQnKSB7XG4gICAgY29uc29sZS5kZWJ1ZyhgW0pTIEZyYW1ld29ya10gU2V0IHZpZXdwb3J0ICh3aWR0aDogJHtjb25maWdzLndpZHRofSkgZm9yIGFwcCMke2FwcC5pZH0uYClcbiAgICB2YWxpZGF0ZVZpZXdwb3J0KGNvbmZpZ3MpXG4gIH1cblxuICAvLyBTZW5kIHZpZXdwb3J0IGNvbmZpZ3MgdG8gbmF0aXZlXG4gIGlmIChhcHAgJiYgYXBwLmNhbGxUYXNrcykge1xuICAgIHJldHVybiBhcHAuY2FsbFRhc2tzKFt7XG4gICAgICBtb2R1bGU6ICdtZXRhJyxcbiAgICAgIG1ldGhvZDogJ3NldFZpZXdwb3J0JyxcbiAgICAgIGFyZ3M6IFtjb25maWdzXVxuICAgIH1dKVxuICB9XG5cbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgZWxzZSBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICdkZXZlbG9wbWVudCcpIHtcbiAgICBjb25zb2xlLndhcm4oYFtKUyBGcmFtZXdvcmtdIENhbid0IGZpbmQgXCJjYWxsVGFza3NcIiBtZXRob2Qgb24gY3VycmVudCBhcHAuYClcbiAgfVxufVxuXG4vKipcbiAqIFZhbGlkYXRlIHRoZSB2aWV3cG9ydCBjb25maWcuXG4gKiBAcGFyYW0ge09iamVjdH0gY29uZmlnc1xuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVWaWV3cG9ydCAoY29uZmlncyA9IHt9KSB7XG4gIGNvbnN0IHsgd2lkdGggfSA9IGNvbmZpZ3NcbiAgaWYgKHdpZHRoKSB7XG4gICAgaWYgKHR5cGVvZiB3aWR0aCAhPT0gJ251bWJlcicgJiYgd2lkdGggIT09ICdkZXZpY2Utd2lkdGgnKSB7XG4gICAgICBjb25zb2xlLndhcm4oYFtKUyBGcmFtZXdvcmtdIE5vdCBzdXBwb3J0IHRvIHVzZSAke3dpZHRofSBhcyB2aWV3cG9ydCB3aWR0aC5gKVxuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICAgIHJldHVybiB0cnVlXG4gIH1cbiAgY29uc29sZS53YXJuKCdbSlMgRnJhbWV3b3JrXSB0aGUgdmlld3BvcnQgY29uZmlnIHNob3VsZCBjb250YWluIHRoZSBcIndpZHRoXCIgcHJvcGVydHkuJylcbiAgcmV0dXJuIGZhbHNlXG59XG4iLCIvKlxuICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZVxuICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlXG4gKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvblxuICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZVxuICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZVxuICogXCJMaWNlbnNlXCIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlXG4gKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsXG4gKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhblxuICogXCJBUyBJU1wiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTllcbiAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZVxuICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9uc1xuICogdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbmltcG9ydCBzZW12ZXIgZnJvbSAnc2VtdmVyJ1xuaW1wb3J0IFZtIGZyb20gJy4uLy4uL3ZtL2luZGV4J1xuaW1wb3J0ICogYXMgZG93bmdyYWRlIGZyb20gJy4uL2Rvd25ncmFkZSdcbmltcG9ydCB7IHNldFZpZXdwb3J0IH0gZnJvbSAnLi4vdmlld3BvcnQnXG5pbXBvcnQge1xuICByZXF1aXJlQ3VzdG9tQ29tcG9uZW50XG59IGZyb20gJy4uL3JlZ2lzdGVyJ1xuaW1wb3J0IHtcbiAgaXNQbGFpbk9iamVjdCxcbiAgaXNXZWV4Q29tcG9uZW50LFxuICBpc05wbU1vZHVsZSxcbiAgcmVtb3ZlV2VleFByZWZpeCxcbiAgcmVtb3ZlSlNTdXJmaXhcbn0gZnJvbSAnLi4vLi4vdXRpbC9pbmRleCdcblxuLyoqXG4gKiBib290c3RyYXAgYXBwIGZyb20gYSBjZXJ0YWluIGN1c3RvbSBjb21wb25lbnQgd2l0aCBjb25maWcgJiBkYXRhXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBib290c3RyYXAgKGFwcCwgbmFtZSwgY29uZmlnLCBkYXRhKSB7XG4gIGNvbnNvbGUuZGVidWcoYFtKUyBGcmFtZXdvcmtdIGJvb3RzdHJhcCBmb3IgJHtuYW1lfWApXG5cbiAgLy8gMS4gdmFsaWRhdGUgY3VzdG9tIGNvbXBvbmVudCBuYW1lIGZpcnN0XG4gIGxldCBjbGVhbk5hbWVcbiAgaWYgKGlzV2VleENvbXBvbmVudChuYW1lKSkge1xuICAgIGNsZWFuTmFtZSA9IHJlbW92ZVdlZXhQcmVmaXgobmFtZSlcbiAgfVxuICBlbHNlIGlmIChpc05wbU1vZHVsZShuYW1lKSkge1xuICAgIGNsZWFuTmFtZSA9IHJlbW92ZUpTU3VyZml4KG5hbWUpXG4gICAgLy8gY2hlY2sgaWYgZGVmaW5lIGJ5IG9sZCAnZGVmaW5lJyBtZXRob2RcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICBpZiAoIXJlcXVpcmVDdXN0b21Db21wb25lbnQoYXBwLCBjbGVhbk5hbWUpKSB7XG4gICAgICByZXR1cm4gbmV3IEVycm9yKGBJdCdzIG5vdCBhIGNvbXBvbmVudDogJHtuYW1lfWApXG4gICAgfVxuICB9XG4gIGVsc2Uge1xuICAgIHJldHVybiBuZXcgRXJyb3IoYFdyb25nIGNvbXBvbmVudCBuYW1lOiAke25hbWV9YClcbiAgfVxuXG4gIC8vIDIuIHZhbGlkYXRlIGNvbmZpZ3VyYXRpb25cbiAgY29uZmlnID0gaXNQbGFpbk9iamVjdChjb25maWcpID8gY29uZmlnIDoge31cbiAgLy8gMi4xIHRyYW5zZm9ybWVyIHZlcnNpb24gY2hlY2tcbiAgaWYgKHR5cGVvZiBjb25maWcudHJhbnNmb3JtZXJWZXJzaW9uID09PSAnc3RyaW5nJyAmJlxuICAgIHR5cGVvZiBnbG9iYWwudHJhbnNmb3JtZXJWZXJzaW9uID09PSAnc3RyaW5nJyAmJlxuICAgICFzZW12ZXIuc2F0aXNmaWVzKGNvbmZpZy50cmFuc2Zvcm1lclZlcnNpb24sXG4gICAgICBnbG9iYWwudHJhbnNmb3JtZXJWZXJzaW9uKSkge1xuICAgIHJldHVybiBuZXcgRXJyb3IoYEpTIEJ1bmRsZSB2ZXJzaW9uOiAke2NvbmZpZy50cmFuc2Zvcm1lclZlcnNpb259IGAgK1xuICAgICAgYG5vdCBjb21wYXRpYmxlIHdpdGggJHtnbG9iYWwudHJhbnNmb3JtZXJWZXJzaW9ufWApXG4gIH1cbiAgLy8gMi4yIGRvd25ncmFkZSB2ZXJzaW9uIGNoZWNrXG4gIGNvbnN0IGRvd25ncmFkZVJlc3VsdCA9IGRvd25ncmFkZS5jaGVjayhjb25maWcuZG93bmdyYWRlKVxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgaWYgKGRvd25ncmFkZVJlc3VsdC5pc0Rvd25ncmFkZSkge1xuICAgIGFwcC5jYWxsVGFza3MoW3tcbiAgICAgIG1vZHVsZTogJ2luc3RhbmNlV3JhcCcsXG4gICAgICBtZXRob2Q6ICdlcnJvcicsXG4gICAgICBhcmdzOiBbXG4gICAgICAgIGRvd25ncmFkZVJlc3VsdC5lcnJvclR5cGUsXG4gICAgICAgIGRvd25ncmFkZVJlc3VsdC5jb2RlLFxuICAgICAgICBkb3duZ3JhZGVSZXN1bHQuZXJyb3JNZXNzYWdlXG4gICAgICBdXG4gICAgfV0pXG4gICAgcmV0dXJuIG5ldyBFcnJvcihgRG93bmdyYWRlWyR7ZG93bmdyYWRlUmVzdWx0LmNvZGV9XTogJHtkb3duZ3JhZGVSZXN1bHQuZXJyb3JNZXNzYWdlfWApXG4gIH1cblxuICAvLyBzZXQgdmlld3BvcnRcbiAgaWYgKGNvbmZpZy52aWV3cG9ydCkge1xuICAgIHNldFZpZXdwb3J0KGFwcCwgY29uZmlnLnZpZXdwb3J0KVxuICB9XG5cbiAgLy8gMy4gY3JlYXRlIGEgbmV3IFZtIHdpdGggY3VzdG9tIGNvbXBvbmVudCBuYW1lIGFuZCBkYXRhXG4gIGFwcC52bSA9IG5ldyBWbShjbGVhbk5hbWUsIG51bGwsIHsgX2FwcDogYXBwIH0sIG51bGwsIGRhdGEpXG59XG4iLCIvKlxuICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZVxuICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlXG4gKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvblxuICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZVxuICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZVxuICogXCJMaWNlbnNlXCIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlXG4gKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsXG4gKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhblxuICogXCJBUyBJU1wiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTllcbiAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZVxuICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9uc1xuICogdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbmltcG9ydCB7XG4gIGlzV2VleENvbXBvbmVudCxcbiAgaXNXZWV4TW9kdWxlLFxuICBpc05vcm1hbE1vZHVsZSxcbiAgaXNOcG1Nb2R1bGUsXG4gIHJlbW92ZVdlZXhQcmVmaXgsXG4gIHJlbW92ZUpTU3VyZml4XG59IGZyb20gJy4uLy4uL3V0aWwvaW5kZXgnXG5pbXBvcnQge1xuICByZWdpc3RlckN1c3RvbUNvbXBvbmVudCxcbiAgcmVxdWlyZUN1c3RvbUNvbXBvbmVudCxcbiAgaW5pdE1vZHVsZXNcbn0gZnJvbSAnLi4vcmVnaXN0ZXInXG5cbi8qKlxuICogZGVmaW5lKG5hbWUsIGZhY3RvcnkpIGZvciBwcmltYXJ5IHVzYWdlXG4gKiBvclxuICogZGVmaW5lKG5hbWUsIGRlcHMsIGZhY3RvcnkpIGZvciBjb21wYXRpYmlsaXR5XG4gKiBOb3RpY2U6IERPIE5PVCB1c2UgZnVuY3Rpb24gZGVmaW5lKCkge30sXG4gKiBpdCB3aWxsIGNhdXNlIGVycm9yIGFmdGVyIGJ1aWxkZWQgYnkgd2VicGFja1xuICovXG5leHBvcnQgY29uc3QgZGVmaW5lRm4gPSBmdW5jdGlvbiAoYXBwLCBuYW1lLCAuLi5hcmdzKSB7XG4gIGNvbnNvbGUuZGVidWcoYFtKUyBGcmFtZXdvcmtdIGRlZmluZSBhIGNvbXBvbmVudCAke25hbWV9YClcblxuICAvLyBhZGFwdCBhcmdzOlxuICAvLyAxLiBuYW1lLCBkZXBzW10sIGZhY3RvcnkoKVxuICAvLyAyLiBuYW1lLCBmYWN0b3J5KClcbiAgLy8gMy4gbmFtZSwgZGVmaW5pdGlvbnt9XG4gIGxldCBmYWN0b3J5LCBkZWZpbml0aW9uXG4gIGlmIChhcmdzLmxlbmd0aCA+IDEpIHtcbiAgICBkZWZpbml0aW9uID0gYXJnc1sxXVxuICB9XG4gIGVsc2Uge1xuICAgIGRlZmluaXRpb24gPSBhcmdzWzBdXG4gIH1cbiAgaWYgKHR5cGVvZiBkZWZpbml0aW9uID09PSAnZnVuY3Rpb24nKSB7XG4gICAgZmFjdG9yeSA9IGRlZmluaXRpb25cbiAgICBkZWZpbml0aW9uID0gbnVsbFxuICB9XG5cbiAgLy8gcmVzb2x2ZSBkZWZpbml0aW9uIGZyb20gZmFjdG9yeVxuICBpZiAoZmFjdG9yeSkge1xuICAgIGNvbnN0IHIgPSAobmFtZSkgPT4ge1xuICAgICAgaWYgKGlzV2VleENvbXBvbmVudChuYW1lKSkge1xuICAgICAgICBjb25zdCBjbGVhbk5hbWUgPSByZW1vdmVXZWV4UHJlZml4KG5hbWUpXG4gICAgICAgIHJldHVybiByZXF1aXJlQ3VzdG9tQ29tcG9uZW50KGFwcCwgY2xlYW5OYW1lKVxuICAgICAgfVxuICAgICAgaWYgKGlzV2VleE1vZHVsZShuYW1lKSkge1xuICAgICAgICBjb25zdCBjbGVhbk5hbWUgPSByZW1vdmVXZWV4UHJlZml4KG5hbWUpXG4gICAgICAgIHJldHVybiBhcHAucmVxdWlyZU1vZHVsZShjbGVhbk5hbWUpXG4gICAgICB9XG4gICAgICBpZiAoaXNOb3JtYWxNb2R1bGUobmFtZSkgfHwgaXNOcG1Nb2R1bGUobmFtZSkpIHtcbiAgICAgICAgY29uc3QgY2xlYW5OYW1lID0gcmVtb3ZlSlNTdXJmaXgobmFtZSlcbiAgICAgICAgcmV0dXJuIGFwcC5jb21tb25Nb2R1bGVzW2NsZWFuTmFtZV1cbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgbSA9IHsgZXhwb3J0czoge319XG4gICAgZmFjdG9yeShyLCBtLmV4cG9ydHMsIG0pXG4gICAgZGVmaW5pdGlvbiA9IG0uZXhwb3J0c1xuICB9XG5cbiAgLy8gYXBwbHkgZGVmaW5pdGlvblxuICBpZiAoaXNXZWV4Q29tcG9uZW50KG5hbWUpKSB7XG4gICAgY29uc3QgY2xlYW5OYW1lID0gcmVtb3ZlV2VleFByZWZpeChuYW1lKVxuICAgIHJlZ2lzdGVyQ3VzdG9tQ29tcG9uZW50KGFwcCwgY2xlYW5OYW1lLCBkZWZpbml0aW9uKVxuICB9XG4gIGVsc2UgaWYgKGlzV2VleE1vZHVsZShuYW1lKSkge1xuICAgIGNvbnN0IGNsZWFuTmFtZSA9IHJlbW92ZVdlZXhQcmVmaXgobmFtZSlcbiAgICBpbml0TW9kdWxlcyh7IFtjbGVhbk5hbWVdOiBkZWZpbml0aW9uIH0pXG4gIH1cbiAgZWxzZSBpZiAoaXNOb3JtYWxNb2R1bGUobmFtZSkpIHtcbiAgICBjb25zdCBjbGVhbk5hbWUgPSByZW1vdmVKU1N1cmZpeChuYW1lKVxuICAgIGFwcC5jb21tb25Nb2R1bGVzW2NsZWFuTmFtZV0gPSBkZWZpbml0aW9uXG4gIH1cbiAgZWxzZSBpZiAoaXNOcG1Nb2R1bGUobmFtZSkpIHtcbiAgICBjb25zdCBjbGVhbk5hbWUgPSByZW1vdmVKU1N1cmZpeChuYW1lKVxuICAgIGlmIChkZWZpbml0aW9uLnRlbXBsYXRlIHx8XG4gICAgICAgIGRlZmluaXRpb24uc3R5bGUgfHxcbiAgICAgICAgZGVmaW5pdGlvbi5tZXRob2RzKSB7XG4gICAgICAvLyBkb3duZ3JhZGUgdG8gb2xkIGRlZmluZSBtZXRob2QgKGRlZmluZSgnY29tcG9uZW50TmFtZScsIGZhY3RvcnkpKVxuICAgICAgLy8gdGhlIGV4cG9ydHMgY29udGFpbiBvbmUga2V5IG9mIHRlbXBsYXRlLCBzdHlsZSBvciBtZXRob2RzXG4gICAgICAvLyBidXQgaXQgaGFzIHJpc2shISFcbiAgICAgIHJlZ2lzdGVyQ3VzdG9tQ29tcG9uZW50KGFwcCwgY2xlYW5OYW1lLCBkZWZpbml0aW9uKVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGFwcC5jb21tb25Nb2R1bGVzW2NsZWFuTmFtZV0gPSBkZWZpbml0aW9uXG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQGRlcHJlY2F0ZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyIChhcHAsIHR5cGUsIG9wdGlvbnMpIHtcbiAgY29uc29sZS53YXJuKCdbSlMgRnJhbWV3b3JrXSBSZWdpc3RlciBpcyBkZXByZWNhdGVkLCBwbGVhc2UgaW5zdGFsbCBsYXN0ZXN0IHRyYW5zZm9ybWVyLicpXG4gIHJlZ2lzdGVyQ3VzdG9tQ29tcG9uZW50KGFwcCwgdHlwZSwgb3B0aW9ucylcbn1cbiIsIi8qXG4gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lXG4gKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGVcbiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uXG4gKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlXG4gKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlXG4gKiBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2VcbiAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZyxcbiAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuXG4gKiBcIkFTIElTXCIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWVxuICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlXG4gKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zXG4gKiB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuLyoqXG4gKiBAZmlsZU92ZXJ2aWV3XG4gKiBhcGkgdGhhdCBpbnZva2VkIGJ5IGpzIGJ1bmRsZSBjb2RlXG4gKlxuICogLSBkZWZpbmUobmFtZSwgZmFjdG9yeSk6IGRlZmluZSBhIG5ldyBjb21wb3NlZCBjb21wb25lbnQgdHlwZVxuICogLSBib290c3RyYXAodHlwZSwgY29uZmlnLCBkYXRhKTogcmVxdWlyZSBhIGNlcnRhaW4gdHlwZSAmXG4gKiAgICAgICAgIHJlbmRlciB3aXRoIChvcHRpb25hbCkgZGF0YVxuICpcbiAqIGRlcHJlY2F0ZWQ6XG4gKiAtIHJlZ2lzdGVyKHR5cGUsIG9wdGlvbnMpOiByZWdpc3RlciBhIG5ldyBjb21wb3NlZCBjb21wb25lbnQgdHlwZVxuICogLSByZW5kZXIodHlwZSwgZGF0YSk6IHJlbmRlciBieSBhIGNlcnRhaW4gdHlwZSB3aXRoIChvcHRpb25hbCkgZGF0YVxuICogLSByZXF1aXJlKHR5cGUpKGRhdGEpOiByZXF1aXJlIGEgdHlwZSB0aGVuIHJlbmRlciB3aXRoIGRhdGFcbiAqL1xuXG5leHBvcnQgeyBib290c3RyYXAgfSBmcm9tICcuL2Jvb3RzdHJhcCdcbmV4cG9ydCB7IGRlZmluZUZuLCByZWdpc3RlciB9IGZyb20gJy4vZGVmaW5lJ1xuIiwiLypcbiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmVcbiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZVxuICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb25cbiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGVcbiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGVcbiAqIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZVxuICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLFxuICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW5cbiAqIFwiQVMgSVNcIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXG4gKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGVcbiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnNcbiAqIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG4vKipcbiAqIEBmaWxlT3ZlcnZpZXdcbiAqIGluc3RhbmNlIGNvbnRyb2xzIGZyb20gbmF0aXZlXG4gKlxuICogLSBmaXJlIGV2ZW50XG4gKiAtIGNhbGxiYWNrXG4gKiAtIHJlZnJlc2hcbiAqIC0gZGVzdHJveVxuICpcbiAqIGNvcnJlc3BvbmRlZCB3aXRoIHRoZSBBUEkgb2YgaW5zdGFuY2UgbWFuYWdlciAoZnJhbWV3b3JrLmpzKVxuICovXG5pbXBvcnQgeyBleHRlbmQsIHR5cG9mIH0gZnJvbSAnLi4vLi4vdXRpbC9pbmRleCdcblxuLyoqXG4gKiBSZWZyZXNoIGFuIGFwcCB3aXRoIGRhdGEgdG8gaXRzIHJvb3QgY29tcG9uZW50IG9wdGlvbnMuXG4gKiBAcGFyYW0gIHtvYmplY3R9IGFwcFxuICogQHBhcmFtICB7YW55fSAgICBkYXRhXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWZyZXNoIChhcHAsIGRhdGEpIHtcbiAgY29uc29sZS5kZWJ1ZyhgW0pTIEZyYW1ld29ya10gUmVmcmVzaCB3aXRoYCwgZGF0YSxcbiAgICAgICAgICAgIGBpbiBpbnN0YW5jZVske2FwcC5pZH1dYClcbiAgY29uc3Qgdm0gPSBhcHAudm1cbiAgaWYgKHZtICYmIGRhdGEpIHtcbiAgICBpZiAodHlwZW9mIHZtLnJlZnJlc2hEYXRhID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB2bS5yZWZyZXNoRGF0YShkYXRhKVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGV4dGVuZCh2bSwgZGF0YSlcbiAgICB9XG4gICAgYXBwLmRpZmZlci5mbHVzaCgpXG4gICAgYXBwLmRvYy50YXNrQ2VudGVyLnNlbmQoJ2RvbScsIHsgYWN0aW9uOiAncmVmcmVzaEZpbmlzaCcgfSwgW10pXG4gICAgcmV0dXJuXG4gIH1cbiAgcmV0dXJuIG5ldyBFcnJvcihgaW52YWxpZCBkYXRhIFwiJHtkYXRhfVwiYClcbn1cblxuLyoqXG4gKiBEZXN0cm95IGFuIGFwcC5cbiAqIEBwYXJhbSAge29iamVjdH0gYXBwXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZXN0cm95IChhcHApIHtcbiAgY29uc29sZS5kZWJ1ZyhgW0pTIEZyYW1ld29ya10gRGVzdG9yeSBhbiBpbnN0YW5jZSgke2FwcC5pZH0pYClcblxuICBpZiAoYXBwLnZtKSB7XG4gICAgZGVzdHJveVZtKGFwcC52bSlcbiAgfVxuXG4gIGFwcC5pZCA9ICcnXG4gIGFwcC5vcHRpb25zID0gbnVsbFxuICBhcHAuYmxvY2tzID0gbnVsbFxuICBhcHAudm0gPSBudWxsXG4gIGFwcC5kb2MudGFza0NlbnRlci5kZXN0cm95Q2FsbGJhY2soKVxuICBhcHAuZG9jLmRlc3Ryb3koKVxuICBhcHAuZG9jID0gbnVsbFxuICBhcHAuY3VzdG9tQ29tcG9uZW50TWFwID0gbnVsbFxuICBhcHAuY29tbW9uTW9kdWxlcyA9IG51bGxcbn1cblxuLyoqXG4gKiBEZXN0cm95IGFuIFZtLlxuICogQHBhcmFtIHtvYmplY3R9IHZtXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZXN0cm95Vm0gKHZtKSB7XG4gIGRlbGV0ZSB2bS5fYXBwXG4gIGRlbGV0ZSB2bS5fY29tcHV0ZWRcbiAgZGVsZXRlIHZtLl9jc3NcbiAgZGVsZXRlIHZtLl9kYXRhXG4gIGRlbGV0ZSB2bS5faWRzXG4gIGRlbGV0ZSB2bS5fbWV0aG9kc1xuICBkZWxldGUgdm0uX29wdGlvbnNcbiAgZGVsZXRlIHZtLl9wYXJlbnRcbiAgZGVsZXRlIHZtLl9wYXJlbnRFbFxuICBkZWxldGUgdm0uX3Jvb3RFbFxuXG4gIC8vIHJlbW92ZSBhbGwgd2F0Y2hlcnNcbiAgaWYgKHZtLl93YXRjaGVycykge1xuICAgIGxldCB3YXRjaGVyQ291bnQgPSB2bS5fd2F0Y2hlcnMubGVuZ3RoXG4gICAgd2hpbGUgKHdhdGNoZXJDb3VudC0tKSB7XG4gICAgICB2bS5fd2F0Y2hlcnNbd2F0Y2hlckNvdW50XS50ZWFyZG93bigpXG4gICAgfVxuICAgIGRlbGV0ZSB2bS5fd2F0Y2hlcnNcbiAgfVxuXG4gIC8vIGRlc3Ryb3kgY2hpbGQgdm1zIHJlY3Vyc2l2ZWx5XG4gIGlmICh2bS5fY2hpbGRyZW5WbXMpIHtcbiAgICBsZXQgdm1Db3VudCA9IHZtLl9jaGlsZHJlblZtcy5sZW5ndGhcbiAgICB3aGlsZSAodm1Db3VudC0tKSB7XG4gICAgICBkZXN0cm95Vm0odm0uX2NoaWxkcmVuVm1zW3ZtQ291bnRdKVxuICAgIH1cbiAgICBkZWxldGUgdm0uX2NoaWxkcmVuVm1zXG4gIH1cblxuICBjb25zb2xlLmRlYnVnKGBbSlMgRnJhbWV3b3JrXSBcImRlc3Ryb3llZFwiIGxpZmVjeWNsZSBpbiBWbSgke3ZtLl90eXBlfSlgKVxuICB2bS4kZW1pdCgnaG9vazpkZXN0cm95ZWQnKVxuXG4gIGRlbGV0ZSB2bS5fdHlwZVxuICBkZWxldGUgdm0uX3ZtRXZlbnRzXG59XG5cbi8qKlxuICogR2V0IGEgSlNPTiBvYmplY3QgdG8gZGVzY3JpYmUgdGhlIGRvY3VtZW50IGJvZHkuXG4gKiBAcGFyYW0gIHtvYmplY3R9IGFwcFxuICogQHJldHVybiB7b2JqZWN0fVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Um9vdEVsZW1lbnQgKGFwcCkge1xuICBjb25zdCBkb2MgPSBhcHAuZG9jIHx8IHt9XG4gIGNvbnN0IGJvZHkgPSBkb2MuYm9keSB8fCB7fVxuICByZXR1cm4gYm9keS50b0pTT04gPyBib2R5LnRvSlNPTigpIDoge31cbn1cblxuLyoqXG4gKiBGaXJlIGFuIGV2ZW50IGZyb20gcmVuZGVyZXIuIFRoZSBldmVudCBoYXMgdHlwZSwgYW4gZXZlbnQgb2JqZWN0IGFuZCBhblxuICogZWxlbWVudCByZWYuIElmIHRoZSBldmVudCBjb21lcyB3aXRoIHNvbWUgdmlydHVhbC1ET00gY2hhbmdlcywgaXQgc2hvdWxkXG4gKiBoYXZlIG9uZSBtb3JlIHBhcmFtZXRlciB0byBkZXNjcmliZSB0aGUgY2hhbmdlcy5cbiAqIEBwYXJhbSAge29iamVjdH0gYXBwXG4gKiBAcGFyYW0gIHtzdHJpbmd9IHJlZlxuICogQHBhcmFtICB7dHlwZX0gICB0eXBlXG4gKiBAcGFyYW0gIHtvYmplY3R9IGVcbiAqIEBwYXJhbSAge29iamVjdH0gZG9tQ2hhbmdlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZmlyZUV2ZW50IChhcHAsIHJlZiwgdHlwZSwgZSwgZG9tQ2hhbmdlcykge1xuICBjb25zb2xlLmRlYnVnKGBbSlMgRnJhbWV3b3JrXSBGaXJlIGEgXCIke3R5cGV9XCIgZXZlbnQgb24gYW4gZWxlbWVudCgke3JlZn0pIGluIGluc3RhbmNlKCR7YXBwLmlkfSlgKVxuICBpZiAoQXJyYXkuaXNBcnJheShyZWYpKSB7XG4gICAgcmVmLnNvbWUoKHJlZikgPT4ge1xuICAgICAgcmV0dXJuIGZpcmVFdmVudChhcHAsIHJlZiwgdHlwZSwgZSkgIT09IGZhbHNlXG4gICAgfSlcbiAgICByZXR1cm5cbiAgfVxuICBjb25zdCBlbCA9IGFwcC5kb2MuZ2V0UmVmKHJlZilcbiAgaWYgKGVsKSB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXBwLmRvYy5maXJlRXZlbnQoZWwsIHR5cGUsIGUsIGRvbUNoYW5nZXMpXG4gICAgYXBwLmRpZmZlci5mbHVzaCgpXG4gICAgYXBwLmRvYy50YXNrQ2VudGVyLnNlbmQoJ2RvbScsIHsgYWN0aW9uOiAndXBkYXRlRmluaXNoJyB9LCBbXSlcbiAgICByZXR1cm4gcmVzdWx0XG4gIH1cbiAgcmV0dXJuIG5ldyBFcnJvcihgaW52YWxpZCBlbGVtZW50IHJlZmVyZW5jZSBcIiR7cmVmfVwiYClcbn1cblxuLyoqXG4gKiBNYWtlIGEgY2FsbGJhY2sgZm9yIGEgY2VydGFpbiBhcHAuXG4gKiBAcGFyYW0gIHtvYmplY3R9ICAgYXBwXG4gKiBAcGFyYW0gIHtudW1iZXJ9ICAgY2FsbGJhY2tJZFxuICogQHBhcmFtICB7YW55fSAgICAgIGRhdGFcbiAqIEBwYXJhbSAge2Jvb2xlYW59ICBpZktlZXBBbGl2ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gY2FsbGJhY2sgKGFwcCwgY2FsbGJhY2tJZCwgZGF0YSwgaWZLZWVwQWxpdmUpIHtcbiAgY29uc29sZS5kZWJ1ZyhgW0pTIEZyYW1ld29ya10gSW52b2tlIGEgY2FsbGJhY2soJHtjYWxsYmFja0lkfSkgd2l0aGAsIGRhdGEsXG4gICAgICAgICAgICBgaW4gaW5zdGFuY2UoJHthcHAuaWR9KWApXG4gIGNvbnN0IHJlc3VsdCA9IGFwcC5kb2MudGFza0NlbnRlci5jYWxsYmFjayhjYWxsYmFja0lkLCBkYXRhLCBpZktlZXBBbGl2ZSlcbiAgdXBkYXRlQWN0aW9ucyhhcHApXG4gIGFwcC5kb2MudGFza0NlbnRlci5zZW5kKCdkb20nLCB7IGFjdGlvbjogJ3VwZGF0ZUZpbmlzaCcgfSwgW10pXG4gIHJldHVybiByZXN1bHRcbn1cblxuLyoqXG4gKiBDb2xsZWN0IGFsbCB2aXJ0dWFsLURPTSBtdXRhdGlvbnMgdG9nZXRoZXIgYW5kIHNlbmQgdGhlbSB0byByZW5kZXJlci5cbiAqIEBwYXJhbSAge29iamVjdH0gYXBwXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVBY3Rpb25zIChhcHApIHtcbiAgYXBwLmRpZmZlci5mbHVzaCgpXG59XG5cbi8qKlxuICogQ2FsbCBhbGwgdGFza3MgZnJvbSBhbiBhcHAgdG8gcmVuZGVyZXIgKG5hdGl2ZSkuXG4gKiBAcGFyYW0gIHtvYmplY3R9IGFwcFxuICogQHBhcmFtICB7YXJyYXl9ICB0YXNrc1xuICovXG5leHBvcnQgZnVuY3Rpb24gY2FsbFRhc2tzIChhcHAsIHRhc2tzKSB7XG4gIGxldCByZXN1bHRcblxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICBpZiAodHlwb2YodGFza3MpICE9PSAnYXJyYXknKSB7XG4gICAgdGFza3MgPSBbdGFza3NdXG4gIH1cblxuICB0YXNrcy5mb3JFYWNoKHRhc2sgPT4ge1xuICAgIHJlc3VsdCA9IGFwcC5kb2MudGFza0NlbnRlci5zZW5kKFxuICAgICAgJ21vZHVsZScsXG4gICAgICB7XG4gICAgICAgIG1vZHVsZTogdGFzay5tb2R1bGUsXG4gICAgICAgIG1ldGhvZDogdGFzay5tZXRob2RcbiAgICAgIH0sXG4gICAgICB0YXNrLmFyZ3NcbiAgICApXG4gIH0pXG5cbiAgcmV0dXJuIHJlc3VsdFxufVxuIiwiLypcbiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmVcbiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZVxuICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb25cbiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGVcbiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGVcbiAqIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZVxuICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLFxuICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW5cbiAqIFwiQVMgSVNcIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXG4gKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGVcbiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnNcbiAqIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG4vKipcbiAqIEBmaWxlT3ZlcnZpZXdcbiAqIGluc3RhbmNlIGNvbnRyb2xzIGZyb20gbmF0aXZlXG4gKlxuICogLSBpbml0IGJ1bmRsZVxuICpcbiAqIGNvcnJlc3BvbmRlZCB3aXRoIHRoZSBBUEkgb2YgaW5zdGFuY2UgbWFuYWdlciAoZnJhbWV3b3JrLmpzKVxuICovXG5cbmltcG9ydCBWbSBmcm9tICcuLi8uLi92bS9pbmRleCdcbmltcG9ydCB7IHJlbW92ZVdlZXhQcmVmaXggfSBmcm9tICcuLi8uLi91dGlsL2luZGV4J1xuaW1wb3J0IHtcbiAgZGVmaW5lRm4sXG4gIGJvb3RzdHJhcCxcbiAgcmVnaXN0ZXJcbn0gZnJvbSAnLi4vYnVuZGxlL2luZGV4J1xuaW1wb3J0IHsgdXBkYXRlQWN0aW9ucyB9IGZyb20gJy4vbWlzYydcblxuLyoqXG4gKiBJbml0IGFuIGFwcCBieSBydW4gY29kZSB3aXRnaCBkYXRhXG4gKiBAcGFyYW0gIHtvYmplY3R9IGFwcFxuICogQHBhcmFtICB7c3RyaW5nfSBjb2RlXG4gKiBAcGFyYW0gIHtvYmplY3R9IGRhdGFcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluaXQgKGFwcCwgY29kZSwgZGF0YSwgc2VydmljZXMpIHtcbiAgY29uc29sZS5kZWJ1ZygnW0pTIEZyYW1ld29ya10gSW50aWFsaXplIGFuIGluc3RhbmNlIHdpdGg6XFxuJywgZGF0YSlcbiAgbGV0IHJlc3VsdFxuXG4gIC8vIHByZXBhcmUgYXBwIGVudiBtZXRob2RzXG4gIGNvbnN0IGJ1bmRsZURlZmluZSA9ICguLi5hcmdzKSA9PiBkZWZpbmVGbihhcHAsIC4uLmFyZ3MpXG4gIGNvbnN0IGJ1bmRsZUJvb3RzdHJhcCA9IChuYW1lLCBjb25maWcsIF9kYXRhKSA9PiB7XG4gICAgcmVzdWx0ID0gYm9vdHN0cmFwKGFwcCwgbmFtZSwgY29uZmlnLCBfZGF0YSB8fCBkYXRhKVxuICAgIHVwZGF0ZUFjdGlvbnMoYXBwKVxuICAgIGFwcC5kb2MubGlzdGVuZXIuY3JlYXRlRmluaXNoKClcbiAgICBjb25zb2xlLmRlYnVnKGBbSlMgRnJhbWV3b3JrXSBBZnRlciBpbnRpYWxpemVkIGFuIGluc3RhbmNlKCR7YXBwLmlkfSlgKVxuICB9XG4gIGNvbnN0IGJ1bmRsZVZtID0gVm1cbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgY29uc3QgYnVuZGxlUmVnaXN0ZXIgPSAoLi4uYXJncykgPT4gcmVnaXN0ZXIoYXBwLCAuLi5hcmdzKVxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICBjb25zdCBidW5kbGVSZW5kZXIgPSAobmFtZSwgX2RhdGEpID0+IHtcbiAgICByZXN1bHQgPSBib290c3RyYXAoYXBwLCBuYW1lLCB7fSwgX2RhdGEpXG4gIH1cbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgY29uc3QgYnVuZGxlUmVxdWlyZSA9IG5hbWUgPT4gX2RhdGEgPT4ge1xuICAgIHJlc3VsdCA9IGJvb3RzdHJhcChhcHAsIG5hbWUsIHt9LCBfZGF0YSlcbiAgfVxuICBjb25zdCBidW5kbGVEb2N1bWVudCA9IGFwcC5kb2NcbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgY29uc3QgYnVuZGxlUmVxdWlyZU1vZHVsZSA9IG5hbWUgPT4gYXBwLnJlcXVpcmVNb2R1bGUocmVtb3ZlV2VleFByZWZpeChuYW1lKSlcblxuICBjb25zdCB3ZWV4R2xvYmFsT2JqZWN0ID0ge1xuICAgIGNvbmZpZzogYXBwLm9wdGlvbnMsXG4gICAgZGVmaW5lOiBidW5kbGVEZWZpbmUsXG4gICAgYm9vdHN0cmFwOiBidW5kbGVCb290c3RyYXAsXG4gICAgcmVxdWlyZU1vZHVsZTogYnVuZGxlUmVxdWlyZU1vZHVsZSxcbiAgICBkb2N1bWVudDogYnVuZGxlRG9jdW1lbnQsXG4gICAgVm06IGJ1bmRsZVZtXG4gIH1cblxuICBPYmplY3QuZnJlZXplKHdlZXhHbG9iYWxPYmplY3QpXG5cbiAgLy8gcHJlcGFyZSBjb2RlXG4gIGxldCBmdW5jdGlvbkJvZHlcbiAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gIGlmICh0eXBlb2YgY29kZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIC8vIGBmdW5jdGlvbiAoKSB7Li4ufWAgLT4gYHsuLi59YFxuICAgIC8vIG5vdCB2ZXJ5IHN0cmljdFxuICAgIGZ1bmN0aW9uQm9keSA9IGNvZGUudG9TdHJpbmcoKS5zdWJzdHIoMTIpXG4gIH1cbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgZWxzZSBpZiAoY29kZSkge1xuICAgIGZ1bmN0aW9uQm9keSA9IGNvZGUudG9TdHJpbmcoKVxuICB9XG4gIC8vIHdyYXAgSUZGRSBhbmQgdXNlIHN0cmljdCBtb2RlXG4gIGZ1bmN0aW9uQm9keSA9IGAoZnVuY3Rpb24oZ2xvYmFsKXtcXG5cXG5cInVzZSBzdHJpY3RcIjtcXG5cXG4gJHtmdW5jdGlvbkJvZHl9IFxcblxcbn0pKE9iamVjdC5jcmVhdGUodGhpcykpYFxuXG4gIC8vIHJ1biBjb2RlIGFuZCBnZXQgcmVzdWx0XG4gIGNvbnN0IHsgV1hFbnZpcm9ubWVudCB9ID0gZ2xvYmFsXG4gIGNvbnN0IHRpbWVyQVBJcyA9IHt9XG5cbiAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gIGlmIChXWEVudmlyb25tZW50ICYmIFdYRW52aXJvbm1lbnQucGxhdGZvcm0gIT09ICdXZWInKSB7XG4gICAgLy8gdGltZXIgQVBJcyBwb2x5ZmlsbCBpbiBuYXRpdmVcbiAgICBjb25zdCB0aW1lciA9IGFwcC5yZXF1aXJlTW9kdWxlKCd0aW1lcicpXG4gICAgT2JqZWN0LmFzc2lnbih0aW1lckFQSXMsIHtcbiAgICAgIHNldFRpbWVvdXQ6ICguLi5hcmdzKSA9PiB7XG4gICAgICAgIGNvbnN0IGhhbmRsZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgYXJnc1swXSguLi5hcmdzLnNsaWNlKDIpKVxuICAgICAgICB9XG4gICAgICAgIHRpbWVyLnNldFRpbWVvdXQoaGFuZGxlciwgYXJnc1sxXSlcbiAgICAgICAgcmV0dXJuIGFwcC5kb2MudGFza0NlbnRlci5jYWxsYmFja01hbmFnZXIubGFzdENhbGxiYWNrSWQudG9TdHJpbmcoKVxuICAgICAgfSxcbiAgICAgIHNldEludGVydmFsOiAoLi4uYXJncykgPT4ge1xuICAgICAgICBjb25zdCBoYW5kbGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGFyZ3NbMF0oLi4uYXJncy5zbGljZSgyKSlcbiAgICAgICAgfVxuICAgICAgICB0aW1lci5zZXRJbnRlcnZhbChoYW5kbGVyLCBhcmdzWzFdKVxuICAgICAgICByZXR1cm4gYXBwLmRvYy50YXNrQ2VudGVyLmNhbGxiYWNrTWFuYWdlci5sYXN0Q2FsbGJhY2tJZC50b1N0cmluZygpXG4gICAgICB9LFxuICAgICAgY2xlYXJUaW1lb3V0OiAobikgPT4ge1xuICAgICAgICB0aW1lci5jbGVhclRpbWVvdXQobilcbiAgICAgIH0sXG4gICAgICBjbGVhckludGVydmFsOiAobikgPT4ge1xuICAgICAgICB0aW1lci5jbGVhckludGVydmFsKG4pXG4gICAgICB9XG4gICAgfSlcbiAgfVxuICAvLyBydW4gY29kZSBhbmQgZ2V0IHJlc3VsdFxuICBjb25zdCBnbG9iYWxPYmplY3RzID0gT2JqZWN0LmFzc2lnbih7XG4gICAgZGVmaW5lOiBidW5kbGVEZWZpbmUsXG4gICAgcmVxdWlyZTogYnVuZGxlUmVxdWlyZSxcbiAgICBib290c3RyYXA6IGJ1bmRsZUJvb3RzdHJhcCxcbiAgICByZWdpc3RlcjogYnVuZGxlUmVnaXN0ZXIsXG4gICAgcmVuZGVyOiBidW5kbGVSZW5kZXIsXG4gICAgX193ZWV4X2RlZmluZV9fOiBidW5kbGVEZWZpbmUsIC8vIGFsaWFzIGZvciBkZWZpbmVcbiAgICBfX3dlZXhfYm9vdHN0cmFwX186IGJ1bmRsZUJvb3RzdHJhcCwgLy8gYWxpYXMgZm9yIGJvb3RzdHJhcFxuICAgIF9fd2VleF9kb2N1bWVudF9fOiBidW5kbGVEb2N1bWVudCxcbiAgICBfX3dlZXhfcmVxdWlyZV9fOiBidW5kbGVSZXF1aXJlTW9kdWxlLFxuICAgIF9fd2VleF92aWV3bW9kZWxfXzogYnVuZGxlVm0sXG4gICAgd2VleDogd2VleEdsb2JhbE9iamVjdFxuICB9LCB0aW1lckFQSXMsIHNlcnZpY2VzKVxuICBpZiAoIWNhbGxGdW5jdGlvbk5hdGl2ZShnbG9iYWxPYmplY3RzLCBmdW5jdGlvbkJvZHkpKSB7XG4gICAgLy8gSWYgZmFpbGVkIHRvIGNvbXBpbGUgZnVuY3Rpb25Cb2R5IG9uIG5hdGl2ZSBzaWRlLFxuICAgIC8vIGZhbGxiYWNrIHRvIGNhbGxGdW5jdGlvbi5cbiAgICBjYWxsRnVuY3Rpb24oZ2xvYmFsT2JqZWN0cywgZnVuY3Rpb25Cb2R5KVxuICB9XG5cbiAgcmV0dXJuIHJlc3VsdFxufVxuXG4vKipcbiAqIENhbGwgYSBuZXcgZnVuY3Rpb24gYm9keSB3aXRoIHNvbWUgZ2xvYmFsIG9iamVjdHMuXG4gKiBAcGFyYW0gIHtvYmplY3R9IGdsb2JhbE9iamVjdHNcbiAqIEBwYXJhbSAge3N0cmluZ30gY29kZVxuICogQHJldHVybiB7YW55fVxuICovXG5mdW5jdGlvbiBjYWxsRnVuY3Rpb24gKGdsb2JhbE9iamVjdHMsIGJvZHkpIHtcbiAgY29uc3QgZ2xvYmFsS2V5cyA9IFtdXG4gIGNvbnN0IGdsb2JhbFZhbHVlcyA9IFtdXG4gIGZvciAoY29uc3Qga2V5IGluIGdsb2JhbE9iamVjdHMpIHtcbiAgICBnbG9iYWxLZXlzLnB1c2goa2V5KVxuICAgIGdsb2JhbFZhbHVlcy5wdXNoKGdsb2JhbE9iamVjdHNba2V5XSlcbiAgfVxuICBnbG9iYWxLZXlzLnB1c2goYm9keSlcblxuICBjb25zdCByZXN1bHQgPSBuZXcgRnVuY3Rpb24oLi4uZ2xvYmFsS2V5cylcbiAgcmV0dXJuIHJlc3VsdCguLi5nbG9iYWxWYWx1ZXMpXG59XG5cbi8qKlxuICogQ2FsbCBhIG5ldyBmdW5jdGlvbiBnZW5lcmF0ZWQgb24gdGhlIFY4IG5hdGl2ZSBzaWRlLlxuICogQHBhcmFtICB7b2JqZWN0fSBnbG9iYWxPYmplY3RzXG4gKiBAcGFyYW0gIHtzdHJpbmd9IGJvZHlcbiAqIEByZXR1cm4ge2Jvb2xlYW59IHJldHVybiB0cnVlIGlmIG5vIGVycm9yIG9jY3VycmVkLlxuICovXG5mdW5jdGlvbiBjYWxsRnVuY3Rpb25OYXRpdmUgKGdsb2JhbE9iamVjdHMsIGJvZHkpIHtcbiAgaWYgKHR5cGVvZiBjb21waWxlQW5kUnVuQnVuZGxlICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICBsZXQgZm4gPSB2b2lkIDBcbiAgbGV0IGlzTmF0aXZlQ29tcGlsZU9rID0gZmFsc2VcbiAgbGV0IHNjcmlwdCA9ICcoZnVuY3Rpb24gKCdcbiAgY29uc3QgZ2xvYmFsS2V5cyA9IFtdXG4gIGNvbnN0IGdsb2JhbFZhbHVlcyA9IFtdXG4gIGZvciAoY29uc3Qga2V5IGluIGdsb2JhbE9iamVjdHMpIHtcbiAgICBnbG9iYWxLZXlzLnB1c2goa2V5KVxuICAgIGdsb2JhbFZhbHVlcy5wdXNoKGdsb2JhbE9iamVjdHNba2V5XSlcbiAgfVxuICBmb3IgKGxldCBpID0gMDsgaSA8IGdsb2JhbEtleXMubGVuZ3RoIC0gMTsgKytpKSB7XG4gICAgc2NyaXB0ICs9IGdsb2JhbEtleXNbaV1cbiAgICBzY3JpcHQgKz0gJywnXG4gIH1cbiAgc2NyaXB0ICs9IGdsb2JhbEtleXNbZ2xvYmFsS2V5cy5sZW5ndGggLSAxXVxuICBzY3JpcHQgKz0gJykgeydcbiAgc2NyaXB0ICs9IGJvZHlcbiAgc2NyaXB0ICs9ICd9ICknXG5cbiAgdHJ5IHtcbiAgICBjb25zdCB3ZWV4ID0gZ2xvYmFsT2JqZWN0cy53ZWV4IHx8IHt9XG4gICAgY29uc3QgY29uZmlnID0gd2VleC5jb25maWcgfHwge31cbiAgICBmbiA9IGNvbXBpbGVBbmRSdW5CdW5kbGUoc2NyaXB0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWcuYnVuZGxlVXJsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWcuYnVuZGxlRGlnZXN0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWcuY29kZUNhY2hlUGF0aClcbiAgICBpZiAoZm4gJiYgdHlwZW9mIGZuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBmbiguLi5nbG9iYWxWYWx1ZXMpXG4gICAgICBpc05hdGl2ZUNvbXBpbGVPayA9IHRydWVcbiAgICB9XG4gIH1cbiAgY2F0Y2ggKGUpIHtcbiAgICBjb25zb2xlLmVycm9yKGUpXG4gIH1cblxuICByZXR1cm4gaXNOYXRpdmVDb21waWxlT2tcbn1cbiIsIi8qXG4gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lXG4gKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGVcbiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uXG4gKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlXG4gKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlXG4gKiBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2VcbiAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZyxcbiAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuXG4gKiBcIkFTIElTXCIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWVxuICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlXG4gKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zXG4gKiB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuLyoqXG4gKiBAZmlsZU92ZXJ2aWV3XG4gKiBpbnN0YW5jZSBjb250cm9scyBmcm9tIG5hdGl2ZVxuICpcbiAqIC0gaW5pdCBidW5kbGVcbiAqIC0gZmlyZSBldmVudFxuICogLSBjYWxsYmFja1xuICogLSBkZXN0cm95XG4gKlxuICogY29ycmVzcG9uZGVkIHdpdGggdGhlIEFQSSBvZiBpbnN0YW5jZSBtYW5hZ2VyIChmcmFtZXdvcmsuanMpXG4gKi9cbmV4cG9ydCB7IGluaXQgfSBmcm9tICcuL2luaXQnXG5cbmV4cG9ydCB7XG4gIHJlZnJlc2gsXG4gIGRlc3Ryb3ksXG4gIGdldFJvb3RFbGVtZW50LFxuICBmaXJlRXZlbnQsXG4gIGNhbGxiYWNrLFxuICB1cGRhdGVBY3Rpb25zLFxuICBjYWxsVGFza3Ncbn0gZnJvbSAnLi9taXNjJ1xuIiwiLypcbiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmVcbiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZVxuICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb25cbiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGVcbiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGVcbiAqIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZVxuICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLFxuICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW5cbiAqIFwiQVMgSVNcIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXG4gKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGVcbiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnNcbiAqIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBEaWZmZXIge1xuICBjb25zdHJ1Y3RvciAoaWQpIHtcbiAgICB0aGlzLmlkID0gaWRcbiAgICB0aGlzLm1hcCA9IFtdXG4gICAgdGhpcy5ob29rcyA9IFtdXG4gIH1cbiAgaXNFbXB0eSAoKSB7XG4gICAgcmV0dXJuIHRoaXMubWFwLmxlbmd0aCA9PT0gMFxuICB9XG4gIGFwcGVuZCAodHlwZSwgZGVwdGgsIHJlZiwgaGFuZGxlcikge1xuICAgIGlmICghdGhpcy5oYXNUaW1lcikge1xuICAgICAgdGhpcy5oYXNUaW1lciA9IHRydWVcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLmhhc1RpbWVyID0gZmFsc2VcbiAgICAgICAgdGhpcy5mbHVzaCh0cnVlKVxuICAgICAgfSwgMClcbiAgICB9XG4gICAgY29uc3QgbWFwID0gdGhpcy5tYXBcbiAgICBpZiAoIW1hcFtkZXB0aF0pIHtcbiAgICAgIG1hcFtkZXB0aF0gPSB7fVxuICAgIH1cbiAgICBjb25zdCBncm91cCA9IG1hcFtkZXB0aF1cbiAgICBpZiAoIWdyb3VwW3R5cGVdKSB7XG4gICAgICBncm91cFt0eXBlXSA9IHt9XG4gICAgfVxuICAgIGlmICh0eXBlID09PSAnZWxlbWVudCcpIHtcbiAgICAgIGlmICghZ3JvdXBbdHlwZV1bcmVmXSkge1xuICAgICAgICBncm91cFt0eXBlXVtyZWZdID0gW11cbiAgICAgIH1cbiAgICAgIGdyb3VwW3R5cGVdW3JlZl0ucHVzaChoYW5kbGVyKVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGdyb3VwW3R5cGVdW3JlZl0gPSBoYW5kbGVyXG4gICAgfVxuICB9XG4gIGZsdXNoIChpc1RpbWVvdXQpIHtcbiAgICBjb25zdCBtYXAgPSB0aGlzLm1hcC5zbGljZSgpXG4gICAgdGhpcy5tYXAubGVuZ3RoID0gMFxuICAgIG1hcC5mb3JFYWNoKChncm91cCkgPT4ge1xuICAgICAgY2FsbFR5cGVNYXAoZ3JvdXAsICdyZXBlYXQnKVxuICAgICAgY2FsbFR5cGVNYXAoZ3JvdXAsICdzaG93bicpXG4gICAgICBjYWxsVHlwZUxpc3QoZ3JvdXAsICdlbGVtZW50JylcbiAgICB9KVxuXG4gICAgY29uc3QgaG9va3MgPSB0aGlzLmhvb2tzLnNsaWNlKClcbiAgICB0aGlzLmhvb2tzLmxlbmd0aCA9IDBcbiAgICBob29rcy5mb3JFYWNoKChmbikgPT4ge1xuICAgICAgZm4oKVxuICAgIH0pXG5cbiAgICBpZiAoIXRoaXMuaXNFbXB0eSgpKSB7XG4gICAgICB0aGlzLmZsdXNoKClcbiAgICB9XG4gIH1cbiAgdGhlbiAoZm4pIHtcbiAgICB0aGlzLmhvb2tzLnB1c2goZm4pXG4gIH1cbn1cblxuZnVuY3Rpb24gY2FsbFR5cGVNYXAgKGdyb3VwLCB0eXBlKSB7XG4gIGNvbnN0IG1hcCA9IGdyb3VwW3R5cGVdXG4gIGZvciAoY29uc3QgcmVmIGluIG1hcCkge1xuICAgIG1hcFtyZWZdKClcbiAgfVxufVxuXG5mdW5jdGlvbiBjYWxsVHlwZUxpc3QgKGdyb3VwLCB0eXBlKSB7XG4gIGNvbnN0IG1hcCA9IGdyb3VwW3R5cGVdXG4gIGZvciAoY29uc3QgcmVmIGluIG1hcCkge1xuICAgIGNvbnN0IGxpc3QgPSBtYXBbcmVmXVxuICAgIGxpc3QuZm9yRWFjaCgoaGFuZGxlcikgPT4geyBoYW5kbGVyKCkgfSlcbiAgfVxufVxuIiwiLypcbiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmVcbiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZVxuICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb25cbiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGVcbiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGVcbiAqIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZVxuICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLFxuICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW5cbiAqIFwiQVMgSVNcIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXG4gKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGVcbiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnNcbiAqIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG4vKipcbiAqIEBmaWxlT3ZlcnZpZXdcbiAqIFdlZXggQXBwIGNvbnN0cnVjdG9yICYgZGVmaW5pdGlvblxuICovXG5cbmltcG9ydCBEaWZmZXIgZnJvbSAnLi9kaWZmZXInXG5pbXBvcnQgcmVuZGVyZXIgZnJvbSAnLi4vY29uZmlnJ1xuXG4vKipcbiAqIEFwcCBjb25zdHJ1Y3RvciBmb3IgV2VleCBmcmFtZXdvcmsuXG4gKiBAcGFyYW0ge3N0cmluZ30gaWRcbiAqIEBwYXJhbSB7b2JqZWN0fSBvcHRpb25zXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEFwcCAoaWQsIG9wdGlvbnMpIHtcbiAgdGhpcy5pZCA9IGlkXG4gIHRoaXMub3B0aW9ucyA9IG9wdGlvbnMgfHwge31cbiAgdGhpcy52bSA9IG51bGxcbiAgdGhpcy5jdXN0b21Db21wb25lbnRNYXAgPSB7fVxuICB0aGlzLmNvbW1vbk1vZHVsZXMgPSB7fVxuXG4gIC8vIGRvY3VtZW50XG4gIHRoaXMuZG9jID0gbmV3IHJlbmRlcmVyLkRvY3VtZW50KFxuICAgIGlkLFxuICAgIHRoaXMub3B0aW9ucy5idW5kbGVVcmwsXG4gICAgbnVsbCxcbiAgICByZW5kZXJlci5MaXN0ZW5lclxuICApXG4gIHRoaXMuZGlmZmVyID0gbmV3IERpZmZlcihpZClcbn1cbiIsIi8qXG4gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lXG4gKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGVcbiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uXG4gKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlXG4gKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlXG4gKiBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2VcbiAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZyxcbiAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuXG4gKiBcIkFTIElTXCIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWVxuICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlXG4gKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zXG4gKiB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuLyoqXG4gKiBAZmlsZU92ZXJ2aWV3XG4gKiBXZWV4IGluc3RhbmNlIGNvbnN0cnVjdG9yICYgZGVmaW5pdGlvblxuICovXG5cbmltcG9ydCB7IHJlcXVpcmVNb2R1bGUgfSBmcm9tICcuL3JlZ2lzdGVyJ1xuaW1wb3J0IHsgdXBkYXRlQWN0aW9ucywgY2FsbFRhc2tzIH0gZnJvbSAnLi9jdHJsL2luZGV4J1xuaW1wb3J0IEFwcCBmcm9tICcuL2luc3RhbmNlJ1xuXG4vKipcbiAqIEBkZXByZWNhdGVkXG4gKi9cbkFwcC5wcm90b3R5cGUucmVxdWlyZU1vZHVsZSA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIHJldHVybiByZXF1aXJlTW9kdWxlKHRoaXMsIG5hbWUpXG59XG5cbi8qKlxuICogQGRlcHJlY2F0ZWRcbiAqL1xuQXBwLnByb3RvdHlwZS51cGRhdGVBY3Rpb25zID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdXBkYXRlQWN0aW9ucyh0aGlzKVxufVxuXG4vKipcbiAqIEBkZXByZWNhdGVkXG4gKi9cbkFwcC5wcm90b3R5cGUuY2FsbFRhc2tzID0gZnVuY3Rpb24gKHRhc2tzKSB7XG4gIHJldHVybiBjYWxsVGFza3ModGhpcywgdGFza3MpXG59XG5cbi8qKlxuICogUHJldmVudCBtb2RpZmljYXRpb24gb2YgQXBwIGFuZCBBcHAucHJvdG90eXBlXG4gKi9cbk9iamVjdC5mcmVlemUoQXBwKVxuT2JqZWN0LmZyZWV6ZShBcHAucHJvdG90eXBlKVxuXG5leHBvcnQgZGVmYXVsdCBBcHBcbiIsIi8qXG4gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lXG4gKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGVcbiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uXG4gKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlXG4gKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlXG4gKiBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2VcbiAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZyxcbiAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuXG4gKiBcIkFTIElTXCIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWVxuICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlXG4gKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zXG4gKiB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuZXhwb3J0IGNvbnN0IGluc3RhbmNlTWFwID0ge31cbiIsIi8qXG4gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lXG4gKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGVcbiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uXG4gKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlXG4gKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlXG4gKiBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2VcbiAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZyxcbiAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuXG4gKiBcIkFTIElTXCIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWVxuICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlXG4gKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zXG4gKiB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuaW1wb3J0IEFwcCBmcm9tICcuLi9hcHAvaW5kZXgnXG5pbXBvcnQgeyBpbnN0YW5jZU1hcCB9IGZyb20gJy4vbWFwJ1xuaW1wb3J0IHsgaW5pdCBhcyBpbml0QXBwIH0gZnJvbSAnLi4vYXBwL2N0cmwvaW5kZXgnXG5pbXBvcnQgeyByZXNldFRhcmdldCB9IGZyb20gJy4uL2NvcmUvZGVwJ1xuXG4vKipcbiAqIENyZWF0ZSBhIFdlZXggaW5zdGFuY2UuXG4gKlxuICogQHBhcmFtICB7c3RyaW5nfSBpZFxuICogQHBhcmFtICB7c3RyaW5nfSBjb2RlXG4gKiBAcGFyYW0gIHtvYmplY3R9IG9wdGlvbnNcbiAqICAgICAgICAgb3B0aW9uIGBIQVNfTE9HYCBlbmFibGUgcHJpbnQgbG9nXG4gKiBAcGFyYW0gIHtvYmplY3R9IGRhdGFcbiAqIEBwYXJhbSAge29iamVjdH0gaW5mbyB7IGNyZWF0ZWQsIC4uLiBzZXJ2aWNlcyB9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVJbnN0YW5jZSAoaWQsIGNvZGUsIG9wdGlvbnMsIGRhdGEsIGluZm8pIHtcbiAgY29uc3QgeyBzZXJ2aWNlcyB9ID0gaW5mbyB8fCB7fVxuICByZXNldFRhcmdldCgpXG4gIGxldCBpbnN0YW5jZSA9IGluc3RhbmNlTWFwW2lkXVxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fVxuICBsZXQgcmVzdWx0XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gIGlmICghaW5zdGFuY2UpIHtcbiAgICBpbnN0YW5jZSA9IG5ldyBBcHAoaWQsIG9wdGlvbnMpXG4gICAgaW5zdGFuY2VNYXBbaWRdID0gaW5zdGFuY2VcbiAgICByZXN1bHQgPSBpbml0QXBwKGluc3RhbmNlLCBjb2RlLCBkYXRhLCBzZXJ2aWNlcylcbiAgfVxuICBlbHNlIHtcbiAgICByZXN1bHQgPSBuZXcgRXJyb3IoYGludmFsaWQgaW5zdGFuY2UgaWQgXCIke2lkfVwiYClcbiAgfVxuICByZXR1cm4gKHJlc3VsdCBpbnN0YW5jZW9mIEVycm9yKSA/IHJlc3VsdCA6IGluc3RhbmNlXG59XG4iLCIvKlxuICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZVxuICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlXG4gKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvblxuICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZVxuICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZVxuICogXCJMaWNlbnNlXCIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlXG4gKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsXG4gKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhblxuICogXCJBUyBJU1wiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTllcbiAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZVxuICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9uc1xuICogdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbmltcG9ydCBjb25maWcgZnJvbSAnLi4vY29uZmlnJ1xuaW1wb3J0IHtcbiAgcmVmcmVzaCxcbiAgZGVzdHJveVxufSBmcm9tICcuLi9hcHAvY3RybC9pbmRleCdcbmltcG9ydCB7IGluc3RhbmNlTWFwIH0gZnJvbSAnLi9tYXAnXG5pbXBvcnQgeyByZXNldFRhcmdldCB9IGZyb20gJy4uL2NvcmUvZGVwJ1xuXG4vKipcbiAqIEluaXQgY29uZmlnIGluZm9ybWF0aW9ucyBmb3IgV2VleCBmcmFtZXdvcmtcbiAqIEBwYXJhbSAge29iamVjdH0gY2ZnXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbml0IChjZmcpIHtcbiAgY29uZmlnLkRvY3VtZW50ID0gY2ZnLkRvY3VtZW50XG4gIGNvbmZpZy5FbGVtZW50ID0gY2ZnLkVsZW1lbnRcbiAgY29uZmlnLkNvbW1lbnQgPSBjZmcuQ29tbWVudFxuICBjb25maWcuc2VuZFRhc2tzID0gY2ZnLnNlbmRUYXNrc1xuICBjb25maWcuTGlzdGVuZXIgPSBjZmcuTGlzdGVuZXJcbn1cblxuLyoqXG4gKiBSZWZyZXNoIGEgV2VleCBpbnN0YW5jZSB3aXRoIGRhdGEuXG4gKlxuICogQHBhcmFtICB7c3RyaW5nfSBpZFxuICogQHBhcmFtICB7b2JqZWN0fSBkYXRhXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWZyZXNoSW5zdGFuY2UgKGlkLCBkYXRhKSB7XG4gIGNvbnN0IGluc3RhbmNlID0gaW5zdGFuY2VNYXBbaWRdXG4gIGxldCByZXN1bHRcbiAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgaWYgKGluc3RhbmNlKSB7XG4gICAgcmVzdWx0ID0gcmVmcmVzaChpbnN0YW5jZSwgZGF0YSlcbiAgfVxuICBlbHNlIHtcbiAgICByZXN1bHQgPSBuZXcgRXJyb3IoYGludmFsaWQgaW5zdGFuY2UgaWQgXCIke2lkfVwiYClcbiAgfVxuICByZXR1cm4gcmVzdWx0XG59XG5cbi8qKlxuICogRGVzdHJveSBhIFdlZXggaW5zdGFuY2UuXG4gKiBAcGFyYW0gIHtzdHJpbmd9IGlkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZXN0cm95SW5zdGFuY2UgKGlkKSB7XG4gIC8vIE1hcmt1cCBzb21lIGdsb2JhbCBzdGF0ZSBpbiBuYXRpdmUgc2lkZVxuICBpZiAodHlwZW9mIG1hcmt1cFN0YXRlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgbWFya3VwU3RhdGUoKVxuICB9XG5cbiAgcmVzZXRUYXJnZXQoKVxuICBjb25zdCBpbnN0YW5jZSA9IGluc3RhbmNlTWFwW2lkXVxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICBpZiAoIWluc3RhbmNlKSB7XG4gICAgcmV0dXJuIG5ldyBFcnJvcihgaW52YWxpZCBpbnN0YW5jZSBpZCBcIiR7aWR9XCJgKVxuICB9XG4gIGRlc3Ryb3koaW5zdGFuY2UpXG4gIGRlbGV0ZSBpbnN0YW5jZU1hcFtpZF1cbiAgLy8gbm90aWZ5Q29udGV4dERpc3Bvc2VkIGlzIHVzZWQgdG8gdGVsbCB2OCB0byBkbyBhIGZ1bGwgR0MsXG4gIC8vIGJ1dCB0aGlzIHdvdWxkIGhhdmUgYSBuZWdhdGl2ZSBwZXJmb3JtYW5jZSBpbXBhY3Qgb24gd2VleCxcbiAgLy8gYmVjYXVzZSBhbGwgdGhlIGlubGluZSBjYWNoZSBpbiB2OCB3b3VsZCBnZXQgY2xlYXJlZFxuICAvLyBkdXJpbmcgYSBmdWxsIEdDLlxuICAvLyBUbyB0YWtlIGNhcmUgb2YgYm90aCBtZW1vcnkgYW5kIHBlcmZvcm1hbmNlLCBqdXN0IHRlbGwgdjhcbiAgLy8gdG8gZG8gYSBmdWxsIEdDIGV2ZXJ5IGVpZ2h0ZWVuIHRpbWVzLlxuICBjb25zdCBpZE51bSA9IE1hdGgucm91bmQoaWQpXG4gIGNvbnN0IHJvdW5kID0gMThcbiAgaWYgKGlkTnVtID4gMCkge1xuICAgIGNvbnN0IHJlbWFpbmRlciA9IGlkTnVtICUgcm91bmRcbiAgICBpZiAoIXJlbWFpbmRlciAmJiB0eXBlb2Ygbm90aWZ5VHJpbU1lbW9yeSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgbm90aWZ5VHJpbU1lbW9yeSgpXG4gICAgfVxuICB9XG4gIHJldHVybiBpbnN0YW5jZU1hcFxufVxuIiwiLypcbiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmVcbiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZVxuICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb25cbiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGVcbiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGVcbiAqIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZVxuICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLFxuICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW5cbiAqIFwiQVMgSVNcIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXG4gKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGVcbiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnNcbiAqIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5pbXBvcnQgVm0gZnJvbSAnLi4vdm0vaW5kZXgnXG5pbXBvcnQgY29uZmlnIGZyb20gJy4uL2NvbmZpZydcbmltcG9ydCB7XG4gIGluaXRNb2R1bGVzLFxuICBpbml0TWV0aG9kc1xufSBmcm9tICcuLi9hcHAvcmVnaXN0ZXInXG5cbmNvbnN0IHtcbiAgbmF0aXZlQ29tcG9uZW50TWFwXG59ID0gY29uZmlnXG5cbi8qKlxuICogUmVnaXN0ZXIgdGhlIG5hbWUgb2YgZWFjaCBuYXRpdmUgY29tcG9uZW50LlxuICogQHBhcmFtICB7YXJyYXl9IGNvbXBvbmVudHMgYXJyYXkgb2YgbmFtZVxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXJDb21wb25lbnRzIChjb21wb25lbnRzKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KGNvbXBvbmVudHMpKSB7XG4gICAgY29tcG9uZW50cy5mb3JFYWNoKGZ1bmN0aW9uIHJlZ2lzdGVyIChuYW1lKSB7XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICAgIGlmICghbmFtZSkge1xuICAgICAgICByZXR1cm5cbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgbmFtZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgbmF0aXZlQ29tcG9uZW50TWFwW25hbWVdID0gdHJ1ZVxuICAgICAgfVxuICAgICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICAgIGVsc2UgaWYgKHR5cGVvZiBuYW1lID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbmFtZS50eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgICBuYXRpdmVDb21wb25lbnRNYXBbbmFtZS50eXBlXSA9IG5hbWVcbiAgICAgIH1cbiAgICB9KVxuICB9XG59XG5cbi8qKlxuICogUmVnaXN0ZXIgdGhlIG5hbWUgYW5kIG1ldGhvZHMgb2YgZWFjaCBtb2R1bGUuXG4gKiBAcGFyYW0gIHtvYmplY3R9IG1vZHVsZXMgYSBvYmplY3Qgb2YgbW9kdWxlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXJNb2R1bGVzIChtb2R1bGVzKSB7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gIGlmICh0eXBlb2YgbW9kdWxlcyA9PT0gJ29iamVjdCcpIHtcbiAgICBpbml0TW9kdWxlcyhtb2R1bGVzKVxuICB9XG59XG5cbi8qKlxuICogUmVnaXN0ZXIgdGhlIG5hbWUgYW5kIG1ldGhvZHMgb2YgZWFjaCBhcGkuXG4gKiBAcGFyYW0gIHtvYmplY3R9IGFwaXMgYSBvYmplY3Qgb2YgYXBpc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXJNZXRob2RzIChtZXRob2RzKSB7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gIGlmICh0eXBlb2YgbWV0aG9kcyA9PT0gJ29iamVjdCcpIHtcbiAgICBpbml0TWV0aG9kcyhWbSwgbWV0aG9kcylcbiAgfVxufVxuXG4vLyBAdG9kbzogSGFjayBmb3IgdGhpcyBmcmFtZXdvcmsgb25seS4gV2lsbCBiZSByZS1kZXNpZ25lZCBvciByZW1vdmVkIGxhdGVyLlxuZ2xvYmFsLnJlZ2lzdGVyTWV0aG9kcyA9IHJlZ2lzdGVyTWV0aG9kc1xuIiwiLypcbiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmVcbiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZVxuICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb25cbiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGVcbiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGVcbiAqIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZVxuICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLFxuICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW5cbiAqIFwiQVMgSVNcIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXG4gKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGVcbiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnNcbiAqIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5pbXBvcnQgeyBpbnN0YW5jZU1hcCB9IGZyb20gJy4vbWFwJ1xuaW1wb3J0IHtcbiAgZmlyZUV2ZW50LFxuICBjYWxsYmFja1xufSBmcm9tICcuLi9hcHAvY3RybC9pbmRleCdcblxuY29uc3QganNIYW5kbGVycyA9IHtcbiAgZmlyZUV2ZW50OiAoaWQsIC4uLmFyZ3MpID0+IHtcbiAgICByZXR1cm4gZmlyZUV2ZW50KGluc3RhbmNlTWFwW2lkXSwgLi4uYXJncylcbiAgfSxcbiAgY2FsbGJhY2s6IChpZCwgLi4uYXJncykgPT4ge1xuICAgIHJldHVybiBjYWxsYmFjayhpbnN0YW5jZU1hcFtpZF0sIC4uLmFyZ3MpXG4gIH1cbn1cblxuLyoqXG4gKiBBY2NlcHQgY2FsbHMgZnJvbSBuYXRpdmUgKGV2ZW50IG9yIGNhbGxiYWNrKS5cbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd9IGlkXG4gKiBAcGFyYW0gIHthcnJheX0gdGFza3MgbGlzdCB3aXRoIGBtZXRob2RgIGFuZCBgYXJnc2BcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlY2VpdmVUYXNrcyAoaWQsIHRhc2tzKSB7XG4gIGNvbnN0IGluc3RhbmNlID0gaW5zdGFuY2VNYXBbaWRdXG4gIGlmIChpbnN0YW5jZSAmJiBBcnJheS5pc0FycmF5KHRhc2tzKSkge1xuICAgIGNvbnN0IHJlc3VsdHMgPSBbXVxuICAgIHRhc2tzLmZvckVhY2goKHRhc2spID0+IHtcbiAgICAgIGNvbnN0IGhhbmRsZXIgPSBqc0hhbmRsZXJzW3Rhc2subWV0aG9kXVxuICAgICAgY29uc3QgYXJncyA9IFsuLi50YXNrLmFyZ3NdXG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgICAgaWYgKHR5cGVvZiBoYW5kbGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGFyZ3MudW5zaGlmdChpZClcbiAgICAgICAgcmVzdWx0cy5wdXNoKGhhbmRsZXIoLi4uYXJncykpXG4gICAgICB9XG4gICAgfSlcbiAgICByZXR1cm4gcmVzdWx0c1xuICB9XG4gIHJldHVybiBuZXcgRXJyb3IoYGludmFsaWQgaW5zdGFuY2UgaWQgXCIke2lkfVwiIG9yIHRhc2tzYClcbn1cbiIsIi8qXG4gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lXG4gKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGVcbiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uXG4gKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlXG4gKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlXG4gKiBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2VcbiAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZyxcbiAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuXG4gKiBcIkFTIElTXCIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWVxuICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlXG4gKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zXG4gKiB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuaW1wb3J0IHsgaW5zdGFuY2VNYXAgfSBmcm9tICcuL21hcCdcbmltcG9ydCB7XG4gIGdldFJvb3RFbGVtZW50XG59IGZyb20gJy4uL2FwcC9jdHJsL2luZGV4J1xuXG4vKipcbiAqIEdldCBhIHdob2xlIGVsZW1lbnQgdHJlZSBvZiBhbiBpbnN0YW5jZSBmb3IgZGVidWdnaW5nLlxuICogQHBhcmFtICB7c3RyaW5nfSBpZFxuICogQHJldHVybiB7b2JqZWN0fSBhIHZpcnR1YWwgZG9tIHRyZWVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFJvb3QgKGlkKSB7XG4gIGNvbnN0IGluc3RhbmNlID0gaW5zdGFuY2VNYXBbaWRdXG4gIGxldCByZXN1bHRcbiAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgaWYgKGluc3RhbmNlKSB7XG4gICAgcmVzdWx0ID0gZ2V0Um9vdEVsZW1lbnQoaW5zdGFuY2UpXG4gIH1cbiAgZWxzZSB7XG4gICAgcmVzdWx0ID0gbmV3IEVycm9yKGBpbnZhbGlkIGluc3RhbmNlIGlkIFwiJHtpZH1cImApXG4gIH1cbiAgcmV0dXJuIHJlc3VsdFxufVxuIiwiLypcbiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmVcbiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZVxuICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb25cbiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGVcbiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGVcbiAqIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZVxuICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLFxuICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW5cbiAqIFwiQVMgSVNcIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXG4gKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGVcbiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnNcbiAqIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG4vKipcbiAqIEBmaWxlT3ZlcnZpZXcgV2VleCBmcmFtZXdvcmsgZW50cnkuXG4gKi9cblxuaW1wb3J0ICogYXMgbWV0aG9kcyBmcm9tICcuL2FwaS9tZXRob2RzJ1xuXG5pbXBvcnQgVm0gZnJvbSAnLi92bSdcbmV4cG9ydCB7IGNyZWF0ZUluc3RhbmNlIH0gZnJvbSAnLi9zdGF0aWMvY3JlYXRlJ1xuZXhwb3J0IHsgaW5pdCwgcmVmcmVzaEluc3RhbmNlLCBkZXN0cm95SW5zdGFuY2UgfSBmcm9tICcuL3N0YXRpYy9saWZlJ1xuaW1wb3J0IHsgcmVnaXN0ZXJDb21wb25lbnRzLCByZWdpc3Rlck1vZHVsZXMsIHJlZ2lzdGVyTWV0aG9kcyB9IGZyb20gJy4vc3RhdGljL3JlZ2lzdGVyJ1xuZXhwb3J0IHsgcmVjZWl2ZVRhc2tzIH0gZnJvbSAnLi9zdGF0aWMvYnJpZGdlJ1xuZXhwb3J0IHsgZ2V0Um9vdCB9IGZyb20gJy4vc3RhdGljL21pc2MnXG5cbi8vIHJlZ2lzdGVyIHNwZWNpYWwgbWV0aG9kcyBmb3IgV2VleCBmcmFtZXdvcmtcbnJlZ2lzdGVyTWV0aG9kcyhtZXRob2RzKVxuXG4vKipcbiAqIFByZXZlbnQgbW9kaWZpY2F0aW9uIG9mIFZtIGFuZCBWbS5wcm90b3R5cGVcbiAqL1xuT2JqZWN0LmZyZWV6ZShWbSlcblxuZXhwb3J0IHsgcmVnaXN0ZXJDb21wb25lbnRzLCByZWdpc3Rlck1vZHVsZXMsIHJlZ2lzdGVyTWV0aG9kcyB9XG4iXSwibmFtZXMiOlsiY29uc3QiLCJ0aGlzIiwibGV0IiwidWlkIiwiYXJndW1lbnRzIiwiZGVmIiwiaSIsInR5cGUiLCJpbml0TWV0aG9kcyIsImRvd25ncmFkZS5jaGVjayIsImNsZWFuTmFtZSIsInJlZ2lzdGVyIiwiQXBwIiwicmVuZGVyZXIiLCJpbml0QXBwIiwiaW5pdCIsIm5hdGl2ZUNvbXBvbmVudE1hcCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7QUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUE2QkEsQUFBTyxTQUFTLENBQUMsRUFBRSxFQUFFLEVBQUU7RUFDckIsT0FBTyxDQUFDLElBQUksQ0FBQyw4REFBOEQsQ0FBQyxDQUFBO0VBQzVFQSxJQUFNLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFBO0VBQzFCLElBQUksSUFBSSxFQUFFO0lBQ1IsT0FBTyxJQUFJLENBQUMsRUFBRTtHQUNmO0NBQ0Y7Ozs7Ozs7O0FBUUQsQUFBTyxTQUFTLEdBQUcsRUFBRSxFQUFFLEVBQUU7RUFDdkJBLElBQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUE7RUFDMUIsSUFBSSxJQUFJLEVBQUU7SUFDUixPQUFPLElBQUksQ0FBQyxFQUFFO0dBQ2Y7Q0FDRjs7Ozs7Ozs7QUFRRCxBQUFPLFNBQVMsR0FBRyxFQUFFLEVBQUUsRUFBRTtFQUN2QkEsSUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQTtFQUMxQixJQUFJLElBQUksRUFBRTtJQUNSLE9BQU8sSUFBSSxDQUFDLEVBQUU7R0FDZjtDQUNGOzs7Ozs7O0FBT0QsQUFBTyxTQUFTLFdBQVcsRUFBRSxFQUFF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LENBQUMsU0FBUyxJQUFJLEVBQUU7SUFDakQsT0FBTyxZQUFZLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO0dBQ2xDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7Q0FDZDs7QUFFRCxTQUFTLFlBQVksQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFO0VBQ2pDLEtBQUssQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO0VBQzVCLElBQUksQ0FBQyxHQUFHLEtBQUssR0FBRyxFQUFFLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO0VBQzNDLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFO0lBQzlDLEtBQUssQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUNyQyxJQUFJLEdBQUcsQ0FBQzs7SUFFUixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUM7TUFDUixFQUFBLEdBQUcsR0FBRyxFQUFFLENBQUMsRUFBQTtTQUNOLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQztNQUNiLEVBQUEsR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDLEdBQUcsUUFBUSxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxFQUFBO1NBQzNDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO01BQ2YsSUFBSSxDQUFDLEtBQUssR0FBRztRQUNYLEVBQUEsR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxNQUFNLEdBQUcsQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsRUFBQTs7UUFFOUQsRUFBQSxHQUFHLEdB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
diff --git a/packages/weex-legacy-framework/index.min.js b/packages/weex-legacy-framework/index.min.js
deleted file mode 100644
index c53c7cf..0000000
--- a/packages/weex-legacy-framework/index.min.js
+++ /dev/null
@@ -1 +0,0 @@
-!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t(e.WeexLegacyFramework=e.WeexLegacyFramework||{})}(this,function(e){"use strict";function t(e){for(var r=[],n=arguments.length-1;n-- >0;)r[n]=arguments[n+1];if("function"==typeof Object.assign)Object.assign.apply(Object,[e].concat(r));else{var o=r.shift();for(var i in o)e[i]=o[i];r.length&&t.apply(void 0,[e].concat(r))}return e}function r(e,t,r,n){Object.defineProperty(e,t,{value:r,enumerable:!!n,writable:!0,configurable:!0})}function n(e,t){if(e.length){var r=e.indexOf(t);if(r>-1)return e.splice(r,1)}}function o(e,t){return ut.call(e,t)}function i(e,t){return function(r){var n=arguments.length;return n?n>1?e.apply(t,arguments):e.call(t,r):e.call(t)}}function a(e){return null!==e&&"object"==typeof e}function s(e){return lt.call(e)===pt}function c(e){var t=(e+"").charCodeAt(0);return 36===t||95===t}function u(){return"object"==typeof nativeSet?nativeSet.create():new st}function l(e){var t=Object.prototype.toString.call(e);return t.substring(8,t.length-1).toLowerCase()}function p(e){return e.replace(ht,"").replace(dt,"")}function f(e){return e.replace(mt,"")}function h(){this.id=bt++,this.subs=[]}function d(e){h.target&&kt.push(h.target),h.target=e}function v(){h.target=kt.pop()}function m(){h.target=null,kt=[]}function y(e,r,n,o){o&&t(this,o);var i="function"==typeof r;this.vm=e,e._watchers.push(this),this.expression=r,this.cb=n,this.id=++Et,this.active=!0,this.dirty=this.lazy,this.deps=[],this.newDeps=[],this.depIds=u(),this.newDepIds=u(),i&&(this.getter=r),this.value=this.lazy?void 0:this.get(),this.queued=this.shallow=!1}function g(e,t){var r,n,o,i;if(t||(t=St).clear(),o=Array.isArray(e),i=a(e),o||i){if(e.__ob__){var s=e.__ob__.dep.id;if(t.has(s))return;t.add(s)}if(o)for(r=e.length;r--;)g(e[r],t);else if(i)for(r=(n=Object.keys(e)).length;r--;)g(e[n[r]],t)}}function w(e){this.value=e,this.dep=new h,r(e,"__ob__",this),Array.isArray(e)?((ft?_:b)(e,$t,xt),this.observeArray(e)):this.walk(e)}function _(e,t){e.__proto__=t}function b(e,t,n){for(var o=0,i=n.length;o<i;o++){var a=n[o];r(e,a,t[a])}}function k(e,t){if(a(e)){var r;return o(e,"__ob__")&&e.__ob__ instanceof w?r=e.__ob__:(Array.isArray(e)||s(e))&&Object.isExtensible(e)&&!e._isVue&&(r=new w(e)),r&&t&&r.addVm(t),r}}function E(e,t,r){var n=new h,o=Object.getOwnPropertyDescriptor(e,t);if(!o||!1!==o.configurable){var i=o&&o.get,a=o&&o.set,s=k(r);Object.defineProperty(e,t,{enumerable:!0,configurable:!0,get:function(){var t=i?i.call(e):r;if(h.target&&(n.depend(),s&&s.dep.depend(),Array.isArray(t)))for(var o=void 0,a=0,c=t.length;a<c;a++)(o=t[a])&&o.__ob__&&o.__ob__.dep.depend();return t},set:function(t){t!==(i?i.call(e):r)&&(a?a.call(e,t):r=t,s=k(t),n.notify())}})}}function S(e,t,r){if(Array.isArray(e))return e.splice(t,1,r);if(o(e,t))e[t]=r;else if(e._isVue)S(e._data,t,r);else{var n=e.__ob__;if(n){if(n.convert(t,r),n.dep.notify(),n.vms)for(var i=n.vms.length;i--;)j(n.vms[i],t);return r}e[t]=r}}function j(e,t){(Ot.indexOf(t)>-1||!c(t))&&Object.defineProperty(e,t,{configurable:!0,enumerable:!0,get:function(){return e._data[t]},set:function(r){e._data[t]=r}})}function $(e,t){c(t)||delete e[t]}function x(e){e._watchers=[],O(e),A(e),F(e)}function O(e){var t=e._data;s(t)||(t={});for(var r=Object.keys(t),n=r.length;n--;)j(e,r[n]);k(t,e)}function M(){}function A(e){var t=e._computed;if(t)for(var r in t){var n=t[r],o={enumerable:!0,configurable:!0};"function"==typeof n?(o.get=C(n,e),o.set=M):(o.get=n.get?!1!==n.cache?C(n.get,e):i(n.get,e):M,o.set=n.set?i(n.set,e):M),Object.defineProperty(e,r,o)}}function C(e,t){var r=new y(t,e,null,{lazy:!0});return function(){return r.dirty&&r.evaluate(),h.target&&r.depend(),r.value}}function F(e){var t=e._methods;if(t)for(var r in t)e[r]=t[r]}function T(e){var t=e.type,r=At[t];if("object"==typeof r)for(var n in r)if(null==e[n])e[n]=r[n];else if("object"===l(e[n])&&"object"===l(r[n]))for(var o in r[n])null==e[n][o]&&(e[n][o]=r[n][o])}function V(e,t,r){q(e,t,r.id,e),B(e,t,r.attr),N(e,t,r.classList),z(e,t,r.style),U(e,t,r.events)}function I(e,t,r,n){t=t||{},r=r||{};var o=(t._options||{}).props;Array.isArray(o)&&(o=o.reduce(function(e,t){return e[t]=!0,e},{})),D(n,o,e,t),D(r.attr,o,e,t)}function J(e,t,r,n){void 0===n&&(n={}),P(r.classList,e,t),R(r.style,e,t),n.children?n.children[n.children.length-1]._vm=t:n._vm=t}function D(e,t,r,n){if(e){for(var o in e)!function(o){if(!t||t[o]){var i=e[o];if("function"==typeof i){var a=Z(r,i,function(e){n[o]=e});n[o]=a}else n[o]=i}}(o)}}function R(e,t,r){for(var n in e)!function(n){var o=e[n];if("function"==typeof o){var i=Z(t,o,function(e){r._rootEl&&r._rootEl.setStyle(n,e)});r._rootEl.setStyle(n,i)}else r._rootEl&&r._rootEl.setStyle(n,o)}(n)}function P(e,t,r){function n(e,t){"array"===l(e)&&e.unshift(t)}var o=t._options&&t._options.style||{};if(r._rootEl){var i="@originalRootEl";if(o[i]=r._rootEl.classStyle,"function"==typeof e){var a=Z(t,e,function(e){n(e,i),L(r._rootEl,o,e)});n(a,i),L(r._rootEl,o,a)}else null!=e&&(n(e,i),L(r._rootEl,o,e))}}function q(e,t,r,n){var o=Object.create(null);if(Object.defineProperties(o,{vm:{value:n,writable:!1,configurable:!1},el:{get:function(){return t||n._rootEl},configurable:!1}}),"function"==typeof r){var i=r;((r=i.call(e))||0===r)&&(e._ids[r]=o),Z(e,i,function(t){t&&(e._ids[t]=o)})}else r&&"string"==typeof r&&(e._ids[r]=o)}function B(e,t,r){W(e,t,"attr",r)}function L(e,t,r){"string"==typeof r&&(r=r.split(/\s+/)),r.forEach(function(e,t){r.splice.apply(r,[t,1].concat(e.split(/\s+/)))});for(var n={},o=r.length,i=0;i<o;i++)!function(e){var o=t[r[e]];o&&Object.keys(o).forEach(function(e){n[e]=o[e]})}(i);e.setClassStyle(n)}function N(e,t,r){if("function"==typeof r||Array.isArray(r))if(!Array.isArray(r)||r.length){var n=e._options&&e._options.style||{};if("function"==typeof r){var o=Z(e,r,function(e){L(t,n,e)});L(t,n,o)}else L(t,n,r)}else t.setClassStyle({})}function z(e,t,r){W(e,t,"style",r)}function X(e,t,r,n){t.addEvent(r,i(n,e))}function U(e,t,r){if(r)for(var n=Object.keys(r),o=n.length;o--;){var i=n[o],a=r[i];"string"==typeof a&&((a=e[a])||console.warn('[JS Framework] The event handler "'+a+'" is not defined.')),X(e,t,i,a)}}function W(e,t,r,n){if(n)for(var o=Object.keys(n),i=o.length;i--;){var a=o[i],s=n[a];"function"==typeof s?H(e,t,r,a,s):t[Ct[r]](a,s)}}function H(e,t,r,n,o){var i=Ct[r],a=Z(e,o,function(r){function o(){t[i](n,r)}var a=e&&e._app&&e._app.differ;a?a.append("element",t.depth,t.ref,o):o()});t[i](n,a)}function Z(e,t,r){return e._static?t.call(e,e):new y(e,t,function(e,t){"object"!=typeof e&&e===t||r(e)}).value}function G(e,t){return e._app.doc.createBody(t)}function K(e,t){return e._app.doc.createElement(t)}function Q(e,t){var r=Y(e),n=ee(e),o=Ft++;if(t.element){var i=t.updateMark;i?(i.element&&(i=i.end),t.element.insertAfter(n,i),t.element.insertAfter(r,i),t.updateMark=n):(t.element.insertBefore(r,t.end),t.element.insertBefore(n,t.end)),t=t.element}else t.appendChild(r),t.appendChild(n);return{start:r,end:n,element:t,blockId:o}}function Y(e){return e._app.doc.createComment("start")}function ee(e){return e._app.doc.createComment("end")}function te(e,t,r){if(r.element){var n=r.end,o=r.updateMark;if(r.children&&r.children.push(t),o){var i=re(e,t,o);return r.updateMark=t.element?t.end:t,i}if(!t.element)return r.element.insertBefore(t,n);r.element.insertBefore(t.start,n),r.element.insertBefore(t.end,n)}else{if(!t.element)return r.appendChild(t);r.appendChild(t.start),r.appendChild(t.end)}}function re(e,t,r){return t.element?oe(t,r):ne(t,r)}function ne(e,t){var r=t.parentNode;if(r)return r.insertAfter(e,t)}function oe(e,t){var r=t.parentNode;if(r){for(var n,o=e.start,i=[o];o&&o!==e.end;)o=o.nextSibling,i.push(o);var a=t;return i.every(function(e){return n=r.insertAfter(e,a),a=e,-1!==n}),n}}function ie(e,t,r){void 0===r&&(r=!1),t.element?se(t,r):ae(t),t._vm&&t._vm.$emit("hook:destroyed")}function ae(e){var t=e.parentNode;t&&t.removeChild(e)}function se(e,t){void 0===t&&(t=!1);for(var r=[],n=e.start.nextSibling;n&&n!==e.end;)r.push(n),n=n.nextSibling;t||ae(e.start),r.forEach(function(e){ae(e)}),t||ae(e.end)}function ce(e){var t=e._options||{},r=t.template||{};t.replace?r.children&&1===r.children.length?ue(e,r.children[0],e._parentEl):ue(e,r.children,e._parentEl):ue(e,r,e._parentEl),console.debug('[JS Framework] "ready" lifecycle in Vm('+e._type+")"),e.$emit("hook:ready"),e._ready=!0}function ue(e,t,r,n){if(-1!==(e._app||{}).lastSignal)if(t.attr&&t.attr.hasOwnProperty("static")&&(e._static=!0),le(t))me(e,t,r,n);else{if(n=n||{},pe(t))return console.debug('[JS Framework] compile "content" block by',t),void(e._content=Q(e,r));if(fe(t,n))return console.debug('[JS Framework] compile "repeat" logic by',t),void("document"===r.type?console.warn("[JS Framework] The root element does't support `repeat` directive!"):ye(e,t,r));if(he(t,n))return console.debug('[JS Framework] compile "if" logic by',t),void("document"===r.type?console.warn("[JS Framework] The root element does't support `if` directive!"):ge(e,t,r,n));var o=n.type||t.type;if(de(o,n))we(e,t,r,o,n);else{var i=o,a=ve(e,t,i);if(a)return console.debug("[JS Framework] compile composed component by",t),void _e(e,a,t,r,i,n);console.debug("[JS Framework] compile native component by",t),be(e,t,r,i)}}}function le(e){return Array.isArray(e)}function pe(e){return"content"===e.type||"slot"===e.type}function fe(e,t){return!t.hasOwnProperty("repeat")&&e.repeat}function he(e,t){return!t.hasOwnProperty("shown")&&e.shown}function de(e,t){return"function"==typeof e&&!t.hasOwnProperty("type")}function ve(e,t,r){var n;return e._app&&e._app.customComponentMap&&(n=e._app.customComponentMap[r]),e._options&&e._options.components&&(n=e._options.components[r]),t.component&&(n=n||{}),n}function me(e,t,r,n){var o=Q(e,r);t.forEach(function(t){ue(e,t,o,n)})}function ye(e,t,r){var n=t.repeat,o="function"==typeof n,i=n.getter||n.expression||n;"function"!=typeof i&&(i=function(){return[]});var a=n.key||"$index",s=n.value||"$value",c=n.trackBy||t.trackBy||t.attr&&t.attr.trackBy,u=Q(e,r);u.children=[],u.data=[],u.vms=[],Ee(e,t,u,{getter:i,key:a,value:s,trackBy:c,oldStyle:o})}function ge(e,t,r,n){var o={shown:!0},i=Q(e,r);r.element&&r.children&&r.children.push(i),n.repeat&&(o.repeat=n.repeat),Se(e,t,i,o)}function we(e,r,n,o,i){var a=t({type:o.call(e)},i),s=Q(e,n);n.element&&n.children&&n.children.push(s),Z(e,o,function(n){var o=t({type:n},i);ie(e,s,!0),ue(e,r,s,o)}),ue(e,r,s,a)}function _e(e,t,r,n,o,i){var a=new(0,e.constructor)(o,t,e,n,void 0,{"hook:init":function(){e._static&&(this._static=e._static),q(e,null,r.id,this),this._externalBinding={parent:e,template:r}},"hook:created":function(){I(e,this,r,i.repeat)},"hook:ready":function(){this._content&&ke(e,r,this._content)}});J(e,a,r,n)}function be(e,t,r,n){T(t);var o;if("_documentElement"===r.ref?(console.debug("[JS Framework] compile to create body for "+n),o=G(e,n)):(console.debug("[JS Framework] compile to create element for "+n),o=K(e,n)),!e._rootEl){e._rootEl=o;var a=e._externalBinding||{},s=a.template,c=a.parent;if(s&&s.events&&c&&o)for(var u in s.events){var l=c[s.events[u]];l&&o.addEvent(u,i(l,c))}}V(e,o,t),t.attr&&t.attr.append&&(t.append=t.attr.append),t.append&&(o.attr=o.attr||{},o.attr.append=t.append);var p="tree"===t.append,f=e._app||{};-1===f.lastSignal||p||(console.debug("[JS Framework] compile to append single node for",o),f.lastSignal=te(e,o,r)),-1!==f.lastSignal&&ke(e,t,o),-1!==f.lastSignal&&p&&(console.debug("[JS Framework] compile to append whole tree for",o),f.lastSignal=te(e,o,r))}function ke(e,t,r){var n=e._app||{},o=t.children;o&&o.length&&o.every(function(t){return ue(e,t,r),-1!==n.lastSignal})}function Ee(e,t,r,n){function o(e,n,o){var s;l?(s=e,a(e)?(s[p]=n,s.hasOwnProperty("INDEX")||Object.defineProperty(s,"INDEX",{value:function(){console.warn('[JS Framework] "INDEX" in repeat is deprecated, please use "$index" instead')}})):(console.warn("[JS Framework] Each list item must be an object in old-style repeat, please use `repeat={{v in list}}` instead."),(s={})[p]=n,s[f]=e)):((s={})[p]=n,s[f]=e);var c=$e(o,s);i.push(c),ue(c,t,r,{repeat:e})}var i=r.vms,s=r.children,c=n.getter,u=n.trackBy,l=n.oldStyle,p=n.key,f=n.value,h=je(e,r,c,"repeat",function(t){if(console.debug('[JS Framework] the "repeat" item has changed',t),r&&t){var n=s.slice(),a=i.slice(),c=r.data.slice(),h={},d={};t.forEach(function(e,t){var r=u?e[u]:l?e[p]:t;null!=r&&""!==r&&(h[r]=e)});var v=[];c.forEach(function(t,r){var o=u?t[u]:l?t[p]:r;h.hasOwnProperty(o)?(d[o]={item:t,index:r,key:o,target:n[r],vm:a[r]},v.push(t)):ie(e,n[r])}),s.length=0,i.length=0,r.data=t.slice(),r.updateMark=r.start,t.forEach(function(t,n){var a=u?t[u]:l?t[p]:n,c=d[a];c?(c.item===v[0]?v.shift():(v.$remove(c.item),re(e,c.target,r.updateMark,!0)),s.push(c.target),i.push(c.vm),l?c.vm=t:c.vm[f]=t,c.vm[p]=n,r.updateMark=c.target):o(t,n,e)}),delete r.updateMark}});r.data=h.slice(0),h.forEach(function(t,r){o(t,r,e)})}function Se(e,t,r,n){var o=je(e,r,t.shown,"shown",function(o){console.debug('[JS Framework] the "if" item was changed',o),r&&!!r.display!=!!o&&(r.display=!!o,o?ue(e,t,r,n):ie(e,r,!0))});r.display=!!o,o&&ue(e,t,r,n)}function je(e,t,r,n,o){var i=e&&e._app&&e._app.differ,a={},s=(t.element.depth||0)+1;return Z(e,r,function(e){a.latestValue=e,i&&!a.recorded&&i.append(n,s,t.blockId,function(){var e=a.latestValue;o(e),a.recorded=!1,a.latestValue=void 0}),a.recorded=!0})}function $e(e,t){var r=Object.create(e);return r._data=t,O(r),A(r),r._realParent=e,e._static&&(r._static=e._static),r}function xe(e,t){if(t instanceof xe)return t;this.timestamp=Date.now(),this.detail=t,this.type=e;var r=!1;this.stop=function(){r=!0},this.hasStopped=function(){return r}}function Oe(e,t){var r=this,n=this._vmEvents[e];if(n){var o=new xe(e,t);n.forEach(function(e){e.call(r,o)})}}function Me(e,t){var r=new xe(e,t);this.$emit(e,r),!r.hasStopped()&&this._parent&&this._parent.$dispatch&&this._parent.$dispatch(e,r)}function Ae(e,t){var r=new xe(e,t);this.$emit(e,r),!r.hasStopped()&&this._childrenVms&&this._childrenVms.forEach(function(t){t.$broadcast(e,r)})}function Ce(e,t){if(e&&"function"==typeof t){var r=this._vmEvents,n=r[e]||[];n.push(t),r[e]=n,"hook:ready"===e&&this._ready&&this.$emit("hook:ready")}}function Fe(e,t){if(e){var r=this._vmEvents;if(t){var n=r[e];n&&n.$remove(t)}else delete r[e]}}function Te(e,t){var r=e._options||{},n=r.events||{};for(var o in n)e.$on(o,n[o]);for(var i in t)e.$on(i,t[i]);Tt.forEach(function(t){e.$on("hook:"+t,r[t])})}function Ve(e,r,n,o,i,a){n=n||{},this._parent=n._realParent?n._realParent:n,this._app=n._app||{},n._childrenVms&&n._childrenVms.push(this),!r&&this._app.customComponentMap&&(r=this._app.customComponentMap[e]);var s=(r=r||{}).data||{};this._options=r,this._methods=r.methods||{},this._computed=r.computed||{},this._css=r.style||{},this._ids={},this._vmEvents={},this._childrenVms=[],this._type=e,Te(this,a),console.debug('[JS Framework] "init" lifecycle in Vm('+this._type+")"),this.$emit("hook:init"),this._inited=!0,this._data="function"==typeof s?s():s,i&&t(this._data,i),x(this),console.debug('[JS Framework] "created" lifecycle in Vm('+this._type+")"),this.$emit("hook:created"),this._created=!0,r.methods&&r.methods.ready&&(console.warn('"exports.methods.ready" is deprecated, please use "exports.created" instead'),r.methods.ready.call(this)),this._app.doc&&(this._parentEl=o||this._app.doc.documentElement,ce(this))}function Ie(e,t){for(var r in e)!function(r){var n=Vt[r];n||(n={},Vt[r]=n),e[r].forEach(function(e){"string"==typeof e&&(e={name:e}),n[e.name]&&!t||(n[e.name]=e)})}(r)}function Je(e,t){var r=e.prototype;for(var n in t)r.hasOwnProperty(n)||(r[n]=t[n])}function De(e,t){var r=Vt[t],n={};for(var o in r)!function(r){Object.defineProperty(n,r,{configurable:!0,enumerable:!0,get:function(){return function(){for(var n=[],o=arguments.length;o--;)n[o]=arguments[o];return e.callTasks({module:t,method:r,args:n})}},set:function(n){if("function"==typeof n)return e.callTasks({module:t,method:r,args:[n]})}})}(o);return n}function Re(e,t){return e.customComponentMap[t]}function Pe(e,t,r){var n=e.customComponentMap;n[t]?console.error("[JS Framework] define a component("+t+") that already exists"):n[t]=r}function qe(e){if(It.valid(e))return e;for(var t=(e="string"==typeof e?e:"").split("."),r=0,n=[];r<3;){var o="string"==typeof t[r]&&t[r]?t[r]:"0";n.push(o),r++}return n.join(".")}function Be(e,t,r){var n={isDowngrade:!0,errorType:1,code:1e3},o=e.toLowerCase();return n.errorMessage=function(e,t,r){return"Downgrade["+e+"] :: deviceInfo "+t+" matched criteria "+r}(e,t,r),o.indexOf("osversion")>=0?n.code=1001:o.indexOf("appversion")>=0?n.code=1002:o.indexOf("weexversion")>=0?n.code=1003:o.indexOf("devicemodel")>=0&&(n.code=1004),n}function Le(e,t){t=s(t=t||global.WXEnvironment)?t:{};var r={isDowngrade:!1};if("function"===l(e)){var n=e.call(this,t,{semver:It,normalizeVersion:qe});r=(n=!!n)?Be("custom","","custom params"):r}else{var o=(e=s(e)?e:{})[(t.platform||"unknow").toLowerCase()]||{};for(var i in t){var a=i,c=a.toLowerCase(),u=t[i],p=c.indexOf("version")>=0,f=c.indexOf("devicemodel")>=0,h=o[i];if(h&&p){var d=qe(h),v=qe(t[i]);if(It.satisfies(v,d)){r=Be(a,u,h);break}}else if(f&&("array"===l(h)?h:[h]).indexOf(u)>=0){r=Be(a,u,h);break}}}return r}function Ne(e,t){if(void 0===t&&(t={}),e&&e.callTasks)return e.callTasks([{module:"meta",method:"setViewport",args:[t]}])}function ze(e,t,r,n){console.debug("[JS Framework] bootstrap for "+t);var o;if(yt(t))o=p(t);else{if(!_t(t))return new Error("Wrong component name: "+t);if(o=f(t),!Re(e,o))return new Error("It's not a component: "+t)}if("string"==typeof(r=s(r)?r:{}).transformerVersion&&"string"==typeof global.transformerVersion&&!It.satisfies(r.transformerVersion,global.transformerVersion))return new Error("JS Bundle version: "+r.transformerVersion+" not compatible with "+global.transformerVersion);var i=Le(r.downgrade);if(i.isDowngrade)return e.callTasks([{module:"instanceWrap",method:"error",args:[i.errorType,i.code,i.errorMessage]}]),new Error("Downgrade["+i.code+"]: "+i.errorMessage);r.viewport&&Ne(e,r.viewport),e.vm=new Ve(o,null,{_app:e},null,n)}function Xe(e,t,r){console.warn("[JS Framework] Register is deprecated, please install lastest transformer."),Pe(e,t,r)}function Ue(e,r){console.debug("[JS Framework] Refresh with",r,"in instance["+e.id+"]");var n=e.vm;return n&&r?("function"==typeof n.refreshData?n.refreshData(r):t(n,r),e.differ.flush(),void e.doc.taskCenter.send("dom",{action:"refreshFinish"},[])):new Error('invalid data "'+r+'"')}function We(e){console.debug("[JS Framework] Destory an instance("+e.id+")"),e.vm&&He(e.vm),e.id="",e.options=null,e.blocks=null,e.vm=null,e.doc.taskCenter.destroyCallback(),e.doc.destroy(),e.doc=null,e.customComponentMap=null,e.commonModules=null}function He(e){if(delete e._app,delete e._computed,delete e._css,delete e._data,delete e._ids,delete e._methods,delete e._options,delete e._parent,delete e._parentEl,delete e._rootEl,e._watchers){for(var t=e._watchers.length;t--;)e._watchers[t].teardown();delete e._watchers}if(e._childrenVms){for(var r=e._childrenVms.length;r--;)He(e._childrenVms[r]);delete e._childrenVms}console.debug('[JS Framework] "destroyed" lifecycle in Vm('+e._type+")"),e.$emit("hook:destroyed"),delete e._type,delete e._vmEvents}function Ze(e){var t=(e.doc||{}).body||{};return t.toJSON?t.toJSON():{}}function Ge(e,t,r,n,o){console.debug('[JS Framework] Fire a "'+r+'" event on an element('+t+") in instance("+e.id+")");{if(!Array.isArray(t)){var i=e.doc.getRef(t);if(i){var a=e.doc.fireEvent(i,r,n,o);return e.differ.flush(),e.doc.taskCenter.send("dom",{action:"updateFinish"},[]),a}return new Error('invalid element reference "'+t+'"')}t.some(function(t){return!1!==Ge(e,t,r,n)})}}function Ke(e,t,r,n){console.debug("[JS Framework] Invoke a callback("+t+") with",r,"in instance("+e.id+")");var o=e.doc.taskCenter.callback(t,r,n);return Qe(e),e.doc.taskCenter.send("dom",{action:"updateFinish"},[]),o}function Qe(e){e.differ.flush()}function Ye(e,t){var r;return"array"!==l(t)&&(t=[t]),t.forEach(function(t){r=e.doc.taskCenter.send("module",{module:t.module,method:t.method},t.args)}),r}function et(e,t,r,n){console.debug("[JS Framework] Intialize an instance with:\n",r);var o,i=function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];return Jt.apply(void 0,[e].concat(t))},a=function(t,n,i){o=ze(e,t,n,i||r),Qe(e),e.doc.listener.createFinish(),console.debug("[JS Framework] After intialized an instance("+e.id+")")},s=Ve,c=e.doc,u=function(t){return e.requireModule(p(t))},l={config:e.options,define:i,bootstrap:a,requireModule:u,document:c,Vm:s};Object.freeze(l);var f;"function"==typeof t?f=t.toString().substr(12):t&&(f=t.toString()),f='(function(global){\n\n"use strict";\n\n '+f+" \n\n})(Object.create(this))";var h=global.WXEnvironment,d={};if(h&&"Web"!==h.platform){var v=e.requireModule("timer");Object.assign(d,{setTimeout:function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];return v.setTimeout(function(){t[0].apply(t,t.slice(2))},t[1]),e.doc.taskCenter.callbackManager.lastCallbackId.toString()},setInterval:function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];return v.setInterval(function(){t[0].apply(t,t.slice(2))},t[1]),e.doc.taskCenter.callbackManager.lastCallbackId.toString()},clearTimeout:function(e){v.clearTimeout(e)},clearInterval:function(e){v.clearInterval(e)}})}var m=Object.assign({define:i,require:function(t){return function(r){o=ze(e,t,{},r)}},bootstrap:a,register:function(){for(var t=[],r=arguments.length;r--;)t[r]=arguments[r];return Xe.apply(void 0,[e].concat(t))},render:function(t,r){o=ze(e,t,{},r)},__weex_define__:i,__weex_bootstrap__:a,__weex_document__:c,__weex_require__:u,__weex_viewmodel__:s,weex:l},d,n);return rt(m,f)||tt(m,f),o}function tt(e,t){var r=[],n=[];for(var o in e)r.push(o),n.push(e[o]);return r.push(t),(new(Function.prototype.bind.apply(Function,[null].concat(r)))).apply(void 0,n)}function rt(e,t){if("function"!=typeof compileAndRunBundle)return!1;var r=void 0,n=!1,o="(function (",i=[],a=[];for(var s in e)i.push(s),a.push(e[s]);for(var c=0;c<i.length-1;++c)o+=i[c],o+=",";o+=i[i.length-1],o+=") {",o+=t,o+="} )";try{var u=(e.weex||{}).config||{};(r=compileAndRunBundle(o,u.bundleUrl,u.bundleDigest,u.codeCachePath))&&"function"==typeof r&&(r.apply(void 0,a),n=!0)}catch(e){console.error(e)}return n}function nt(e,t){var r=e[t];for(var n in r)r[n]()}function ot(e,t){var r=e[t];for(var n in r)r[n].forEach(function(e){e()})}function it(e,t){this.id=e,this.options=t||{},this.vm=null,this.customComponentMap={},this.commonModules={},this.doc=new Mt.Document(e,this.options.bundleUrl,null,Mt.Listener),this.differ=new Dt(e)}function at(e){"object"==typeof e&&Je(Ve,e)}var st,ct=Object.freeze({$:function(e){console.warn("[JS Framework] Vm#$ is deprecated, please use Vm#$vm instead");var t=this._ids[e];if(t)return t.vm},$el:function(e){var t=this._ids[e];if(t)return t.el},$vm:function(e){var t=this._ids[e];if(t)return t.vm},$renderThen:function(e){return this._app.differ.then(function(){e()})},$scrollTo:function(e,t){console.warn("[JS Framework] Vm#$scrollTo is deprecated, please use \"require('@weex-module/dom').scrollTo(el, options)\" instead");var r=this.$el(e);r&&this._app.requireModule("dom").scrollToElement(r.ref,{offset:t})},$transition:function(e,t,r){var n=this,o=this.$el(e);o&&t&&t.styles&&this._app.requireModule("animation").transition(o.ref,t,function(){for(var e=[],i=arguments.length;i--;)e[i]=arguments[i];n._setStyle(o,t.styles),r&&r.apply(void 0,e)})},$getConfig:function(e){var t=this._app.options;return"function"==typeof e&&(console.warn("[JS Framework] the callback of Vm#$getConfig(callback) is deprecated, this api now can directly RETURN config info."),e(t)),t},$sendHttp:function(e,t){console.warn("[JS Framework] Vm#$sendHttp is deprecated, please use \"require('@weex-module/stream').sendHttp(params, callback)\" instead"),this._app.requireModule("stream").sendHttp(e,t)},$openURL:function(e){console.warn("[JS Framework] Vm#$openURL is deprecated, please use \"require('@weex-module/event').openURL(url)\" instead"),this._app.requireModule("event").openURL(e)},$setTitle:function(e){console.warn("[JS Framework] Vm#$setTitle is deprecated, please use \"require('@weex-module/pageInfo').setTitle(title)\" instead"),this._app.requireModule("pageInfo").setTitle(e)},$call:function(e,t){for(var r=[],n=arguments.length-2;n-- >0;)r[n]=arguments[n+2];console.warn("[JS Framework] Vm#$call is deprecated, please use \"require('@weex-module/moduleName')\" instead");var o=this._app.requireModule(e);o&&o[t]&&o[t].apply(o,r)}}),ut=Object.prototype.hasOwnProperty,lt=Object.prototype.toString,pt="[object Object]",ft="__proto__"in{};"undefined"!=typeof Set&&Set.toString().match(/native code/)?st=Set:((st=function(){this.set=Object.create(null)}).prototype.has=function(e){return void 0!==this.set[e]},st.prototype.add=function(e){null==e||this.set[e]||(this.set[e]=1)},st.prototype.clear=function(){this.set=Object.create(null)});var ht=/^@weex-component\//,dt=/^@weex-module\//,vt=/^\.{1,2}\//,mt=/\.js$/,yt=function(e){return!!e.match(ht)},gt=function(e){return!!e.match(dt)},wt=function(e){return!!e.match(vt)},_t=function(e){return!yt(e)&&!gt(e)&&!wt(e)},bt=0;h.target=null;var kt=[];h.prototype.addSub=function(e){this.subs.push(e)},h.prototype.removeSub=function(e){n(this.subs,e)},h.prototype.depend=function(){h.target&&h.target.addDep(this)},h.prototype.notify=function(){for(var e=this.subs.slice(),t=0,r=e.length;t<r;t++)e[t].update()};var Et=0;y.prototype.get=function(){d(this);var e=this.getter.call(this.vm,this.vm);return this.deep&&g(e),v(),this.cleanupDeps(),e},y.prototype.addDep=function(e){var t=e.id;this.newDepIds.has(t)||(this.newDepIds.add(t),this.newDeps.push(e),this.depIds.has(t)||e.addSub(this))},y.prototype.cleanupDeps=function(){for(var e=this,t=this.deps.length;t--;){var r=e.deps[t];e.newDepIds.has(r.id)||r.removeSub(e)}var n=this.depIds;this.depIds=this.newDepIds,this.newDepIds=n,this.newDepIds.clear(),n=this.deps,this.deps=this.newDeps,this.newDeps=n,this.newDeps.length=0},y.prototype.update=function(e){this.lazy?this.dirty=!0:this.run()},y.prototype.run=function(){if(this.active){var e=this.get();if(e!==this.value||(a(e)||this.deep)&&!this.shallow){var t=this.value;this.value=e,this.cb.call(this.vm,e,t)}this.queued=this.shallow=!1}},y.prototype.evaluate=function(){this.value=this.get(),this.dirty=!1},y.prototype.depend=function(){for(var e=this,t=this.deps.length;t--;)e.deps[t].depend()},y.prototype.teardown=function(){var e=this;if(this.active){this.vm._isBeingDestroyed||this.vm._vForRemoving||n(this.vm._watchers,this);for(var t=this.deps.length;t--;)e.deps[t].removeSub(e);this.active=!1,this.vm=this.cb=this.value=null}};var St=u(),jt=Array.prototype,$t=Object.create(jt);["push","pop","shift","unshift","splice","sort","reverse"].forEach(function(e){var t=jt[e];r($t,e,function(){for(var r=arguments,n=arguments.length,o=new Array(n);n--;)o[n]=r[n];var i,a=t.apply(this,o),s=this.__ob__;switch(e){case"push":case"unshift":i=o;break;case"splice":i=o.slice(2)}return i&&s.observeArray(i),s.dep.notify(),a})}),r(jt,"$set",function(e,t){return console.warn('[JS Framework] "Array.prototype.$set" is not a standard API, it will be removed in the next version.'),e>=this.length&&(this.length=e+1),this.splice(e,1,t)[0]}),r(jt,"$remove",function(e){console.warn('[JS Framework] "Array.prototype.$remove" is not a standard API, it will be removed in the next version.'),this.length&&("number"!=typeof e&&(e=this.indexOf(e)),e>-1&&this.splice(e,1))});var xt=Object.getOwnPropertyNames($t);w.prototype.walk=function(e){var t=this;for(var r in e)t.convert(r,e[r])},w.prototype.observeArray=function(e){for(var t=0,r=e.length;t<r;t++)k(e[t])},w.prototype.convert=function(e,t){E(this.value,e,t)},w.prototype.addVm=function(e){(this.vms||(this.vms=[])).push(e)},w.prototype.removeVm=function(e){n(this.vms,e)};var Ot=["$index","$value","$event"],Mt={nativeComponentMap:{text:!0,image:!0,container:!0,slider:{type:"slider",append:"tree"},cell:{type:"cell",append:"tree"}}},At=Mt.nativeComponentMap,Ct={attr:"setAttr",style:"setStyle",event:"addEvent"},Ft=1,Tt=["init","created","ready","destroyed"];!function(e){e.$emit=Oe,e.$dispatch=Me,e.$broadcast=Ae,e.$on=Ce,e.$off=Fe}(Ve.prototype),Ve.prototype.$watch=function(e,t){Z(this,e,t)},Ve.set=S,Ve.delete=function(e,t){if(o(e,t)){delete e[t];var r=e.__ob__;if(r){if(r.dep.notify(),r.vms)for(var n=r.vms.length;n--;)$(r.vms[n],t)}else e._isVue&&delete e._data[t]}};var Vt={},It=function(e,t){return t={exports:{}},e(t,t.exports),t.exports}(function(e,t){function r(e,t){if(e instanceof n)return e;if("string"!=typeof e)return null;if(e.length>M)return null;if(!(t?C[H]:C[X]).test(e))return null;try{return new n(e,t)}catch(e){return null}}function n(e,t){if(e instanceof n){if(e.loose===t)return e;e=e.version}else if("string"!=typeof e)throw new TypeError("Invalid Version: "+e);if(e.length>M)throw new TypeError("version is longer than "+M+" characters");if(!(this instanceof n))return new n(e,t);O("SemVer",e,t),this.loose=t;var r=e.trim().match(t?C[H]:C[X]);if(!r)throw new TypeError("Invalid Version: "+e);if(this.raw=e,this.major=+r[1],this.minor=+r[2],this.patch=+r[3],this.major>A||this.major<0)throw new TypeError("Invalid major version");if(this.minor>A||this.minor<0)throw new TypeError("Invalid minor version");if(this.patch>A||this.patch<0)throw new TypeError("Invalid patch version");r[4]?this.prerelease=r[4].split(".").map(function(e){if(/^[0-9]+$/.test(e)){var t=+e;if(t>=0&&t<A)return t}return e}):this.prerelease=[],this.build=r[5]?r[5].split("."):[],this.format()}function o(e,t){var r=ye.test(e),n=ye.test(t);return r&&n&&(e=+e,t=+t),r&&!n?-1:n&&!r?1:e<t?-1:e>t?1:0}function i(e,t,r){return new n(e,r).compare(new n(t,r))}function a(e,t,r){return i(e,t,r)>0}function s(e,t,r){return i(e,t,r)<0}function c(e,t,r){return 0===i(e,t,r)}function u(e,t,r){return 0!==i(e,t,r)}function l(e,t,r){return i(e,t,r)>=0}function p(e,t,r){return i(e,t,r)<=0}function f(e,t,r,n){var o;switch(t){case"===":"object"==typeof e&&(e=e.version),"object"==typeof r&&(r=r.version),o=e===r;break;case"!==":"object"==typeof e&&(e=e.version),"object"==typeof r&&(r=r.version),o=e!==r;break;case"":case"=":case"==":o=c(e,r,n);break;case"!=":o=u(e,r,n);break;case">":o=a(e,r,n);break;case">=":o=l(e,r,n);break;case"<":o=s(e,r,n);break;case"<=":o=p(e,r,n);break;default:throw new TypeError("Invalid operator: "+t)}return o}function h(e,t){if(e instanceof h){if(e.loose===t)return e;e=e.value}if(!(this instanceof h))return new h(e,t);O("comparator",e,t),this.loose=t,this.parse(e),this.semver===ge?this.value="":this.value=this.operator+this.semver.version,O("comp",this)}function d(e,t){if(e instanceof d)return e.loose===t?e:new d(e.raw,t);if(e instanceof h)return new d(e.value,t);if(!(this instanceof d))return new d(e,t);if(this.loose=t,this.raw=e,this.set=e.split(/\s*\|\|\s*/).map(function(e){return this.parseRange(e.trim())},this).filter(function(e){return e.length}),!this.set.length)throw new TypeError("Invalid SemVer Range: "+e);this.format()}function v(e,t){return O("comp",e),e=w(e,t),O("caret",e),e=y(e,t),O("tildes",e),e=b(e,t),O("xrange",e),e=E(e,t),O("stars",e),e}function m(e){return!e||"x"===e.toLowerCase()||"*"===e}function y(e,t){return e.trim().split(/\s+/).map(function(e){return g(e,t)}).join(" ")}function g(e,t){var r=t?C[ie]:C[oe];return e.replace(r,function(t,r,n,o,i){O("tilde",e,t,r,n,o,i);var a;return m(r)?a="":m(n)?a=">="+r+".0.0 <"+(+r+1)+".0.0":m(o)?a=">="+r+"."+n+".0 <"+r+"."+(+n+1)+".0":i?(O("replaceTilde pr",i),"-"!==i.charAt(0)&&(i="-"+i),a=">="+r+"."+n+"."+o+i+" <"+r+"."+(+n+1)+".0"):a=">="+r+"."+n+"."+o+" <"+r+"."+(+n+1)+".0",O("tilde return",a),a})}function w(e,t){return e.trim().split(/\s+/).map(function(e){return _(e,t)}).join(" ")}function _(e,t){O("caret",e,t);var r=t?C[ue]:C[ce];return e.replace(r,function(t,r,n,o,i){O("caret",e,t,r,n,o,i);var a;return m(r)?a="":m(n)?a=">="+r+".0.0 <"+(+r+1)+".0.0":m(o)?a="0"===r?">="+r+"."+n+".0 <"+r+"."+(+n+1)+".0":">="+r+"."+n+".0 <"+(+r+1)+".0.0":i?(O("replaceCaret pr",i),"-"!==i.charAt(0)&&(i="-"+i),a="0"===r?"0"===n?">="+r+"."+n+"."+o+i+" <"+r+"."+n+"."+(+o+1):">="+r+"."+n+"."+o+i+" <"+r+"."+(+n+1)+".0":">="+r+"."+n+"."+o+i+" <"+(+r+1)+".0.0"):(O("no pr"),a="0"===r?"0"===n?">="+r+"."+n+"."+o+" <"+r+"."+n+"."+(+o+1):">="+r+"."+n+"."+o+" <"+r+"."+(+n+1)+".0":">="+r+"."+n+"."+o+" <"+(+r+1)+".0.0"),O("caret return",a),a})}function b(e,t){return O("replaceXRanges",e,t),e.split(/\s+/).map(function(e){return k(e,t)}).join(" ")}function k(e,t){e=e.trim();var r=t?C[te]:C[ee];return e.replace(r,function(t,r,n,o,i,a){O("xRange",e,t,r,n,o,i,a);var s=m(n),c=s||m(o),u=c||m(i),l=u;return"="===r&&l&&(r=""),s?t=">"===r||"<"===r?"<0.0.0":"*":r&&l?(c&&(o=0),u&&(i=0),">"===r?(r=">=",c?(n=+n+1,o=0,i=0):u&&(o=+o+1,i=0)):"<="===r&&(r="<",c?n=+n+1:o=+o+1),t=r+n+"."+o+"."+i):c?t=">="+n+".0.0 <"+(+n+1)+".0.0":u&&(t=">="+n+"."+o+".0 <"+n+"."+(+o+1)+".0"),O("xRange return",t),t})}function E(e,t){return O("replaceStars",e,t),e.trim().replace(C[ve],"")}function S(e,t,r,n,o,i,a,s,c,u,l,p,f){return t=m(r)?"":m(n)?">="+r+".0.0":m(o)?">="+r+"."+n+".0":">="+t,s=m(c)?"":m(u)?"<"+(+c+1)+".0.0":m(l)?"<"+c+"."+(+u+1)+".0":p?"<="+c+"."+u+"."+l+"-"+p:"<="+s,(t+" "+s).trim()}function j(e,t){for(r=0;r<e.length;r++)if(!e[r].test(t))return!1;if(t.prerelease.length){for(var r=0;r<e.length;r++)if(O(e[r].semver),e[r].semver!==ge&&e[r].semver.prerelease.length>0){var n=e[r].semver;if(n.major===t.major&&n.minor===t.minor&&n.patch===t.patch)return!0}return!1}return!0}function $(e,t,r){try{t=new d(t,r)}catch(e){return!1}return t.test(e)}function x(e,t,r,o){e=new n(e,o),t=new d(t,o);var i,c,u,f,v;switch(r){case">":i=a,c=p,u=s,f=">",v=">=";break;case"<":i=s,c=l,u=a,f="<",v="<=";break;default:throw new TypeError('Must provide a hilo val of "<" or ">"')}if($(e,t,o))return!1;for(var m=0;m<t.set.length;++m){var y=null,g=null;if(t.set[m].forEach(function(e){e.semver===ge&&(e=new h(">=0.0.0")),y=y||e,g=g||e,i(e.semver,y.semver,o)?y=e:u(e.semver,g.semver,o)&&(g=e)}),y.operator===f||y.operator===v)return!1;if((!g.operator||g.operator===f)&&c(e,g.semver))return!1;if(g.operator===v&&u(e,g.semver))return!1}return!0}t=e.exports=n;var O;"object"==typeof process&&process.env,O=function(){},t.SEMVER_SPEC_VERSION="2.0.0";var M=256,A=Number.MAX_SAFE_INTEGER||9007199254740991,C=t.re=[],F=t.src=[],T=0,V=T++;F[V]="0|[1-9]\\d*";var I=T++;F[I]="[0-9]+";var J=T++;F[J]="\\d*[a-zA-Z-][a-zA-Z0-9-]*";var D=T++;F[D]="("+F[V]+")\\.("+F[V]+")\\.("+F[V]+")";var R=T++;F[R]="("+F[I]+")\\.("+F[I]+")\\.("+F[I]+")";var P=T++;F[P]="(?:"+F[V]+"|"+F[J]+")";var q=T++;F[q]="(?:"+F[I]+"|"+F[J]+")";var B=T++;F[B]="(?:-("+F[P]+"(?:\\."+F[P]+")*))";var L=T++;F[L]="(?:-?("+F[q]+"(?:\\."+F[q]+")*))";var N=T++;F[N]="[0-9A-Za-z-]+";var z=T++;F[z]="(?:\\+("+F[N]+"(?:\\."+F[N]+")*))";var X=T++,U="v?"+F[D]+F[B]+"?"+F[z]+"?";F[X]="^"+U+"$";var W="[v=\\s]*"+F[R]+F[L]+"?"+F[z]+"?",H=T++;F[H]="^"+W+"$";var Z=T++;F[Z]="((?:<|>)?=?)";var G=T++;F[G]=F[I]+"|x|X|\\*";var K=T++;F[K]=F[V]+"|x|X|\\*";var Q=T++;F[Q]="[v=\\s]*("+F[K]+")(?:\\.("+F[K]+")(?:\\.("+F[K]+")(?:"+F[B]+")?"+F[z]+"?)?)?";var Y=T++;F[Y]="[v=\\s]*("+F[G]+")(?:\\.("+F[G]+")(?:\\.("+F[G]+")(?:"+F[L]+")?"+F[z]+"?)?)?";var ee=T++;F[ee]="^"+F[Z]+"\\s*"+F[Q]+"$";var te=T++;F[te]="^"+F[Z]+"\\s*"+F[Y]+"$";var re=T++;F[re]="(?:~>?)";var ne=T++;F[ne]="(\\s*)"+F[re]+"\\s+",C[ne]=new RegExp(F[ne],"g");var oe=T++;F[oe]="^"+F[re]+F[Q]+"$";var ie=T++;F[ie]="^"+F[re]+F[Y]+"$";var ae=T++;F[ae]="(?:\\^)";var se=T++;F[se]="(\\s*)"+F[ae]+"\\s+",C[se]=new RegExp(F[se],"g");var ce=T++;F[ce]="^"+F[ae]+F[Q]+"$";var ue=T++;F[ue]="^"+F[ae]+F[Y]+"$";var le=T++;F[le]="^"+F[Z]+"\\s*("+W+")$|^$";var pe=T++;F[pe]="^"+F[Z]+"\\s*("+U+")$|^$";var fe=T++;F[fe]="(\\s*)"+F[Z]+"\\s*("+W+"|"+F[Q]+")",C[fe]=new RegExp(F[fe],"g");var he=T++;F[he]="^\\s*("+F[Q]+")\\s+-\\s+("+F[Q]+")\\s*$";var de=T++;F[de]="^\\s*("+F[Y]+")\\s+-\\s+("+F[Y]+")\\s*$";var ve=T++;F[ve]="(<|>)?=?\\s*\\*";for(var me=0;me<T;me++)O(me,F[me]),C[me]||(C[me]=new RegExp(F[me]));t.parse=r,t.valid=function(e,t){var n=r(e,t);return n?n.version:null},t.clean=function(e,t){var n=r(e.trim().replace(/^[=v]+/,""),t);return n?n.version:null},t.SemVer=n,n.prototype.format=function(){return this.version=this.major+"."+this.minor+"."+this.patch,this.prerelease.length&&(this.version+="-"+this.prerelease.join(".")),this.version},n.prototype.toString=function(){return this.version},n.prototype.compare=function(e){return O("SemVer.compare",this.version,this.loose,e),e instanceof n||(e=new n(e,this.loose)),this.compareMain(e)||this.comparePre(e)},n.prototype.compareMain=function(e){return e instanceof n||(e=new n(e,this.loose)),o(this.major,e.major)||o(this.minor,e.minor)||o(this.patch,e.patch)},n.prototype.comparePre=function(e){var t=this;if(e instanceof n||(e=new n(e,this.loose)),this.prerelease.length&&!e.prerelease.length)return-1;if(!this.prerelease.length&&e.prerelease.length)return 1;if(!this.prerelease.length&&!e.prerelease.length)return 0;var r=0;do{var i=t.prerelease[r],a=e.prerelease[r];if(O("prerelease compare",r,i,a),void 0===i&&void 0===a)return 0;if(void 0===a)return 1;if(void 0===i)return-1;if(i!==a)return o(i,a)}while(++r)},n.prototype.inc=function(e,t){var r=this;switch(e){case"premajor":this.prerelease.length=0,this.patch=0,this.minor=0,this.major++,this.inc("pre",t);break;case"preminor":this.prerelease.length=0,this.patch=0,this.minor++,this.inc("pre",t);break;case"prepatch":this.prerelease.length=0,this.inc("patch",t),this.inc("pre",t);break;case"prerelease":0===this.prerelease.length&&this.inc("patch",t),this.inc("pre",t);break;case"major":0===this.minor&&0===this.patch&&0!==this.prerelease.length||this.major++,this.minor=0,this.patch=0,this.prerelease=[];break;case"minor":0===this.patch&&0!==this.prerelease.length||this.minor++,this.patch=0,this.prerelease=[];break;case"patch":0===this.prerelease.length&&this.patch++,this.prerelease=[];break;case"pre":if(0===this.prerelease.length)this.prerelease=[0];else{for(var n=this.prerelease.length;--n>=0;)"number"==typeof r.prerelease[n]&&(r.prerelease[n]++,n=-2);-1===n&&this.prerelease.push(0)}t&&(this.prerelease[0]===t?isNaN(this.prerelease[1])&&(this.prerelease=[t,0]):this.prerelease=[t,0]);break;default:throw new Error("invalid increment argument: "+e)}return this.format(),this.raw=this.version,this},t.inc=function(e,t,r,o){"string"==typeof r&&(o=r,r=void 0);try{return new n(e,r).inc(t,o).version}catch(e){return null}},t.diff=function(e,t){if(c(e,t))return null;var n=r(e),o=r(t);if(n.prerelease.length||o.prerelease.length){for(var i in n)if(("major"===i||"minor"===i||"patch"===i)&&n[i]!==o[i])return"pre"+i;return"prerelease"}for(var i in n)if(("major"===i||"minor"===i||"patch"===i)&&n[i]!==o[i])return i},t.compareIdentifiers=o;var ye=/^[0-9]+$/;t.rcompareIdentifiers=function(e,t){return o(t,e)},t.major=function(e,t){return new n(e,t).major},t.minor=function(e,t){return new n(e,t).minor},t.patch=function(e,t){return new n(e,t).patch},t.compare=i,t.compareLoose=function(e,t){return i(e,t,!0)},t.rcompare=function(e,t,r){return i(t,e,r)},t.sort=function(e,r){return e.sort(function(e,n){return t.compare(e,n,r)})},t.rsort=function(e,r){return e.sort(function(e,n){return t.rcompare(e,n,r)})},t.gt=a,t.lt=s,t.eq=c,t.neq=u,t.gte=l,t.lte=p,t.cmp=f,t.Comparator=h;var ge={};h.prototype.parse=function(e){var t=this.loose?C[le]:C[pe],r=e.match(t);if(!r)throw new TypeError("Invalid comparator: "+e);this.operator=r[1],"="===this.operator&&(this.operator=""),r[2]?this.semver=new n(r[2],this.loose):this.semver=ge},h.prototype.toString=function(){return this.value},h.prototype.test=function(e){return O("Comparator.test",e,this.loose),this.semver===ge||("string"==typeof e&&(e=new n(e,this.loose)),f(e,this.operator,this.semver,this.loose))},h.prototype.intersects=function(e,t){if(!(e instanceof h))throw new TypeError("a Comparator is required");var r;if(""===this.operator)return r=new d(e.value,t),$(this.value,r,t);if(""===e.operator)return r=new d(this.value,t),$(e.semver,r,t);var n=!(">="!==this.operator&&">"!==this.operator||">="!==e.operator&&">"!==e.operator),o=!("<="!==this.operator&&"<"!==this.operator||"<="!==e.operator&&"<"!==e.operator),i=this.semver.version===e.semver.version,a=!(">="!==this.operator&&"<="!==this.operator||">="!==e.operator&&"<="!==e.operator),s=f(this.semver,"<",e.semver,t)&&(">="===this.operator||">"===this.operator)&&("<="===e.operator||"<"===e.operator),c=f(this.semver,">",e.semver,t)&&("<="===this.operator||"<"===this.operator)&&(">="===e.operator||">"===e.operator);return n||o||i&&a||s||c},t.Range=d,d.prototype.format=function(){return this.range=this.set.map(function(e){return e.join(" ").trim()}).join("||").trim(),this.range},d.prototype.toString=function(){return this.range},d.prototype.parseRange=function(e){var t=this.loose;e=e.trim(),O("range",e,t);var r=t?C[de]:C[he];e=e.replace(r,S),O("hyphen replace",e),e=e.replace(C[fe],"$1$2$3"),O("comparator trim",e,C[fe]),e=(e=(e=e.replace(C[ne],"$1~")).replace(C[se],"$1^")).split(/\s+/).join(" ");var n=t?C[le]:C[pe],o=e.split(" ").map(function(e){return v(e,t)}).join(" ").split(/\s+/);return this.loose&&(o=o.filter(function(e){return!!e.match(n)})),o=o.map(function(e){return new h(e,t)})},d.prototype.intersects=function(e,t){if(!(e instanceof d))throw new TypeError("a Range is required");return this.set.some(function(r){return r.every(function(r){return e.set.some(function(e){return e.every(function(e){return r.intersects(e,t)})})})})},t.toComparators=function(e,t){return new d(e,t).set.map(function(e){return e.map(function(e){return e.value}).join(" ").trim().split(" ")})},d.prototype.test=function(e){var t=this;if(!e)return!1;"string"==typeof e&&(e=new n(e,this.loose));for(var r=0;r<this.set.length;r++)if(j(t.set[r],e))return!0;return!1},t.satisfies=$,t.maxSatisfying=function(e,t,r){var o=null,i=null;try{var a=new d(t,r)}catch(e){return null}return e.forEach(function(e){a.test(e)&&(o&&-1!==i.compare(e)||(i=new n(o=e,r)))}),o},t.minSatisfying=function(e,t,r){var o=null,i=null;try{var a=new d(t,r)}catch(e){return null}return e.forEach(function(e){a.test(e)&&(o&&1!==i.compare(e)||(i=new n(o=e,r)))}),o},t.validRange=function(e,t){try{return new d(e,t).range||"*"}catch(e){return null}},t.ltr=function(e,t,r){return x(e,t,"<",r)},t.gtr=function(e,t,r){return x(e,t,">",r)},t.outside=x,t.prerelease=function(e,t){var n=r(e,t);return n&&n.prerelease.length?n.prerelease:null},t.intersects=function(e,t,r){return e=new d(e,r),t=new d(t,r),e.intersects(t)}}),Jt=function(e,t){for(var r=[],n=arguments.length-2;n-- >0;)r[n]=arguments[n+2];console.debug("[JS Framework] define a component "+t);var o,i;if("function"==typeof(i=r.length>1?r[1]:r[0])&&(o=i,i=null),o){var a={exports:{}};o(function(t){if(yt(t)){var r=p(t);return Re(e,r)}if(gt(t)){var n=p(t);return e.requireModule(n)}if(wt(t)||_t(t)){var o=f(t);return e.commonModules[o]}},a.exports,a),i=a.exports}if(yt(t)){var s=p(t);Pe(e,s,i)}else if(gt(t)){var c;Ie((c={},c[p(t)]=i,c))}else if(wt(t)){var u=f(t);e.commonModules[u]=i}else if(_t(t)){var l=f(t);i.template||i.style||i.methods?Pe(e,l,i):e.commonModules[l]=i}},Dt=function(e){this.id=e,this.map=[],this.hooks=[]};Dt.prototype.isEmpty=function(){return 0===this.map.length},Dt.prototype.append=function(e,t,r,n){var o=this;this.hasTimer||(this.hasTimer=!0,setTimeout(function(){o.hasTimer=!1,o.flush(!0)},0));var i=this.map;i[t]||(i[t]={});var a=i[t];a[e]||(a[e]={}),"element"===e?(a[e][r]||(a[e][r]=[]),a[e][r].push(n)):a[e][r]=n},Dt.prototype.flush=function(e){var t=this.map.slice();this.map.length=0,t.forEach(function(e){nt(e,"repeat"),nt(e,"shown"),ot(e,"element")});var r=this.hooks.slice();this.hooks.length=0,r.forEach(function(e){e()}),this.isEmpty()||this.flush()},Dt.prototype.then=function(e){this.hooks.push(e)},it.prototype.requireModule=function(e){return De(this,e)},it.prototype.updateActions=function(){return Qe(this)},it.prototype.callTasks=function(e){return Ye(this,e)},Object.freeze(it),Object.freeze(it.prototype);var Rt={},Pt=Mt.nativeComponentMap;global.registerMethods=at;var qt={fireEvent:function(e){for(var t=[],r=arguments.length-1;r-- >0;)t[r]=arguments[r+1];return Ge.apply(void 0,[Rt[e]].concat(t))},callback:function(e){for(var t=[],r=arguments.length-1;r-- >0;)t[r]=arguments[r+1];return Ke.apply(void 0,[Rt[e]].concat(t))}};at(ct),Object.freeze(Ve),e.registerComponents=function(e){Array.isArray(e)&&e.forEach(function(e){e&&("string"==typeof e?Pt[e]=!0:"object"==typeof e&&"string"==typeof e.type&&(Pt[e.type]=e))})},e.registerModules=function(e){"object"==typeof e&&Ie(e)},e.registerMethods=at,e.createInstance=function(e,t,r,n,o){var i=(o||{}).services;m();var a=Rt[e];r=r||{};var s;return a?s=new Error('invalid instance id "'+e+'"'):(a=new it(e,r),Rt[e]=a,s=et(a,t,n,i)),s instanceof Error?s:a},e.init=function(e){Mt.Document=e.Document,Mt.Element=e.Element,Mt.Comment=e.Comment,Mt.sendTasks=e.sendTasks,Mt.Listener=e.Listener},e.refreshInstance=function(e,t){var r=Rt[e];return r?Ue(r,t):new Error('invalid instance id "'+e+'"')},e.destroyInstance=function(e){"function"==typeof markupState&&markupState(),m();var t=Rt[e];if(!t)return new Error('invalid instance id "'+e+'"');We(t),delete Rt[e];var r=Math.round(e);return r>0&&(r%18||"function"!=typeof notifyTrimMemory||notifyTrimMemory()),Rt},e.receiveTasks=function(e,t){if(Rt[e]&&Array.isArray(t)){var r=[];return t.forEach(function(t){var n=qt[t.method],o=[].concat(t.args);"function"==typeof n&&(o.unshift(e),r.push(n.apply(void 0,o)))}),r}return new Error('invalid instance id "'+e+'" or tasks')},e.getRoot=function(e){var t=Rt[e];return t?Ze(t):new Error('invalid instance id "'+e+'"')},Object.defineProperty(e,"__esModule",{value:!0})});
diff --git a/packages/weex-legacy-framework/package.json b/packages/weex-legacy-framework/package.json
deleted file mode 100644
index 8b07efc..0000000
--- a/packages/weex-legacy-framework/package.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
-  "name": "weex-legacy-framework",
-  "version": "0.21.6",
-  "description": "Weex Legacy Framework",
-  "main": "index.js",
-  "engines": {
-    "node": ">=4"
-  },
-  "homepage": "https://github.com/apache/incubator-weex/",
-  "keywords": [
-    "weex",
-    "hybrid",
-    "mvvm",
-    "javascript",
-    "runtime"
-  ],
-  "repository": {
-    "type": "git",
-    "url": "git+ssh://git@github.com/apache/incubator-weex.git"
-  },
-  "license": "Apache-2.0"
-}
diff --git a/packages/weex-vanilla-framework/.npmignore b/packages/weex-vanilla-framework/.npmignore
deleted file mode 100644
index 1cb6dac..0000000
--- a/packages/weex-vanilla-framework/.npmignore
+++ /dev/null
@@ -1,4 +0,0 @@
-node_modules
-package-lock.json
-*.log
-*.gz
diff --git a/packages/weex-vanilla-framework/index.js b/packages/weex-vanilla-framework/index.js
deleted file mode 100644
index 503b05a..0000000
--- a/packages/weex-vanilla-framework/index.js
+++ /dev/null
@@ -1,136 +0,0 @@
-/* Weex Vanilla Framework 0.21.7, Build 2017-08-08 11:59. */
-
-(function (global, factory) {
-  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
-  typeof define === 'function' && define.amd ? define(['exports'], factory) :
-  (factory((global.WeexVanillaFramework = global.WeexVanillaFramework || {})));
-}(this, (function (exports) { 'use strict';
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-var config = {};
-
-var instanceMap = {};
-
-function init (cfg) {
-  config.Document = cfg.Document;
-  config.Element = cfg.Element;
-  config.Comment = cfg.Comment;
-  config.sendTasks = cfg.sendTasks;
-}
-
-function createInstance (id, code, options, data, serviceObjects) {
-  if ( options === void 0 ) options = {};
-  if ( data === void 0 ) data = {};
-  if ( serviceObjects === void 0 ) serviceObjects = {};
-
-  var document = new config.Document(id, options.bundleUrl);
-  var callbacks = {};
-  var instance = { id: id, data: data, document: document, callbacks: callbacks };
-
-  var lastCallbackId = 0;
-  document.addCallback = function (func) {
-    lastCallbackId++;
-    callbacks[lastCallbackId] = func;
-    return lastCallbackId
-  };
-  document.handleCallback = function (funcId, data, ifLast) {
-    var callback = callbacks[funcId];
-    if (ifLast) {
-      delete callbacks[funcId];
-    }
-    return callback(data)
-  };
-  instanceMap[id] = instance;
-
-  var globalObjects = Object.assign({
-    Document: config.Document,
-    Element: config.Element,
-    Comment: config.Comment,
-    sendTasks: function (tasks) { return config.sendTasks(id, tasks, -1); },
-    options: options,
-    document: document
-  }, serviceObjects);
-
-  var globalKeys = [];
-  var globalValues = [];
-  for (var key in globalObjects) {
-    globalKeys.push(key);
-    globalValues.push(globalObjects[key]);
-  }
-  globalKeys.push(code);
-
-  var result = new (Function.prototype.bind.apply( Function, [ null ].concat( globalKeys) ));
-  result.apply(void 0, globalValues);
-
-  config.sendTasks(id, [{ module: 'dom', method: 'createFinish', args: [] }], -1);
-
-  return instance
-}
-
-function destroyInstance (id) {
-  delete instanceMap[id];
-}
-
-function getRoot (id) {
-  return instanceMap[id].document.body.toJSON()
-}
-
-function receiveTasks (id, tasks) {
-  var jsHandlers = {
-    fireEvent: function (id, ref, type, data, domChanges) {
-      var ref$1 = instanceMap[id];
-      var document = ref$1.document;
-      var el = document.getRef(ref);
-      return document.fireEvent(el, type, data, domChanges)
-    },
-
-    callback: function (id, funcId, data, ifLast) {
-      var ref = instanceMap[id];
-      var document = ref.document;
-      return document.handleCallback(funcId, data, ifLast)
-    }
-  };
-
-  var ref = instanceMap[id] || {};
-  var document = ref.document;
-  if (document && Array.isArray(tasks)) {
-    var results = [];
-    tasks.forEach(function (task) {
-      var handler = jsHandlers[task.method];
-      var args = [].concat( task.args );
-      if (typeof handler === 'function') {
-        args.unshift(id);
-        results.push(handler.apply(void 0, args));
-      }
-    });
-    return results
-  }
-}
-
-exports.init = init;
-exports.createInstance = createInstance;
-exports.destroyInstance = destroyInstance;
-exports.getRoot = getRoot;
-exports.receiveTasks = receiveTasks;
-
-Object.defineProperty(exports, '__esModule', { value: true });
-
-})));
-//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjpudWxsLCJzb3VyY2VzIjpbIi4uLy4uL2h0bWw1L2ZyYW1ld29ya3MvdmFuaWxsYS9pbmRleC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZVxuICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlXG4gKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvblxuICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZVxuICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZVxuICogXCJMaWNlbnNlXCIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlXG4gKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsXG4gKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhblxuICogXCJBUyBJU1wiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTllcbiAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZVxuICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9uc1xuICogdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbmNvbnN0IGNvbmZpZyA9IHt9XG5cbmNvbnN0IGluc3RhbmNlTWFwID0ge31cblxuZXhwb3J0IGZ1bmN0aW9uIGluaXQgKGNmZykge1xuICBjb25maWcuRG9jdW1lbnQgPSBjZmcuRG9jdW1lbnRcbiAgY29uZmlnLkVsZW1lbnQgPSBjZmcuRWxlbWVudFxuICBjb25maWcuQ29tbWVudCA9IGNmZy5Db21tZW50XG4gIGNvbmZpZy5zZW5kVGFza3MgPSBjZmcuc2VuZFRhc2tzXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVJbnN0YW5jZSAoaWQsIGNvZGUsIG9wdGlvbnMgPSB7fSwgZGF0YSA9IHt9LCBzZXJ2aWNlT2JqZWN0cyA9IHt9KSB7XG4gIGNvbnN0IGRvY3VtZW50ID0gbmV3IGNvbmZpZy5Eb2N1bWVudChpZCwgb3B0aW9ucy5idW5kbGVVcmwpXG4gIGNvbnN0IGNhbGxiYWNrcyA9IHt9XG4gIGNvbnN0IGluc3RhbmNlID0geyBpZCwgZGF0YSwgZG9jdW1lbnQsIGNhbGxiYWNrcyB9XG5cbiAgbGV0IGxhc3RDYWxsYmFja0lkID0gMFxuICBkb2N1bWVudC5hZGRDYWxsYmFjayA9IGZ1bmMgPT4ge1xuICAgIGxhc3RDYWxsYmFja0lkKytcbiAgICBjYWxsYmFja3NbbGFzdENhbGxiYWNrSWRdID0gZnVuY1xuICAgIHJldHVybiBsYXN0Q2FsbGJhY2tJZFxuICB9XG4gIGRvY3VtZW50LmhhbmRsZUNhbGxiYWNrID0gKGZ1bmNJZCwgZGF0YSwgaWZMYXN0KSA9PiB7XG4gICAgY29uc3QgY2FsbGJhY2sgPSBjYWxsYmFja3NbZnVuY0lkXVxuICAgIGlmIChpZkxhc3QpIHtcbiAgICAgIGRlbGV0ZSBjYWxsYmFja3NbZnVuY0lkXVxuICAgIH1cbiAgICByZXR1cm4gY2FsbGJhY2soZGF0YSlcbiAgfVxuICBpbnN0YW5jZU1hcFtpZF0gPSBpbnN0YW5jZVxuXG4gIGNvbnN0IGdsb2JhbE9iamVjdHMgPSBPYmplY3QuYXNzaWduKHtcbiAgICBEb2N1bWVudDogY29uZmlnLkRvY3VtZW50LFxuICAgIEVsZW1lbnQ6IGNvbmZpZy5FbGVtZW50LFxuICAgIENvbW1lbnQ6IGNvbmZpZy5Db21tZW50LFxuICAgIHNlbmRUYXNrczogdGFza3MgPT4gY29uZmlnLnNlbmRUYXNrcyhpZCwgdGFza3MsIC0xKSxcbiAgICBvcHRpb25zLFxuICAgIGRvY3VtZW50XG4gIH0sIHNlcnZpY2VPYmplY3RzKVxuXG4gIGNvbnN0IGdsb2JhbEtleXMgPSBbXVxuICBjb25zdCBnbG9iYWxWYWx1ZXMgPSBbXVxuICBmb3IgKGNvbnN0IGtleSBpbiBnbG9iYWxPYmplY3RzKSB7XG4gICAgZ2xvYmFsS2V5cy5wdXNoKGtleSlcbiAgICBnbG9iYWxWYWx1ZXMucHVzaChnbG9iYWxPYmplY3RzW2tleV0pXG4gIH1cbiAgZ2xvYmFsS2V5cy5wdXNoKGNvZGUpXG5cbiAgY29uc3QgcmVzdWx0ID0gbmV3IEZ1bmN0aW9uKC4uLmdsb2JhbEtleXMpXG4gIHJlc3VsdCguLi5nbG9iYWxWYWx1ZXMpXG5cbiAgY29uZmlnLnNlbmRUYXNrcyhpZCwgW3sgbW9kdWxlOiAnZG9tJywgbWV0aG9kOiAnY3JlYXRlRmluaXNoJywgYXJnczogW10gfV0sIC0xKVxuXG4gIHJldHVybiBpbnN0YW5jZVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZGVzdHJveUluc3RhbmNlIChpZCkge1xuICBkZWxldGUgaW5zdGFuY2VNYXBbaWRdXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRSb290IChpZCkge1xuICByZXR1cm4gaW5zdGFuY2VNYXBbaWRdLmRvY3VtZW50LmJvZHkudG9KU09OKClcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlY2VpdmVUYXNrcyAoaWQsIHRhc2tzKSB7XG4gIGNvbnN0IGpzSGFuZGxlcnMgPSB7XG4gICAgZmlyZUV2ZW50OiAoaWQsIHJlZiwgdHlwZSwgZGF0YSwgZG9tQ2hhbmdlcykgPT4ge1xuICAgICAgY29uc3QgeyBkb2N1bWVudCB9ID0gaW5zdGFuY2VNYXBbaWRdXG4gICAgICBjb25zdCBlbCA9IGRvY3VtZW50LmdldFJlZihyZWYpXG4gICAgICByZXR1cm4gZG9jdW1lbnQuZmlyZUV2ZW50KGVsLCB0eXBlLCBkYXRhLCBkb21DaGFuZ2VzKVxuICAgIH0sXG5cbiAgICBjYWxsYmFjazogKGlkLCBmdW5jSWQsIGRhdGEsIGlmTGFzdCkgPT4ge1xuICAgICAgY29uc3QgeyBkb2N1bWVudCB9ID0gaW5zdGFuY2VNYXBbaWRdXG4gICAgICByZXR1cm4gZG9jdW1lbnQuaGFuZGxlQ2FsbGJhY2soZnVuY0lkLCBkYXRhLCBpZkxhc3QpXG4gICAgfVxuICB9XG5cbiAgY29uc3QgeyBkb2N1bWVudCB9ID0gaW5zdGFuY2VNYXBbaWRdIHx8IHt9XG4gIGlmIChkb2N1bWVudCAmJiBBcnJheS5pc0FycmF5KHRhc2tzKSkge1xuICAgIGNvbnN0IHJlc3VsdHMgPSBbXVxuICAgIHRhc2tzLmZvckVhY2goKHRhc2spID0+IHtcbiAgICAgIGNvbnN0IGhhbmRsZXIgPSBqc0hhbmRsZXJzW3Rhc2subWV0aG9kXVxuICAgICAgY29uc3QgYXJncyA9IFsuLi50YXNrLmFyZ3NdXG4gICAgICBpZiAodHlwZW9mIGhhbmRsZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgYXJncy51bnNoaWZ0KGlkKVxuICAgICAgICByZXN1bHRzLnB1c2goaGFuZGxlciguLi5hcmdzKSlcbiAgICAgIH1cbiAgICB9KVxuICAgIHJldHVybiByZXN1bHRzXG4gIH1cbn1cbiJdLCJuYW1lcyI6WyJjb25zdCIsImxldCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7QUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBa0JBQSxJQUFNLE1BQU0sR0FBRyxFQUFFLENBQUE7O0FBRWpCQSxJQUFNLFdBQVcsR0FBRyxFQUFFLENBQUE7O0FBRXRCLEFBQU8sU0FBUyxJQUFJLEVBQUUsR0FBRyxFQUFFO0VBQ3pCLE1BQU0sQ0FBQyxRQUFRLEdBQUcsR0FBRyxDQUFDLFFBQVEsQ0FBQTtFQUM5QixNQUFNLENBQUMsT0FBTyxHQUFHLEdBQUcsQ0FB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
diff --git a/packages/weex-vanilla-framework/index.min.js b/packages/weex-vanilla-framework/index.min.js
deleted file mode 100644
index 199508f..0000000
--- a/packages/weex-vanilla-framework/index.min.js
+++ /dev/null
@@ -1 +0,0 @@
-!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n(e.WeexVanillaFramework=e.WeexVanillaFramework||{})}(this,function(e){"use strict";var n={},t={};e.init=function(e){n.Document=e.Document,n.Element=e.Element,n.Comment=e.Comment,n.sendTasks=e.sendTasks},e.createInstance=function(e,o,a,r,c){void 0===a&&(a={}),void 0===r&&(r={}),void 0===c&&(c={});var u=new n.Document(e,a.bundleUrl),i={},d={id:e,data:r,document:u,callbacks:i},s=0;u.addCallback=function(e){return s++,i[s]=e,s},u.handleCallback=function(e,n,t){var o=i[e];return t&&delete i[e],o(n)},t[e]=d;var l=Object.assign({Document:n.Document,Element:n.Element,Comment:n.Comment,sendTasks:function(t){return n.sendTasks(e,t,-1)},options:a,document:u},c),f=[],m=[];for(var p in l)f.push(p),m.push(l[p]);return f.push(o),(new(Function.prototype.bind.apply(Function,[null].concat(f)))).apply(void 0,m),n.sendTasks(e,[{module:"dom",method:"createFinish",args:[]}],-1),d},e.destroyInstance=function(e){delete t[e]},e.getRoot=function(e){return t[e].document.body.toJSON()},e.receiveTasks=function(e,n){var o={fireEvent:function(e,n,o,a,r){var c=t[e].document,u=c.getRef(n);return c.fireEvent(u,o,a,r)},callback:function(e,n,o,a){return t[e].document.handleCallback(n,o,a)}};if((t[e]||{}).document&&Array.isArray(n)){var a=[];return n.forEach(function(n){var t=o[n.method],r=[].concat(n.args);"function"==typeof t&&(r.unshift(e),a.push(t.apply(void 0,r)))}),a}},Object.defineProperty(e,"__esModule",{value:!0})});
diff --git a/packages/weex-vanilla-framework/package.json b/packages/weex-vanilla-framework/package.json
deleted file mode 100644
index 2d1e14a..0000000
--- a/packages/weex-vanilla-framework/package.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  "name": "weex-vanilla-framework",
-  "main": "index.js",
-  "description": "Weex Vanilla Framework",
-  "version": "0.21.7",
-  "engines": {
-    "node": ">=4"
-  },
-  "homepage": "https://github.com/apache/incubator-weex/",
-  "keywords": [
-    "weex",
-    "hybrid",
-    "mvvm",
-    "javascript"
-  ],
-  "license": "Apache-2.0",
-  "repository": {
-    "type": "git",
-    "url": "git+ssh://git@github.com/apache/incubator-weex.git"
-  }
-}
diff --git a/test/js-framework/unit/default/api/methods.js b/test/js-framework/unit/default/api/methods.js
deleted file mode 100644
index 83f6586..0000000
--- a/test/js-framework/unit/default/api/methods.js
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-import chai from 'chai'
-import sinon from 'sinon'
-import sinonChai from 'sinon-chai'
-const { expect } = chai
-chai.use(sinonChai)
-
-import '../../../../../runtime/shared/env/console'
-import * as modules from '../../../../../runtime/frameworks/legacy/api/modules'
-import * as methods from '../../../../../runtime/frameworks/legacy/api/methods'
-import Differ from '../../../../../runtime/frameworks/legacy/app/differ'
-import { initModules, requireModule, clearModules, initMethods } from '../../../../../runtime/frameworks/legacy/app/register'
-
-function Vm () {
-}
-
-describe('built-in methods', () => {
-  let vm
-  const requireSpy = sinon.spy()
-  const moduleSpy = sinon.spy()
-
-  before(() => {
-    clearModules()
-
-    initModules(modules)
-    initMethods(Vm, methods)
-
-    vm = new Vm()
-
-    Object.assign(vm, {
-      _app: {
-        options: {
-          debug: true,
-          bundleUrl: 'path_to_bundleUrl'
-        },
-        differ: new Differ(),
-        requireModule: (name) => {
-          requireSpy(name)
-          const module = requireModule(this, name)
-          const mockModule = {}
-          for (const moduleName in module) {
-            mockModule[moduleName] = function (...args) {
-              moduleSpy(...args)
-              if (typeof args[args.length - 1] === 'function') {
-                args[args.length - 1]()
-              }
-            }
-          }
-          return mockModule
-        }
-      },
-      _setStyle: function () {},
-      _ids: {
-        a: {
-          vm: {},
-          el: {
-            ref: '_root'
-          }
-        }
-      }
-    })
-
-    for (const apiName in vm) {
-      if (apiName.indexOf('$') === 0) {
-        vm[apiName] = sinon.spy(vm, apiName)
-      }
-    }
-    sinon.stub(console, 'warn')
-  })
-
-  beforeEach(() => {
-    requireSpy.reset()
-    moduleSpy.reset()
-    console.warn.reset()
-  })
-
-  after(() => {
-    clearModules()
-    console.warn.restore()
-  })
-
-  it('$', () => {
-    expect(vm.$('a')).to.deep.equal(vm._ids.a.vm)
-    expect(vm.$('invalid')).to.be.undefined
-    expect(console.warn.callCount).to.be.equal(2)
-  })
-
-  it('$el', () => {
-    expect(vm.$el('a')).to.deep.equal(vm._ids.a.el)
-    expect(vm.$el('invalid')).to.be.undefined
-  })
-
-  it('$vm', () => {
-    expect(vm.$vm('a')).to.deep.equal(vm._ids.a.vm)
-    expect(vm.$vm('invalid')).to.be.undefined
-  })
-
-  it('$renderThen', () => {
-    const fnSpy = sinon.spy()
-    vm.$renderThen(fnSpy)
-    vm._app.differ.flush()
-    expect(fnSpy.callCount).to.be.equal(1)
-  })
-
-  it('$scrollTo', () => {
-    vm.$scrollTo('a', 100)
-    expect(vm.$scrollTo('invalid', 100)).to.be.undefined
-    expect(requireSpy.firstCall.args[0]).to.be.equal('dom')
-    expect(moduleSpy.firstCall.args.length).to.be.equal(2)
-  })
-
-  it('$transition', () => {
-    const callback = sinon.spy()
-    vm.$transition('a', { styles: { color: '#FF0000' }}, callback)
-    expect(vm.$transition('invalid', {})).to.be.undefined
-    expect(requireSpy.firstCall.args[0]).eql('animation')
-    expect(moduleSpy.firstCall.args.length).eql(3)
-    expect(moduleSpy.firstCall.args[0]).eql('_root')
-    expect(moduleSpy.firstCall.args[1]).eql({
-      styles: { color: '#FF0000' }
-    })
-    expect(callback.callCount).eql(1)
-  })
-
-  it('$getConfig', () => {
-    const config = vm.$getConfig()
-    expect(config).eql({
-      debug: true,
-      bundleUrl: 'path_to_bundleUrl'
-    })
-
-    const configSpy = sinon.spy()
-    vm.$getConfig(configSpy)
-    expect(console.warn.callCount).to.be.equal(1)
-    expect(configSpy.args.length).eql(1)
-    expect(configSpy.args[0][0]).eql({
-      debug: true,
-      bundleUrl: 'path_to_bundleUrl'
-    })
-  })
-
-  it('$sendHttp', () => {
-    const callback = sinon.spy()
-    vm.$sendHttp({ a: 1 }, callback)
-    expect(requireSpy.firstCall.args[0]).eql('stream')
-    expect(moduleSpy.firstCall.args.length).eql(2)
-    expect(moduleSpy.firstCall.args).eql([{ a: 1 }, callback])
-    expect(callback.callCount).eql(1)
-  })
-
-  it('$openURL', () => {
-    vm.$openURL('url')
-    expect(requireSpy.firstCall.args[0]).eql('event')
-    expect(moduleSpy.firstCall.args.length).eql(1)
-    expect(moduleSpy.firstCall.args).eql(['url'])
-  })
-
-  it('$setTitle', () => {
-    vm.$setTitle('title')
-    expect(requireSpy.firstCall.args[0]).eql('pageInfo')
-    expect(moduleSpy.firstCall.args.length).eql(1)
-    expect(moduleSpy.firstCall.args).eql(['title'])
-  })
-
-  it('$call', () => {
-    vm.$call('event', 'openURL', 'url')
-    expect(vm.$call('invalid', 'module')).to.be.undefined
-    expect(vm.$call('event', 'invalid')).to.be.undefined
-    expect(requireSpy.firstCall.args[0]).eql('event')
-    expect(moduleSpy.firstCall.args.length).eql(1)
-    expect(moduleSpy.firstCall.args[0]).eql('url')
-  })
-})
diff --git a/test/js-framework/unit/default/api/modules.js b/test/js-framework/unit/default/api/modules.js
deleted file mode 100644
index 5545337..0000000
--- a/test/js-framework/unit/default/api/modules.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-import chai from 'chai'
-const { expect } = chai
-
-import * as modules from '../../../../../runtime/frameworks/legacy/api/modules'
-import { initModules, requireModule, clearModules } from '../../../../../runtime/frameworks/legacy/app/register'
-
-describe('built-in modules', () => {
-  before(() => {
-    clearModules()
-  })
-
-  after(() => {
-    clearModules()
-  })
-
-  it('have keys', () => {
-    const app = {}
-    initModules(modules)
-    expect(requireModule(app, 'dom')).to.have.all.keys('scrollToElement')
-    expect(requireModule(app, 'stream')).to.have.all.keys('sendHttp')
-    expect(requireModule(app, 'event')).to.have.all.keys('openURL')
-    expect(requireModule(app, 'pageInfo')).to.have.all.keys('setTitle')
-    expect(requireModule(app, 'animation')).to.have.all.keys('transition')
-  })
-})
diff --git a/test/js-framework/unit/default/app/bundle.js b/test/js-framework/unit/default/app/bundle.js
deleted file mode 100644
index 8ee6ae6..0000000
--- a/test/js-framework/unit/default/app/bundle.js
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-import chai from 'chai'
-import sinon from 'sinon'
-import sinonChai from 'sinon-chai'
-const { expect } = chai
-chai.use(sinonChai)
-
-import * as bundle from '../../../../../runtime/frameworks/legacy/app/bundle'
-import * as register from '../../../../../runtime/frameworks/legacy/app/register'
-import { removeWeexPrefix } from '../../../../../runtime/frameworks/legacy/util'
-import { Document } from '../../../../../runtime/vdom'
-import Listener from '../../../../../runtime/bridge/Listener'
-
-describe('parsing a bundle file', () => {
-  const componentTemplate = {
-    type: 'container',
-    children: [{
-      type: 'text',
-      attr: {
-        value: 'Hello World'
-      }
-    }]
-  }
-
-  before(() => {
-    sinon.stub(console, 'info')
-    sinon.stub(console, 'warn')
-    sinon.stub(console, 'error')
-    sinon.stub(console, 'debug')
-  })
-
-  after(() => {
-    console.info.restore()
-    console.warn.restore()
-    console.error.restore()
-    console.debug.restore()
-  })
-
-  describe('use define/bootstrap', () => {
-    let app
-    let callTasksSpy
-
-    before(() => {
-      const id = Date.now()
-      callTasksSpy = sinon.spy()
-
-      const doc = new Document(id, '', (tasks) => {
-        app.callTasks(tasks)
-      })
-
-      app = {
-        id, doc,
-        customComponentMap: {},
-        commonModules: {},
-        callbacks: {},
-        callTasks: callTasksSpy,
-        requireModule: function (name) {
-          return register.requireModule(this, name)
-        }
-      }
-    })
-
-    afterEach(() => {
-      callTasksSpy.reset()
-    })
-
-    describe('define', () => {
-      it('a weex component with factory and deps', () => {
-        bundle.defineFn(app, '@weex-component/a', (require, exports, module) => {
-          module.exports = {
-            template: componentTemplate
-          }
-        })
-        bundle.defineFn(app, '@weex-component/aa', [], (require, exports, module) => {
-          module.exports = {
-            template: componentTemplate
-          }
-        })
-
-        expect(app.customComponentMap['a'].template).to.deep.equal(componentTemplate)
-        expect(app.customComponentMap['aa'].template).to.deep.equal(componentTemplate)
-      })
-
-      it('a weex component with definition object and deps', () => {
-        bundle.defineFn(app, '@weex-component/aaa', {
-          template: componentTemplate
-        })
-        bundle.defineFn(app, '@weex-component/aaaa', [], {
-          template: componentTemplate
-        })
-
-        expect(app.customComponentMap['aaa'].template).to.deep.equal(componentTemplate)
-        expect(app.customComponentMap['aaaa'].template).to.deep.equal(componentTemplate)
-      })
-
-      it('a weex module', () => {
-        const methods = [{
-          name: 'createBody',
-          args: []
-        }]
-
-        bundle.defineFn(app, '@weex-module/dom', (require, exports, module) => {
-          module.exports = methods
-        })
-      })
-
-      it('a normal module', () => {
-        bundle.defineFn(app, './a', (require, exports, module) => {
-          exports.version = '0.1'
-        })
-      })
-
-      it('a npm module', () => {
-        bundle.defineFn(app, 'lib-httpurl', (require, exports, module) => {
-          exports.version = '0.2'
-        })
-      })
-
-      it('a CMD module', () => {
-        bundle.defineFn(app, 'kg/base', [], (require, exports, module) => {
-          exports.version = '0.3'
-        })
-      })
-    })
-
-    describe('require', () => {
-      it('a weex component', (done) => {
-        bundle.defineFn(app, '@weex-component/b', (require, exports, module) => {
-          const componentA = require('@weex-component/a')
-
-          expect(componentA.template).to.be.equal(componentTemplate)
-          done()
-        })
-      })
-
-      it('a weex module', (done) => {
-        // eslint-disable-next-line camelcase
-        const __weex_require__ = name => register.requireModule(app, removeWeexPrefix(name))
-        bundle.defineFn(app, '@weex-component/c', (require, exports, module) => {
-          const dom = require('@weex-module/dom')
-          expect(dom.createBody).to.be.a('function')
-          const dom2 = __weex_require__('dom')
-          expect(dom2.createBody).to.be.a('function')
-          const dom3 = __weex_require__('@weex-module/dom')
-          expect(dom3.createBody).to.be.a('function')
-          done()
-        })
-      })
-
-      it('a normal module', (done) => {
-        bundle.defineFn(app, '@weex-component/d', (require, exports, module) => {
-          const a = require('./a')
-
-          expect(a.version).to.be.equal('0.1')
-          done()
-        })
-      })
-
-      it('a npm module', (done) => {
-        bundle.defineFn(app, '@weex-component/e', (require, exports, module) => {
-          const HttpUrl = require('lib-httpurl')
-
-          expect(HttpUrl.version).to.be.equal('0.2')
-          done()
-        })
-      })
-
-      it('a CMD module', (done) => {
-        bundle.defineFn(app, 'kg/sample', ['kg/base'], (require, exports, module) => {
-          const base = require('kg/base')
-
-          expect(base.version).to.be.equal('0.3')
-          done()
-        })
-      })
-    })
-
-    describe('bootstrap', () => {
-      const ready = sinon.spy()
-
-      before(() => {
-        global.transformerVersion = '>=0.1 <1.0'
-        bundle.defineFn(app, '@weex-component/main', (require, exports, module) => {
-          module.exports = {
-            template: componentTemplate,
-            ready: ready
-          }
-        })
-      })
-
-      after(() => {
-        global.transformerVersion = undefined
-      })
-
-      it('not a weex component', () => {
-        const result = bundle.bootstrap(app, '@weex-module/dom')
-        expect(result).instanceof(Error)
-      })
-
-      it('a weex component', () => {
-        const result = bundle.bootstrap(
-          app,
-          '@weex-component/main',
-          { transformerVersion: '0.1.99' }
-        )
-
-        expect(result).not.instanceof(Error)
-        expect(callTasksSpy.calledTwice).to.be.true
-
-        expect(ready.calledOnce).to.be.true
-        const task1 = callTasksSpy.firstCall.args[0][0]
-        expect(task1.module).to.be.equal('dom')
-        expect(task1.method).to.be.equal('createBody')
-        expect(task1.args[0]).to.deep.equal({
-          type: 'container',
-          ref: '_root',
-          attr: {},
-          style: {}
-        })
-
-        const task2 = callTasksSpy.secondCall.args[0][0]
-        expect(task2.module).to.be.equal('dom')
-        expect(task2.method).to.be.equal('addElement')
-        expect(task2.args[1]).to.deep.equal({
-          type: 'text',
-          ref: app.doc.body.children[0].ref,
-          attr: {
-            value: 'Hello World'
-          },
-          style: {}
-        })
-        expect(task2.args[0]).to.be.equal('_root')
-        expect(task2.args[2]).to.be.equal(-1)
-      })
-
-      it('with a less wrong transformer version', () => {
-        const result = bundle.bootstrap(
-          app,
-          '@weex-component/main',
-          { transformerVersion: '0.0.1' }
-        )
-        expect(result).instanceof(Error)
-      })
-
-      it('with a bigger wrong transformer version', () => {
-        const result = bundle.bootstrap(
-          app,
-          '@weex-component/main',
-          { transformerVersion: '9.9.9' }
-        )
-        expect(result).instanceof(Error)
-      })
-
-      it('with viewport config', () => {
-        bundle.bootstrap(
-          app,
-          '@weex-component/undefined',
-          {
-            viewport: { width: 640 }
-          }
-        )
-        expect(callTasksSpy.callCount).to.be.equal(1)
-        const tasks = callTasksSpy.lastCall.args[0]
-        expect(tasks[0].module).to.be.equal('meta')
-        expect(tasks[0].method).to.be.equal('setViewport')
-        expect(tasks[0].args).to.deep.equal([{ width: 640 }])
-      })
-    })
-  })
-
-  describe('use regsiter/render(backward compatibility)', () => {
-    let app
-    let callTasksSpy
-    let readySpy
-    const template = {
-      type: 'container',
-      children: [{
-        type: 'text',
-        attr: {
-          value: 'Hello World'
-        }
-      }, {
-        type: 'custom'
-      }]
-    }
-
-    before(() => {
-      const id = Date.now()
-      callTasksSpy = sinon.spy()
-      readySpy = sinon.spy()
-
-      const doc = new Document(id, '', (tasks, callback) => {
-        app.callTasks(tasks, callback)
-      }, Listener)
-
-      app = {
-        id, doc,
-        customComponentMap: {},
-        callbacks: {},
-        callTasks: (tasks, callback) => {
-          callTasksSpy(tasks)
-          callback && callback()
-        },
-        requireModule: function (name) {
-          return register.requireModule(this, name)
-        }
-      }
-
-      Object.assign(app, bundle)
-    })
-
-    afterEach(() => {
-      callTasksSpy.reset()
-    })
-
-    describe('register', () => {
-      const readyfn = function () {
-        readySpy(this)
-      }
-
-      it('a component', () => {
-        bundle.register(app, 'custom', {
-          template: componentTemplate,
-          data: {
-            b: 'c'
-          },
-          methods: {
-            ready: readyfn
-          }
-        })
-
-        bundle.register(app, 'main', {
-          template: template,
-          data: {
-            a: 'b'
-          },
-          methods: {
-            ready: readyfn
-          }
-        })
-
-        expect(app.customComponentMap['custom'].template)
-          .to.deep.equal(componentTemplate)
-        expect(app.customComponentMap['main'].template)
-          .to.deep.equal(template)
-      })
-    })
-  })
-
-  describe('use define/require(backward compatibility)', () => {
-    let app
-    let callTasksSpy
-
-    before(() => {
-      const id = Date.now()
-      callTasksSpy = sinon.spy()
-
-      const doc = new Document(id, '', (tasks, callback) => {
-        app.callTasks(tasks, callback)
-      }, Listener)
-
-      app = {
-        id, doc,
-        customComponentMap: {},
-        callbacks: {},
-        callTasks: (tasks, callback) => {
-          callTasksSpy(tasks)
-          callback && callback()
-        },
-        requireModule: function (name) {
-          return register.requireModule(this, name)
-        }
-      }
-    })
-
-    afterEach(() => {
-      callTasksSpy.reset()
-    })
-
-    describe('define(old)', () => {
-      it('a component', () => {
-        bundle.defineFn(app, 'main', (require, exports, module) => {
-          module.exports = {
-            template: componentTemplate
-          }
-        })
-        expect(app.customComponentMap['main'].template)
-          .to.deep.equal(componentTemplate)
-      })
-    })
-  })
-})
diff --git a/test/js-framework/unit/default/app/ctrl.js b/test/js-framework/unit/default/app/ctrl.js
deleted file mode 100644
index 9937626..0000000
--- a/test/js-framework/unit/default/app/ctrl.js
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-import chai from 'chai'
-import sinon from 'sinon'
-import sinonChai from 'sinon-chai'
-const { expect } = chai
-chai.use(sinonChai)
-
-import * as ctrl from '../../../../../runtime/frameworks/legacy/app/ctrl'
-import Differ from '../../../../../runtime/frameworks/legacy/app/differ'
-import { Document } from '../../../../../runtime/vdom'
-
-describe('the api of app', () => {
-  let app
-  let spy1
-  let spy2
-
-  function createApp () {
-    const id = Date.now()
-
-    const app = {
-      id: id,
-      customComponentMap: {},
-      registerComponent: function () {},
-      // define: sinon.spy(),
-      // bootstrap: sinon.stub(),
-      vm: {},
-      differ: new Differ(id)
-    }
-
-    app.doc = new Document(id, '', spy1)
-    app.doc.createBody('div')
-
-    app.doc.taskCenter.callbackManager.add(spy2)
-    // app.bootstrap.returns()
-
-    return app
-  }
-
-  before(() => {
-    spy1 = sinon.spy()
-    spy2 = sinon.spy()
-    app = createApp()
-    !console.debug && (console.debug = function () {})
-  })
-
-  afterEach(() => {
-    spy1.reset()
-    // spy2.reset()
-  })
-
-  describe('init', () => {
-    before(() => {
-      global.transformerVersion = '0.1.3'
-    })
-
-    after(() => {
-      global.transformerVersion = undefined
-    })
-
-    it('a simple bundle', () => {
-      app.requireModule = () => {}
-      ctrl.init(app, `
-        define('main', function (r, e, m) {
-          e.template = {
-            "type": "container",
-            "children": [{
-              "type": "text",
-              "attr": {
-                "value": "Hello World"
-              }
-            }]
-          }
-        })
-
-        bootstrap('main')
-      `)
-
-      // expect(app.define.calledOnce).to.be.true
-      // expect(app.bootstrap.calledOnce).to.be.true
-
-      const task = spy1.lastCall.args[0][0]
-      expect(task.module).to.be.equal('dom')
-      expect(task.method).to.be.equal('createFinish')
-      expect(task.args.length).to.be.equal(0)
-    })
-  })
-
-  describe('getRootElement', () => {
-    it('from a simple', () => {
-      const json = ctrl.getRootElement(app)
-      expect(json.ref).eql('_root')
-      expect(json.type).eql('div')
-      expect(json.children.length).eql(1)
-    })
-    it('from empty object', () => {
-      expect(ctrl.getRootElement({})).to.deep.equal({})
-    })
-  })
-
-  describe('fireEvent', () => {
-    it('click on root', () => {
-      ctrl.fireEvent(app, '_root', 'click')
-      const task = spy1.lastCall.args[0][0]
-      expect(task.module).to.be.equal('dom')
-      expect(task.method).to.be.equal('updateFinish')
-      expect(task.args.length).to.be.equal(0)
-    })
-
-    it('error', () => {
-      const result = ctrl.fireEvent(app, '_rootTest', 'click')
-      expect(result).to.be.an.instanceof(Error)
-    })
-
-    it('click on both root & _rootTest', () => {
-      ctrl.fireEvent(app, ['_root', '_rootTest'], 'click')
-      const task = spy1.lastCall.args[0][0]
-      expect(task.module).to.be.equal('dom')
-      expect(task.method).to.be.equal('updateFinish')
-      expect(task.args.length).to.be.equal(0)
-    })
-  })
-
-  describe('callback', () => {
-    it('with a simple data', () => {
-      const data = { a: 'b' }
-      ctrl.callback(app, '1', data, true)
-      expect(spy2.calledOnce).to.be.true
-
-      const task = spy1.firstCall.args[0][0]
-      expect(task.module).to.be.equal('dom')
-      expect(task.method).to.be.equal('updateFinish')
-      expect(task.args.length).to.be.equal(0)
-    })
-
-    it('multiple called', () => {
-      const data = { a: 'b' }
-      ctrl.callback(app, '1', data, true)
-      expect(spy2.calledTwice).to.be.true
-
-      ctrl.callback(app, '1', data, false)
-      expect(spy2.calledThrice).to.be.true
-    })
-
-    it('error', () => {
-      const data = null
-      const result = ctrl.callback(app, '1', data, true)
-      expect(result).to.be.an.instanceof(Error)
-    })
-  })
-
-  describe('refreshData', () => {
-    it('a simple data', () => {
-      const data = { b: 'c' }
-      ctrl.refresh(app, data)
-      expect(app.vm.b).to.deep.equal(data.b)
-
-      const task = spy1.lastCall.args[0][0]
-      expect(task.module).to.be.equal('dom')
-      expect(task.method).to.be.equal('refreshFinish')
-      expect(task.args.length).to.be.equal(0)
-    })
-
-    it('call refresh with refreshData function', () => {
-      app.vm.refreshData = function () {
-        app.vm.data = 'hello'
-      }
-      const data = { b: 'c' }
-      ctrl.refresh(app, data)
-      expect(app.vm.data).to.equal('hello')
-    })
-
-    it('error', () => {
-      const data = null
-      const result = ctrl.refresh(app, data)
-      expect(result).to.be.an.instanceof(Error)
-    })
-  })
-
-  describe('destory', () => {
-    it('the simple data', () => {
-      ctrl.destroy(app)
-      expect(app.id).to.be.empty
-      expect(app.blocks).to.be.null
-      expect(app.vm).to.be.null
-      expect(app.doc).to.be.null
-      expect(app.customComponentMap).to.be.null
-    })
-    it('the incomplete data', () => {
-      const appx = createApp()
-      delete appx.vm
-      ctrl.destroy(appx)
-      expect(appx.id).to.be.empty
-      expect(appx.blocks).to.be.null
-      expect(appx.vm).to.be.null
-      expect(appx.doc).to.be.null
-      expect(appx.customComponentMap).to.be.null
-    })
-    it('clear vms', () => {
-      const appy = createApp()
-      appy.vm = {
-        $emit () {},
-        _watchers: [{ teardown () {} }],
-        _childrenVms: [{ $emit () {} }]
-      }
-      ctrl.destroy(appy)
-      expect(appy.id).to.be.empty
-      expect(appy.blocks).to.be.null
-      expect(appy.vm).to.be.null
-      expect(appy.doc).to.be.null
-      expect(appy.customComponentMap).to.be.null
-    })
-  })
-})
diff --git a/test/js-framework/unit/default/app/downgrade.js b/test/js-framework/unit/default/app/downgrade.js
deleted file mode 100644
index 6c84378..0000000
--- a/test/js-framework/unit/default/app/downgrade.js
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-import chai from 'chai'
-const { expect } = chai
-
-import * as Downgrade from '../../../../../runtime/frameworks/legacy/app/downgrade'
-
-describe('downgrade', () => {
-  describe('normalizeVersion', () => {
-    it('should be normalize version format', () => {
-      const cases = [
-        ['', '0.0.0'],
-        ['1', '1.0.0'],
-        ['1.0', '1.0.0'],
-        ['1.0.0', '1.0.0'],
-        ['1.0.0.0', '1.0.0'],
-        ['1.3.4.1230', '1.3.4']
-      ]
-
-      cases.map(function (item, index) {
-        const input = item[0]
-        const should = item[1]
-        const test = Downgrade.normalizeVersion(input)
-
-        expect(test).to.be.equal(should)
-      })
-    })
-
-    it('invalid version format', () => {
-      expect(Downgrade.normalizeVersion([])).to.be.equal('0.0.0')
-      expect(Downgrade.normalizeVersion({})).to.be.equal('0.0.0')
-      expect(Downgrade.normalizeVersion(2.0)).to.be.equal('0.0.0')
-    })
-  })
-
-  describe('getError', () => {
-    it('should be get right error message', () => {
-      const cases = [
-        [1000, 'osName', 'iphone', 'iphone'],
-        [1001, 'osVersion', '1.0.0', '1.0.0'],
-        [1002, 'appVersion', '3.2.2', '>3.0.0'],
-        [1003, 'weexVersion', '1.2.3', '>=1.2.3'],
-        [1004, 'deviceModel', '1.0.0', ['1.0.0']]
-      ]
-
-      cases.map(function (item, index) {
-        const code = item[0]
-        const key = item[1]
-        const val = item[2]
-        const criteria = item[3]
-        const test = Downgrade.getError(key, val, criteria)
-
-        expect(test.code).to.be.equal(code)
-        expect(test.errorType).to.be.equal(1)
-        expect(test.isDowngrade).to.be.equal(true)
-      })
-    })
-  })
-
-  describe('check', () => {
-    it('should be match config', () => {
-      const deviceInfo = {
-        platform: 'ios',
-        osVersion: '9.2.1',
-        appVersion: '5.4.0',
-        weexVersion: '1.3.0',
-        deviceModel: 'iPhone6.2'
-      }
-
-      const cases = [
-        [{ ios: { osVersion: '>=9' }}, true],
-        [{ ios: { appVersion: '<10.0.0' }}, true],
-        [{ ios: { appVersion: '>10.0.0' }}, false],
-        [{ ios: { appVersion: '5.4.0' }}, true],
-        [{ ios: { deviceModel: 'ABC' }}, false],
-        [{ ios: { deviceModel: 'iPhone6.2' }}, true],
-        [{ ios: { deviceModel: ['iPhone6.2', 'ABC'] }}, true],
-        [{ ios: { osVersion: '>9', deviceModel: ['iPhone6.2', 'ABC'] }}, true],
-        [{ ios: { osVersion: '>=9', deviceModel: ['iPhone6.2', 'ABC'] }}, true],
-        [{ ios: { weexVersion: '<=9' }}, true]
-      ]
-
-      cases.map(function (item, index) {
-        const criteria = item[0]
-        const should = item[1]
-        const test = Downgrade.check(criteria, deviceInfo)
-
-        expect(test.isDowngrade).to.be.equal(should)
-      })
-    })
-
-    it('should be match config without app version', () => {
-      const deviceInfo = {
-        platform: 'iOS',
-        osVersion: '9.2',
-        weexVersion: '1.3.0',
-        deviceModel: 'iPhone6.2'
-      }
-
-      const cases = [
-        [{ ios: { osVersion: '>=9' }}, true],
-        [{ ios: { osVersion: '>8' }}, true],
-        [{ ios: { appVersion: '<10.0.0' }}, false],
-        [{ ios: { appVersion: '>10.0.0' }}, false],
-        [{ ios: { appVersion: '5.4.0' }}, false],
-        [{ ios: { deviceModel: 'ABC' }}, false],
-        [{ ios: { deviceModel: 'iPhone6.2' }}, true],
-        [{ ios: { deviceModel: ['MF353TA/A', 'ABC'] }}, false],
-        [{ ios: { osVersion: '>9', deviceModel: ['MF353TA/A', 'ABC'] }}, true],
-        [{ ios: { osVersion: '>=9', deviceModel: ['MF353TA/A', 'ABC'] }}, true],
-        [{ ios: { weexVersion: '<=9' }}, true],
-        [{ ios: { weexVersion: '>=1.3.0' }}, true],
-        [{ ios: { weexVersion: '>=1.3.0' }}, true]
-      ]
-
-      cases.map(function (item, index) {
-        const criteria = item[0]
-        const should = item[1]
-        const test = Downgrade.check(criteria, deviceInfo)
-
-        expect(test.isDowngrade).to.be.equal(should)
-      })
-    })
-
-    it('should be match config and deviceInfo from global var', () => {
-      global.WXEnvironment = {
-        platform: 'iOS',
-        osVersion: '9.2',
-        appVersion: '5.4.0',
-        weexVersion: '1.3.0',
-        deviceModel: 'iPhone6.2'
-      }
-
-      const cases = [
-        [{ ios: { osVersion: '>=9' }}, true],
-        [{ ios: { osVersion: '>8' }}, true],
-        [{ ios: { appVersion: '<10.0.0' }}, true],
-        [{ ios: { appVersion: '>10.0.0' }}, false],
-        [{ ios: { appVersion: '5.4.0' }}, true],
-        [{ ios: { deviceModel: 'ABC' }}, false],
-        [{ ios: { deviceModel: 'iPhone6.2' }}, true],
-        [{ ios: { deviceModel: ['MF353TA/A', 'ABC'] }}, false],
-        [{ ios: { osVersion: '>9', deviceModel: ['MF353TA/A', 'ABC'] }}, true],
-        [{ ios: { osVersion: '>=9', deviceModel: ['MF353TA/A', 'ABC'] }}, true],
-        [{ ios: { weexVersion: '<=9' }}, true],
-        [{ ios: { weexVersion: '>=1.3.0' }}, true],
-        [{ ios: { weexVersion: '>=1.3.0' }}, true]
-      ]
-
-      cases.map(function (item, index) {
-        const criteria = item[0]
-        const should = item[1]
-        const test = Downgrade.check(criteria)
-
-        expect(test.isDowngrade).to.be.equal(should)
-      })
-    })
-
-    it('should be using using custom check', () => {
-      const deviceInfo = {
-        platform: 'iOS',
-        osVersion: '9.2',
-        appVersion: '5.4.0',
-        weexVersion: '1.3.0',
-        deviceModel: 'iPhone6.2'
-      }
-
-      const cases = [
-        [
-          function () {
-
-          }, false
-        ],
-        [
-          function () {
-            return true
-          }, true
-        ],
-        [
-          function () {
-            return false
-          }, false
-        ],
-        [
-          function (deviceInfo) {
-            if (deviceInfo.platform === 'iOS') {
-              return true
-            }
-            return false
-          }, true
-        ],
-        [
-          function (deviceInfo, tools) {
-            if (deviceInfo.osVersion === '9.2') {
-              return true
-            }
-            return false
-          }, true
-        ],
-        [
-          function (deviceInfo, tools) {
-            if (tools.normalizeVersion(deviceInfo.osVersion) === '9.2.0') {
-              return true
-            }
-            return false
-          }, true
-        ],
-        [
-          function (deviceInfo, tools) {
-            return tools.semver.satisfies(tools.normalizeVersion(deviceInfo.osVersion), '9.2.0')
-          }, true
-        ],
-        [
-          function (deviceInfo, tools) {
-            return tools.semver.satisfies(deviceInfo.appVersion, '5.4.0')
-          }, true
-        ],
-        [
-          function (deviceInfo, tools) {
-            return tools.semver.satisfies(deviceInfo.weexVersion, '1.3.0')
-          }, true
-        ],
-        [
-          function (deviceInfo, tools) {
-            return deviceInfo.deviceModel === 'iPhone6.2'
-          }, true
-        ],
-        [
-          function (deviceInfo, tools) {
-            return deviceInfo.deviceModel === 'AndroidPad'
-          }, false
-        ],
-        [
-          function (deviceInfo, tools) {
-            return ['iPhone6.2', 'iPhone7.1'].indexOf(deviceInfo.deviceModel) >= 0
-          }, true
-        ]
-      ]
-
-      cases.map(function (item, index) {
-        const criteria = item[0]
-        const should = item[1]
-        const test = Downgrade.check(criteria, deviceInfo)
-
-        expect(test.isDowngrade).to.be.equal(should)
-      })
-    })
-  })
-})
diff --git a/test/js-framework/unit/default/app/index.js b/test/js-framework/unit/default/app/index.js
deleted file mode 100644
index fdfb9ac..0000000
--- a/test/js-framework/unit/default/app/index.js
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-import chai from 'chai'
-import sinon from 'sinon'
-import sinonChai from 'sinon-chai'
-const { expect } = chai
-chai.use(sinonChai)
-
-import App from '../../../../../runtime/frameworks/legacy/app'
-import { Element, Document } from '../../../../../runtime/vdom'
-
-describe('App Instance', () => {
-  const oriDocumentHandler = Document.handler
-  const sendTasksSpy = sinon.spy()
-  let app
-
-  beforeEach(() => {
-    Document.handler = sendTasksSpy
-    const id = Date.now() + ''
-    app = new App(id, {})
-  })
-
-  afterEach(() => {
-    Document.handler = oriDocumentHandler
-  })
-
-  describe('normal check', () => {
-    it('is a class', () => {
-      expect(App).to.be.an('function')
-    })
-
-    it('being created', () => {
-      expect(app).to.be.an('object')
-      expect(app).to.be.instanceof(App)
-    })
-
-    it('with some apis', () => {
-      expect(app.requireModule).a.function
-      expect(app.updateActions).a.function
-      expect(app.callTasks).a.function
-    })
-
-    it('run apis', () => {
-      expect(app.requireModule('stream')).to.deep.equal({})
-      expect(app.updateActions()).to.be.undefined
-      expect(app.callTasks([])).to.be.undefined
-    })
-  })
-
-  describe('call tasks', () => {
-    it('with no args & callback', () => {
-      const tasks = [{
-        module: 'dom',
-        method: 'createBody',
-        args: []
-      }]
-
-      app.callTasks(tasks)
-      expect(sendTasksSpy.lastCall.args[1]).to.deep.equal(tasks)
-    })
-
-    it('with callback', (done) => {
-      const tasks = [{
-        module: 'dom',
-        method: 'createBody',
-        args: []
-      }]
-
-      app.callTasks(tasks)
-      expect(sendTasksSpy.lastCall.args[1]).to.deep.equal(tasks)
-      done()
-    })
-
-    it('with function arg', (done) => {
-      const callbackId = '1'
-
-      const tasks = [{
-        module: 'dom',
-        method: 'createBody',
-        args: [() => {}]
-      }]
-
-      app.callTasks(tasks)
-      expect(sendTasksSpy.lastCall.args[1]).to.deep.equal([{
-        module: 'dom',
-        method: 'createBody',
-        args: [callbackId]
-      }])
-      done()
-    })
-
-    it('with node arg', (done) => {
-      const node = new Element()
-      node.ref = '1'
-
-      const tasks = [{
-        module: 'dom',
-        method: 'createBody',
-        args: [node]
-      }]
-
-      app.callTasks(tasks)
-      expect(sendTasksSpy.lastCall.args[1]).to.deep.equal([{
-        module: 'dom',
-        method: 'createBody',
-        args: [node.ref]
-      }])
-      done()
-    })
-
-    it('with callback after close', (done) => {
-      const callbackId = '1'
-
-      const tasks = [{
-        module: 'dom',
-        method: 'createBody',
-        args: [() => {}]
-      }]
-
-      app.doc.close()
-
-      app.callTasks(tasks)
-      expect(sendTasksSpy.lastCall.args[1]).to.deep.equal([{
-        module: 'dom',
-        method: 'createBody',
-        args: [callbackId]
-      }])
-      done()
-    })
-  })
-})
diff --git a/test/js-framework/unit/default/app/register.js b/test/js-framework/unit/default/app/register.js
deleted file mode 100644
index 853b428..0000000
--- a/test/js-framework/unit/default/app/register.js
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-import chai from 'chai'
-import sinon from 'sinon'
-import sinonChai from 'sinon-chai'
-const { expect } = chai
-chai.use(sinonChai)
-
-import {
-  getModule,
-  clearModules,
-  initModules,
-  initMethods,
-  requireModule,
-  requireCustomComponent,
-  registerCustomComponent
-} from '../../../../../runtime/frameworks/legacy/app/register'
-
-function Ctx () {
-  this.customComponentMap = {}
-  this.callTasks = sinon.spy()
-}
-
-describe('register', () => {
-  let ctx
-
-  before(() => {
-    clearModules()
-    ctx = new Ctx()
-  })
-
-  after(() => {
-    clearModules()
-  })
-
-  describe('component', () => {
-    it('with exports', () => {
-      const def = {
-        a: 'b'
-      }
-      registerCustomComponent(ctx, 'componentA', def)
-      expect(requireCustomComponent(ctx, 'componentA')).to.deep.equal(def)
-    })
-
-    it('with a existing name', () => {
-      const def = {
-        a: 'b'
-      }
-      sinon.stub(console, 'error')
-      registerCustomComponent(ctx, 'componentA', def)
-      expect(console.error).callCount(1)
-      console.error.restore()
-    })
-  })
-
-  describe('module', () => {
-    it('with a old format', () => {
-      initModules({
-        dom: [
-          'createBody',
-          'addElement'
-        ]
-      })
-      expect(requireModule(ctx, 'dom')).to.have.any.keys('createBody', 'addElement')
-    })
-
-    it('with a new format', () => {
-      initModules({
-        dom: [
-          {
-            name: 'moveElement',
-            args: ['string', 'string']
-          }
-        ],
-        stream: [
-          {
-            name: 'sendMtop',
-            args: ['object', 'function']
-          }
-        ]
-      })
-      expect(requireModule(ctx, 'dom')).to.have.all.keys('createBody', 'addElement', 'moveElement')
-      expect(requireModule(ctx, 'stream')).to.have.all.keys('sendMtop')
-    })
-
-    it('with a existed module.method', () => {
-      initModules({
-        dom: [
-          {
-            name: 'moveElement',
-            args: ['string', 'string', 'string']
-          }
-        ]
-      }, true)
-      initModules({
-        stream: [
-          {
-            name: 'sendMtop',
-            args: ['object']
-          }
-        ]
-      })
-      expect(getModule('dom').moveElement).to.deep.equal({
-        name: 'moveElement',
-        args: ['string', 'string', 'string']
-      })
-
-      expect(getModule('stream').sendMtop).to.deep.equal({
-        name: 'sendMtop',
-        args: ['object', 'function']
-      })
-    })
-
-    it('run registered module', () => {
-      initModules({
-        event: [{
-          name: 'openURL',
-          args: ['string']
-        }]
-      })
-      const event = requireModule(ctx, 'event')
-      expect(event).to.have.keys('openURL')
-
-      event.openURL('http://test.com')
-      expect(ctx.callTasks.callCount).to.be.equal(1)
-    })
-  })
-
-  describe('api', () => {
-    it('a common api', () => {
-      initMethods(Ctx, {
-        $test1: function () {
-          return {
-            ctx: this,
-            value: 'test1'
-          }
-        },
-        $test2: function () {
-          return {
-            ctx: this,
-            value: 'test2'
-          }
-        }
-      })
-
-      expect(ctx.$test1).to.be.a('Function')
-      expect(ctx.$test1()).to.deep.equal({
-        ctx: ctx,
-        value: 'test1'
-      })
-      expect(ctx.$test2).to.be.an('Function')
-      expect(ctx.$test2()).to.deep.equal({
-        ctx: ctx,
-        value: 'test2'
-      })
-    })
-
-    it('override api', () => {
-      initMethods(Ctx, {
-        $override: function () {
-          return {
-            ctx: this,
-            value: 'first'
-          }
-        }
-      })
-
-      initMethods(Ctx, {
-        $override: function () {
-          return {
-            ctx: this,
-            value: 'ignored'
-          }
-        }
-      })
-
-      expect(ctx.$override).to.be.a('Function')
-      expect(ctx.$override()).to.deep.equal({
-        ctx: ctx,
-        value: 'first'
-      })
-    })
-  })
-})
diff --git a/test/js-framework/unit/default/app/viewport.js b/test/js-framework/unit/default/app/viewport.js
deleted file mode 100644
index 2caf37c..0000000
--- a/test/js-framework/unit/default/app/viewport.js
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-import chai from 'chai'
-import sinon from 'sinon'
-import sinonChai from 'sinon-chai'
-const { expect } = chai
-chai.use(sinonChai)
-
-import * as viewport from '../../../../../runtime/frameworks/legacy/app/viewport'
-
-describe('viewport', function () {
-  const originalCallNative = global.callNative
-  const { setViewport, validateViewport } = viewport
-  const mockApp = {
-    id: 'mock',
-    callTasks (...args) {
-      global.callNative(...args)
-    }
-  }
-
-  before(() => {
-    sinon.stub(console, 'warn')
-  })
-
-  beforeEach(() => {
-    global.callNative = sinon.spy()
-  })
-  afterEach(() => {
-    global.callNative = originalCallNative
-    console.warn.reset()
-  })
-
-  it('invalid setViewport', () => {
-    setViewport()
-    expect(global.callNative.callCount).to.be.equal(0)
-    setViewport({})
-    expect(global.callNative.callCount).to.be.equal(0)
-  })
-
-  it('setViewport', () => {
-    setViewport(mockApp, {})
-    expect(global.callNative.callCount).to.be.equal(1)
-    setViewport(mockApp, { width: 640 })
-    expect(global.callNative.callCount).to.be.equal(2)
-    setViewport(mockApp, { width: 'device-width' })
-    expect(global.callNative.callCount).to.be.equal(3)
-  })
-
-  it('validateViewport', () => {
-    expect(validateViewport()).to.be.false
-    expect(console.warn.callCount).to.be.equal(1)
-    expect(validateViewport({})).to.be.false
-    expect(console.warn.callCount).to.be.equal(2)
-
-    expect(validateViewport({ width: 200 })).to.be.true
-    expect(console.warn.callCount).to.be.equal(2)
-    expect(validateViewport({ width: 'device-width' })).to.be.true
-    expect(console.warn.callCount).to.be.equal(2)
-
-    expect(validateViewport({ width: 'initial-width' })).to.be.false
-    expect(console.warn.callCount).to.be.equal(3)
-  })
-})
diff --git a/test/js-framework/unit/default/util/index.js b/test/js-framework/unit/default/util/index.js
deleted file mode 100644
index 0d778f7..0000000
--- a/test/js-framework/unit/default/util/index.js
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-import chai from 'chai'
-const { expect } = chai
-
-import * as util from '../../../../../runtime/frameworks/legacy/util'
-
-describe('Util', () => {
-  describe('isReserved', () => {
-    it('should be first char is $ or _', () => {
-      expect(util.isReserved('$isReserved')).eql(true)
-      expect(util.isReserved('_isReserved')).eql(true)
-      expect(util.isReserved('isReserved$')).eql(false)
-      expect(util.isReserved('is$Reserved')).eql(false)
-      expect(util.isReserved('isReserved')).eql(false)
-    })
-  })
-
-  describe('camelize', () => {
-    it('should be camelize a hyphen-delmited string', () => {
-      expect(util.camelize('mini-camelize')).eql('miniCamelize')
-      expect(util.camelize('mini-camelize-test')).eql('miniCamelizeTest')
-    })
-  })
-
-  describe('toArray', () => {
-    it('should be convert an Array-like object to a real Array', () => {
-      const mockup = {
-        '0': 1,
-        '1': 2,
-        '2': 3,
-        length: 3
-      }
-
-      expect(util.toArray(mockup)).eql([1, 2, 3])
-      expect(util.toArray(mockup, 2)).eql([3])
-    })
-  })
-
-  describe('extend', () => {
-    it('should be extend object', () => {
-      const mockup = {
-        a: 1,
-        b: 2
-      }
-
-      expect(util.extend(mockup, { b: 4, c: 5 })).eql({
-        a: 1,
-        b: 4,
-        c: 5
-      })
-
-      expect(util.extend(mockup, { c: 5 })).eql({
-        a: 1,
-        b: 4,
-        c: 5
-      })
-
-      expect(util.extend(mockup, { c: 5 }, { d: 6 }, { e: 7 })).eql({
-        a: 1,
-        b: 4,
-        c: 5,
-        d: 6,
-        e: 7
-      })
-    })
-
-    it('polyfill Object.assign', () => {
-      const _assign = Object.assign
-      Object.assign = undefined
-
-      const mockup = {
-        a: 1,
-        b: 2
-      }
-
-      expect(util.extend(mockup, { b: 4, c: 5 })).eql({
-        a: 1,
-        b: 4,
-        c: 5
-      })
-
-      expect(util.extend(mockup, { c: 5 })).eql({
-        a: 1,
-        b: 4,
-        c: 5
-      })
-
-      expect(util.extend(mockup, { c: 5 }, { d: 6 }, { e: 7 })).eql({
-        a: 1,
-        b: 4,
-        c: 5,
-        d: 6,
-        e: 7
-      })
-
-      Object.assign = _assign
-    })
-  })
-
-  describe('isObject', () => {
-    it('should be an array or object', () => {
-      expect(util.isObject({})).eql(true)
-      expect(util.isObject([])).eql(true)
-      expect(util.isObject('a')).eql(false)
-      expect(util.isObject(1)).eql(false)
-      expect(util.isObject(true)).eql(false)
-      expect(util.isObject(null)).eql(false)
-      expect(util.isObject(undefined)).eql(false)
-      expect(util.isObject(function () {})).eql(false)
-      expect(util.isObject(/\w*/)).eql(true) // regexp is object
-      expect(util.isObject(new Date())).eql(true)
-    })
-  })
-
-  describe('isPlainObject', () => {
-    it('should be an real object', () => {
-      expect(util.isPlainObject({})).eql(true)
-      expect(util.isPlainObject([])).eql(false)
-      expect(util.isPlainObject('a')).eql(false)
-      expect(util.isPlainObject(1)).eql(false)
-      expect(util.isPlainObject(true)).eql(false)
-      expect(util.isPlainObject(null)).eql(false)
-      expect(util.isPlainObject(undefined)).eql(false)
-      expect(util.isPlainObject(function () {})).eql(false)
-      expect(util.isPlainObject(/\w*/)).eql(false)
-      expect(util.isPlainObject(new Date())).eql(false)
-    })
-  })
-
-  describe('typof', () => {
-    it('should be real type', () => {
-      expect(util.typof({})).eql('object')
-      expect(util.typof([])).eql('array')
-      expect(util.typof('a')).eql('string')
-      expect(util.typof(1)).eql('number')
-      expect(util.typof(true)).eql('boolean')
-      expect(util.typof(null)).eql('null')
-      expect(util.typof(undefined)).eql('undefined')
-      expect(util.typof(function () {})).eql('function')
-      expect(util.typof(/\w*/)).eql('regexp')
-      expect(util.typof(new Date())).eql('date')
-    })
-  })
-
-  describe('def', () => {
-    it('should be define a non-enumerable property', () => {
-      const obj = {}
-      util.def(obj, 'a', 1, true)
-      expect(obj).eql({ a: 1 })
-
-      util.def(obj, 'b', 1, false)
-      expect(obj).eql({ a: 1 })
-
-      util.def(obj, 'c', 1, true)
-      expect(obj).eql({ a: 1, c: 1 })
-
-      util.def(obj, 'd', 1)
-      expect(obj).eql({ a: 1, c: 1 })
-    })
-  })
-
-  describe('hyphenate', () => {
-    it('should hyphenate a camelCase string', () => {
-      const str = 'helloWorldWeex'
-      expect(util.hyphenate(str)).eql('hello-world-weex')
-    })
-  })
-})
diff --git a/test/js-framework/unit/default/util/shared.js b/test/js-framework/unit/default/util/shared.js
deleted file mode 100644
index 6778206..0000000
--- a/test/js-framework/unit/default/util/shared.js
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-import { expect } from 'chai'
-
-import * as utils from '../../../../../runtime/frameworks/legacy/util/shared'
-
-describe('test util functions', () => {
-  it('extend', () => {
-    expect(typeof utils.extend).to.be.equal('function')
-
-    const a = { name: 'A', a: true, c: true }
-    const b = { name: 'B', b: true }
-    utils.extend(a, b, { c: false })
-    expect(a).to.be.deep.equal({ name: 'B', a: true, b: true, c: false })
-    expect(b).to.be.deep.equal({ name: 'B', b: true })
-  })
-
-  it('def', () => {
-    expect(typeof utils.def).to.be.equal('function')
-    const obj = { type: 'none' }
-    utils.def(obj, 'count', 42, false)
-
-    expect(obj.hasOwnProperty('count')).to.be.true
-    expect(obj.propertyIsEnumerable('count')).to.be.false
-    expect(obj.type).to.be.equal('none')
-    expect(obj.count).to.be.equal(42)
-    obj.count = 24
-    expect(obj.count).to.be.equal(24)
-  })
-
-  it('remove', () => {
-    expect(typeof utils.remove).to.be.equal('function')
-
-    const arr = ['first', null, 42, null, 28]
-    const obj = { 0: 'first', 1: null, 2: 42 }
-
-    utils.remove(arr, null)
-    expect(arr).to.deep.equal(['first', 42, null, 28])
-    utils.remove(arr, null)
-    expect(arr).to.deep.equal(['first', 42, 28])
-    utils.remove(arr, null)
-    expect(arr).to.deep.equal(['first', 42, 28])
-    utils.remove(arr, 42)
-    expect(arr).to.deep.equal(['first', 28])
-
-    utils.remove(obj, 42)
-    expect(obj).to.deep.equal(obj)
-  })
-
-  it('hasOwn', () => {
-    expect(typeof utils.hasOwn).to.be.equal('function')
-
-    function Point () {
-      this.x = 0
-    }
-    Point.prototype.y = 1
-
-    const p = new Point()
-    expect(p.x).to.be.equal(0)
-    expect(p.y).to.be.equal(1)
-
-    expect(utils.hasOwn(p, 'x')).to.be.true
-    expect(utils.hasOwn(p, 'y')).to.be.false
-  })
-
-  it('bind', () => {
-    expect(typeof utils.bind).to.be.equal('function')
-
-    function who () {
-      return this.name
-    }
-    const obj = { name: 'fixed' }
-    const ctx = { name: 'changed' }
-    const askWho = utils.bind(who, obj)
-
-    expect(who()).to.be.undefined
-    expect(askWho()).to.be.equal('fixed')
-    expect(askWho.call(ctx)).to.be.equal('fixed')
-    expect(askWho.apply(ctx)).to.be.equal('fixed')
-    expect(who.apply(ctx)).to.be.equal('changed')
-  })
-
-  it('toArray', () => {
-    expect(typeof utils.toArray).to.be.equal('function')
-    const obj = { length: 2 }
-    const arr = utils.toArray(obj)
-
-    expect(arr).to.deep.equal([undefined, undefined])
-    expect(arr.hasOwnProperty('0')).to.be.true
-    expect(arr.hasOwnProperty('1')).to.be.true
-    expect(arr.hasOwnProperty('2')).to.be.false
-
-    const arrayLike = {
-      0: 'empty',
-      1: 'first',
-      2: 'second',
-      length: 3
-    }
-    expect(utils.toArray(arrayLike, 1)).to.deep.equal(['first', 'second'])
-  })
-
-  it('isObject', () => {
-    expect(typeof utils.isObject).to.be.equal('function')
-    expect(utils.isObject({})).to.be.true
-    expect(utils.isObject([])).to.be.true
-    expect(utils.isObject(new Date())).to.be.true
-    expect(utils.isObject()).to.be.false
-    expect(utils.isObject('')).to.be.false
-    expect(utils.isObject(42)).to.be.false
-    expect(utils.isObject(NaN)).to.be.false
-    expect(utils.isObject(null)).to.be.false
-    expect(utils.isObject(undefined)).to.be.false
-  })
-
-  it('isPlainObject', () => {
-    expect(typeof utils.isPlainObject).to.be.equal('function')
-    expect(utils.isPlainObject({})).to.be.true
-    expect(utils.isPlainObject([])).to.be.false
-    expect(utils.isPlainObject(new Date())).to.be.false
-    expect(utils.isPlainObject()).to.be.false
-    expect(utils.isPlainObject('')).to.be.false
-    expect(utils.isPlainObject(42)).to.be.false
-    expect(utils.isPlainObject(NaN)).to.be.false
-    expect(utils.isPlainObject(null)).to.be.false
-    expect(utils.isPlainObject(undefined)).to.be.false
-  })
-})
diff --git a/test/js-framework/unit/default/vm/directive.js b/test/js-framework/unit/default/vm/directive.js
deleted file mode 100644
index 451b310..0000000
--- a/test/js-framework/unit/default/vm/directive.js
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-import chai from 'chai'
-import sinon from 'sinon'
-import sinonChai from 'sinon-chai'
-const { expect } = chai
-chai.use(sinonChai)
-
-import {
-  applyNaitveComponentOptions,
-  bindSubVm,
-  bindSubVmAfterInitialized
-} from '../../../../../runtime/frameworks/legacy/vm/directive'
-
-import {
-  initState
-} from '../../../../../runtime/frameworks/legacy/core/state'
-import config from '../../../../../runtime/frameworks/legacy/config'
-
-const { nativeComponentMap } = config
-const directive = {}
-
-function extendVm (vm, methodNames) {
-  methodNames.forEach((name) => {
-    vm[name] = directive[name]
-  })
-  initState(vm)
-}
-
-function initElement (el) {
-  el.setAttr = function (k, v) { this.attr[k] = v }
-  el.setStyle = function (k, v) { this.style[k] = v }
-  el.setClassStyle = function (style) { this.classStyle = style }
-  el.addEvent = function (t, h) {
-    this.event[t] = h
-  }
-}
-
-describe('apply component options', () => {
-  it('apply top prop', () => {
-    nativeComponentMap['test-apply'] = {
-      type: 'test-apply1',
-      append: 'tree'
-    }
-    const template = {
-      type: 'test-apply'
-    }
-    applyNaitveComponentOptions(template)
-    expect(template.type).to.be.equal('test-apply')
-    expect(template.append).to.be.equal('tree')
-
-    delete nativeComponentMap['test-apply']
-  })
-
-  it('apply a object', () => {
-    nativeComponentMap['test-apply'] = {
-      classList: ['c'],
-      attr: {
-        a: 'a',
-        b: 'b'
-      }
-    }
-    const spy = sinon.spy()
-    const template = {
-      type: 'test-apply',
-      classList: spy,
-      attr: {
-        b: '2'
-      }
-    }
-    applyNaitveComponentOptions(template)
-
-    expect(template).to.deep.equal({
-      type: 'test-apply',
-      classList: spy,
-      attr: {
-        a: 'a',
-        b: '2'
-      }
-    })
-
-    delete nativeComponentMap['test-apply']
-  })
-})
-
-// exports._bindSubVm(subVm, template)
-describe('bind external infomations to sub vm', () => {
-  let vm, subVm
-  // const methodNames = [
-  //   '_watch', '_bindKey', '_bindDir',
-  //   '_setId', '_setAttr', '_setClass', '_setStyle',
-  //   '_setEvent', '_bindEvents', '_bindElement',
-  //   '_bindSubVm', '_bindSubVmAfterInitialized']
-  beforeEach(() => {
-    vm = {
-      _data: { a: 1, b: 2, c: 'class-style1' },
-      _watchers: [],
-      _app: { eventManager: { add: () => {} }},
-      _options: {
-        style: {
-          'class-style1': {
-            aaa: 1,
-            bbb: 2
-          },
-          'class-style2': {
-            aaa: 2,
-            ccc: 3
-          }
-        }
-      },
-      foo: function () {}
-    }
-    extendVm(vm, [])
-    subVm = {
-      _options: {
-        props: {
-          a: String,
-          b: String
-        }
-      }
-    }
-  })
-
-  it('bind to no-root-element sub vm', () => {
-    bindSubVm(vm, subVm, {
-      attr: { a: 3, c: 4 },
-      style: { a: 2 },
-      events: { click: 'foo' }
-    })
-    expect(subVm.a).eql(3)
-    expect(subVm.c).is.undefined
-    expect(subVm._rootEl).is.undefined
-  })
-
-  it('bind props with external data', () => {
-    bindSubVm(vm, subVm, {
-      attr: { a: function () { return this.b } }
-    })
-    expect(subVm.a).eql(2)
-  })
-
-  it('bind styles to a sub vm with root element', () => {
-    subVm._rootEl = {
-      attr: {},
-      style: {},
-      event: []
-    }
-    const template = {
-      style: { aaa: 2, bbb: function () { return this.a } }
-    }
-    initElement(subVm._rootEl)
-    bindSubVm(vm, subVm, template)
-    bindSubVmAfterInitialized(vm, subVm, template)
-    expect(subVm._rootEl.style.aaa).eql(2)
-    expect(subVm._rootEl.style.bbb).eql(1)
-    vm.a = 3
-    expect(subVm._rootEl.style.bbb).eql(3)
-  })
-
-  it('bind simply classlist to a sub vm with root element', () => {
-    subVm._rootEl = {
-      attr: {},
-      style: {},
-      event: []
-    }
-    const template = {
-      classList: ['class-style1']
-    }
-    initElement(subVm._rootEl)
-    bindSubVm(vm, subVm, template)
-    bindSubVmAfterInitialized(vm, subVm, template)
-    expect(subVm._rootEl.classStyle.aaa).eql(1)
-    expect(subVm._rootEl.classStyle.bbb).eql(2)
-  })
-
-  it('bind classlist to a sub vm with root element', () => {
-    subVm._rootEl = {
-      attr: {},
-      style: {},
-      event: []
-    }
-    const template = {
-      classList: function () {
-        return [this.c]
-      }
-    }
-    initElement(subVm._rootEl)
-    bindSubVm(vm, subVm, template)
-    bindSubVmAfterInitialized(vm, subVm, template)
-    expect(subVm._rootEl.classStyle.aaa).eql(1)
-    expect(subVm._rootEl.classStyle.bbb).eql(2)
-    vm.c = 'class-style2'
-    expect(subVm._rootEl.classStyle.aaa).eql(2)
-    expect(subVm._rootEl.classStyle.bbb).to.be.undefined
-    expect(subVm._rootEl.classStyle.ccc).eql(3)
-  })
-
-  it('bind events to a sub vm with root element', () => {
-    subVm._rootEl = {
-      attr: {},
-      style: {},
-      event: {}
-    }
-    const template = {
-      events: { click: 'foo' }
-    }
-    initElement(subVm._rootEl)
-    bindSubVm(vm, subVm, template)
-    bindSubVmAfterInitialized(vm, subVm, template)
-    // expect(subVm._rootEl.event.click).a('function')
-  })
-})
diff --git a/test/js-framework/unit/default/vm/dom-helper.js b/test/js-framework/unit/default/vm/dom-helper.js
deleted file mode 100644
index d0e5a54..0000000
--- a/test/js-framework/unit/default/vm/dom-helper.js
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-import chai from 'chai'
-const { expect } = chai
-
-import {
-  createElement,
-  createBlock,
-  createBody,
-  attachTarget,
-  moveTarget,
-  removeTarget
-} from '../../../../../runtime/frameworks/legacy/vm/dom-helper'
-import { Document } from '../../../../../runtime/vdom'
-import Listener from '../../../../../runtime/bridge/Listener'
-
-describe('help create body', () => {
-  let vm
-
-  beforeEach(() => {
-    vm = {
-      _app: { doc: new Document('foo', null, null, Listener) }
-    }
-  })
-
-  afterEach(() => {
-    vm._app.doc.destroy()
-    vm = null
-  })
-
-  it('create body with type', () => {
-    const result = createBody(vm, 'bar')
-    expect(result).is.an.object
-    expect(result.type).eql('bar')
-    expect(result.ref).eql('_root')
-    expect(result.docId).is.not.ok
-  })
-})
-
-describe('help create element', () => {
-  let vm
-
-  beforeEach(() => {
-    vm = {
-      _app: { doc: new Document('foo', null, null, Listener) }
-    }
-  })
-
-  afterEach(() => {
-    vm._app.doc.destroy()
-    vm = null
-  })
-
-  it('create element with type', () => {
-    const result = createElement(vm, 'bar')
-    expect(result).is.an.object
-    expect(result.type).eql('bar')
-    expect(result.docId).is.not.ok
-  })
-})
-
-describe('help create block', () => {
-  let vm
-
-  beforeEach(() => {
-    vm = {
-      _app: { doc: new Document('foo', null, null, Listener) }
-    }
-  })
-
-  afterEach(() => {
-    vm._app.doc.destroy()
-    vm = null
-  })
-
-  it('create block with element', () => {
-    const element = vm._app.doc.createElement('bar')
-    const result = createBlock(vm, element)
-    expect(result).is.an.object
-    expect(result.start).is.an.object
-    expect(result.end).is.an.object
-    expect(result.start.type).eql('comment')
-    expect(result.end.type).eql('comment')
-    expect(result.start.value).eql('start')
-    expect(result.end.value).eql('end')
-    expect(result.element).equal(element)
-    expect(result.element.children).eql([result.start, result.end])
-  })
-})
-
-describe('help attach target', () => {
-  let vm
-
-  beforeEach(() => {
-    vm = {
-      _app: { doc: new Document('foo', null, null, Listener) }
-    }
-  })
-
-  afterEach(() => {
-    vm._app.doc.destroy()
-    vm = null
-  })
-
-  it('attach body to documentElement', () => {
-    const oriCallnative = global.callNative
-    global.callNative = function () {}
-    const target = createBody(vm, 'bar')
-    const dest = vm._app.doc.documentElement
-    attachTarget(vm, target, dest)
-    expect(dest.children).eql([target])
-    global.callNative = oriCallnative
-  })
-
-  it('attach element to body', () => {
-    const target = createElement(vm, 'bar')
-    const dest = createBody(vm, 'baz')
-    attachTarget(vm, target, dest)
-    expect(dest.children).eql([target])
-  })
-
-  it('attach element to element', () => {
-    const target = createElement(vm, 'bar')
-    const dest = createElement(vm, 'baz')
-    attachTarget(vm, target, dest)
-    expect(dest.children).eql([target])
-  })
-
-  it('attach block to element', () => {
-    const parent = createElement(vm, 'bar')
-    const target = createBlock(vm, parent)
-    const dest = createElement(vm, 'baz')
-    attachTarget(vm, target, dest)
-    // block can't attach to another element
-    expect(dest.children).eql([])
-    expect(parent.children).eql([target.start, target.end])
-  })
-
-  it('attach element to block', () => {
-    const target = createElement(vm, 'bar')
-    const parent = createElement(vm, 'baz')
-    const dest = createBlock(vm, parent)
-    attachTarget(vm, target, dest)
-    expect(parent.children).eql([dest.start, target, dest.end])
-  })
-
-  it('attach block to block', () => {
-    const element = createElement(vm, 'bar')
-    const target = createBlock(vm, element)
-    const parent = createElement(vm, 'baz')
-    const dest = createBlock(vm, parent)
-    attachTarget(vm, target, dest)
-    // block can't attach to another element
-    expect(parent.children).eql([dest.start, dest.end])
-    expect(element.children).eql([target.start, target.end])
-  })
-
-  it('attach element to block with an update mark', () => {
-    const target = createElement(vm, 'bar')
-    const parent = createElement(vm, 'baz')
-    const dest = createBlock(vm, parent)
-    const mark = createElement(vm, 'qux')
-
-    attachTarget(vm, target, dest)
-    attachTarget(vm, mark, dest)
-    expect(parent.children).eql([dest.start, target, mark, dest.end])
-
-    dest.updateMark = mark
-    attachTarget(vm, target, dest)
-    expect(parent.children).eql([dest.start, mark, target, dest.end])
-    expect(dest.updateMark).eql(target)
-  })
-
-  it('attach block to block with an update mark', () => {
-    const element = createElement(vm, 'bar')
-    const target = createBlock(vm, element)
-    const parent = createElement(vm, 'baz')
-    const dest = createBlock(vm, parent)
-    const mark = createElement(vm, 'qux')
-
-    attachTarget(vm, target, dest)
-    attachTarget(vm, mark, dest)
-    // block can't attach to another element
-    expect(parent.children).eql([dest.start, mark, dest.end])
-    expect(element.children).eql([target.start, target.end])
-
-    dest.updateMark = mark
-    attachTarget(vm, target, dest)
-    // block can't attach to another element
-    expect(parent.children).eql([dest.start, mark, dest.end])
-    expect(element.children).eql([target.start, target.end])
-  })
-})
-
-describe('help move target', () => {
-  let vm, parent, dest, target1, block1, target2, block2, target3, block3
-
-  beforeEach(() => {
-    vm = {
-      _app: { doc: new Document('foo', null, null, Listener) }
-    }
-    parent = createElement(vm, 'r')
-    dest = createBlock(vm, parent)
-    target1 = createElement(vm, 't1')
-    attachTarget(vm, target1, dest)
-    block1 = createBlock(vm, dest)
-    target2 = createElement(vm, 't2')
-    attachTarget(vm, target2, dest)
-    block2 = createBlock(vm, dest)
-    target3 = createElement(vm, 't3')
-    attachTarget(vm, target3, block2)
-    block3 = createBlock(vm, block2)
-  })
-
-  afterEach(() => {
-    vm._app.doc.destroy()
-    vm = null
-  })
-
-  it('move an element to an element mark', () => {
-    /* eslint-disable indent */
-    expect(parent.children).eql([
-      dest.start,
-      target1, block1.start, block1.end,
-      target2, block2.start,
-        target3, block3.start, block3.end,
-      block2.end,
-      dest.end])
-    /* eslint-enable indent */
-
-    const mark = target2
-    dest.updateMark = mark
-
-    moveTarget(vm, target1, mark)
-
-    /* eslint-disable indent */
-    expect(parent.children).eql([
-      dest.start,
-      block1.start, block1.end,
-      target2, target1, block2.start,
-        target3, block3.start, block3.end,
-      block2.end,
-      dest.end])
-    /* eslint-enable indent */
-  })
-
-  it('move an element to a block mark', () => {
-    const mark = block2.end
-    dest.updateMark = mark
-
-    moveTarget(vm, target1, mark)
-
-    /* eslint-disable indent */
-    expect(parent.children).eql([
-      dest.start,
-      block1.start, block1.end,
-      target2, block2.start,
-        target3, block3.start, block3.end,
-      block2.end, target1,
-      dest.end])
-    /* eslint-enable indent */
-  })
-
-  it('move a block to an element mark', () => {
-    const mark = target2
-    dest.updateMark = mark
-
-    moveTarget(vm, block1, mark)
-
-    /* eslint-disable indent */
-    expect(parent.children).eql([
-      dest.start,
-      target1,
-      target2, block1.start, block1.end,
-      block2.start,
-        target3, block3.start, block3.end,
-      block2.end,
-      dest.end])
-    /* eslint-enable indent */
-  })
-
-  it('move a block to a block mark', () => {
-    const mark = block2.end
-    dest.updateMark = mark
-
-    moveTarget(vm, block1, mark)
-
-    /* eslint-disable indent */
-    expect(parent.children).eql([
-      dest.start,
-      target1,
-      target2,
-      block2.start,
-        target3, block3.start, block3.end,
-      block2.end, block1.start, block1.end,
-      dest.end])
-    /* eslint-enable indent */
-  })
-
-  it('move a whole block to a block mark', () => {
-    const mark = block1.end
-    dest.updateMark = mark
-
-    moveTarget(vm, block2, mark)
-
-    /* eslint-disable indent */
-    expect(parent.children).eql([
-      dest.start,
-      target1, block1.start, block1.end,
-      block2.start,
-        target3, block3.start, block3.end,
-      block2.end,
-      target2,
-      dest.end])
-    /* eslint-enable indent */
-  })
-})
-
-describe('help remove target', () => {
-  let vm
-
-  beforeEach(() => {
-    vm = {
-      _app: { doc: new Document('foo', null, null, Listener) }
-    }
-  })
-
-  afterEach(() => {
-    vm._app.doc.destroy()
-    vm = null
-  })
-
-  it('remove body', () => {
-    const oriCallnative = global.callNative
-    global.callNative = function () {}
-    const parent = vm._app.doc.documentElement
-    const element = createBody(vm, 'baz')
-    parent.appendChild(element)
-    expect(parent.children).eql([element])
-    removeTarget(vm, element)
-    expect(parent.children).eql([])
-    global.callNative = oriCallnative
-  })
-
-  it('remove element', () => {
-    const parent = createElement(vm, 'bar')
-    const element = createElement(vm, 'baz')
-    parent.appendChild(element)
-    expect(parent.children).eql([element])
-    removeTarget(vm, element)
-    expect(parent.children).eql([])
-  })
-
-  it('remove block', () => {
-    const element = createElement(vm, 'baz')
-    const prevElement = createElement(vm, 'prev')
-    const nextElement = createElement(vm, 'next')
-    const parent = createElement(vm, 'bar')
-    attachTarget(vm, prevElement, parent)
-    const block = createBlock(vm, parent)
-    attachTarget(vm, element, block)
-    attachTarget(vm, nextElement, parent)
-
-    expect(parent.children).eql([
-      prevElement, block.start, element, block.end, nextElement])
-
-    removeTarget(vm, block)
-    expect(parent.children).eql([
-      prevElement, nextElement])
-  })
-
-  it('remove block but preserved itself', () => {
-    const element = createElement(vm, 'baz')
-    const prevElement = createElement(vm, 'prev')
-    const nextElement = createElement(vm, 'next')
-    const parent = createElement(vm, 'bar')
-    attachTarget(vm, prevElement, parent)
-    const block = createBlock(vm, parent)
-    attachTarget(vm, element, block)
-    attachTarget(vm, nextElement, parent)
-
-    expect(parent.children).eql([
-      prevElement, block.start, element, block.end, nextElement])
-
-    removeTarget(vm, block, true)
-    expect(parent.children).eql([
-      prevElement, block.start, block.end, nextElement])
-  })
-})
diff --git a/test/js-framework/unit/default/vm/events.js b/test/js-framework/unit/default/vm/events.js
deleted file mode 100644
index b43b016..0000000
--- a/test/js-framework/unit/default/vm/events.js
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-import chai from 'chai'
-import sinon from 'sinon'
-import sinonChai from 'sinon-chai'
-const { expect } = chai
-chai.use(sinonChai)
-
-import Vm from '../../../../../runtime/frameworks/legacy/vm'
-import { Document } from '../../../../../runtime/vdom'
-
-describe('bind and fire events', () => {
-  let doc, customComponentMap, spy
-
-  function checkReady (vm, handler) {
-    /* istanbul ignore else */
-    if (vm._ready) {
-      handler()
-    }
-    else {
-      vm.$on('hook:ready', handler)
-    }
-  }
-
-  beforeEach(() => {
-    spy = sinon.spy()
-    doc = new Document('test', '', spy)
-    customComponentMap = {}
-  })
-
-  afterEach(() => {
-    doc.destroy()
-  })
-
-  it('bind event and fire in a single dom', (done) => {
-    customComponentMap.foo = {
-      template: {
-        type: 'container',
-        attr: {
-          a: function () { return this.x }
-        },
-        events: { click: 'handleClick' }
-      },
-      data: function () {
-        return { x: 1 }
-      },
-      methods: {
-        handleClick: function () {
-          this.x = 2
-        }
-      }
-    }
-
-    const app = { doc, customComponentMap }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    checkReady(vm, function () {
-      expect(doc.body.event.click.handler).a('function')
-
-      const el = doc.body
-      expect(el.attr.a).eql(1)
-      expect(spy.args.length).eql(1)
-      expect(doc.listener.updates.length).eql(0)
-
-      el.event.click.handler({ xxx: 1 })
-      expect(el.attr.a).eql(2)
-      expect(spy.args.length).eql(2)
-      expect(spy.args[1][0]).eql([
-        { module: 'dom', method: 'updateAttrs', args: [el.ref, { a: 2 }] }
-      ])
-
-      done()
-    })
-  })
-
-  it('emit, broadcast and dispatch vm events', (done) => {
-    customComponentMap.foo = {
-      template: {
-        type: 'aaa',
-        children: [{ type: 'bar', component: true }]
-      }
-    }
-    customComponentMap.bar = {
-      template: {
-        type: 'bbb'
-      }
-    }
-
-    const app = { doc, customComponentMap }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    checkReady(vm, function () {
-      doc.close()
-
-      expect(vm._childrenVms.length).eql(1)
-
-      const subVm = vm._childrenVms[0]
-      expect(vm._type).eql('foo')
-      expect(subVm._type).eql('bar')
-
-      const spyA = sinon.spy()
-      const spyB = sinon.spy()
-
-      vm.$on('customTypeA', spyA)
-      subVm.$on('customTypeA', spyB)
-
-      let detail = { aaa: 111 }
-      vm.$emit('customTypeA', detail)
-      expect(spyA.args.length).eql(1)
-      expect(spyB.args.length).eql(0)
-
-      detail = { aaa: 111 }
-      subVm.$emit('customTypeA', detail)
-      expect(spyA.args.length).eql(1)
-      expect(spyB.args.length).eql(1)
-
-      detail = { aaa: 111 }
-      vm.$broadcast('customTypeA', detail)
-      expect(spyA.args.length).eql(2)
-      expect(spyB.args.length).eql(2)
-
-      detail = { aaa: 111 }
-      subVm.$broadcast('customTypeA', detail)
-      expect(spyA.args.length).eql(2)
-      expect(spyB.args.length).eql(3)
-
-      detail = { aaa: 111 }
-      vm.$dispatch('customTypeA', detail)
-      expect(spyA.args.length).eql(3)
-      expect(spyB.args.length).eql(3)
-
-      detail = { aaa: 111 }
-      subVm.$dispatch('customTypeA', detail)
-      expect(spyA.args.length).eql(4)
-      expect(spyB.args.length).eql(4)
-
-      vm.$off('customTypeA', spyA)
-      subVm.$off('customTypeA')
-
-      detail = { aaa: 111 }
-      vm.$emit('customTypeA', detail)
-      detail = { aaa: 111 }
-      subVm.$emit('customTypeA', detail)
-      detail = { aaa: 111 }
-      vm.$broadcast('customTypeA', detail)
-      detail = { aaa: 111 }
-      subVm.$broadcast('customTypeA', detail)
-      detail = { aaa: 111 }
-      vm.$dispatch('customTypeA', detail)
-      detail = { aaa: 111 }
-      subVm.$dispatch('customTypeA', detail)
-
-      expect(spyA.args.length).eql(4)
-      expect(spyB.args.length).eql(4)
-
-      const spyAA = function (e) {
-        e.stop()
-        spyA()
-      }
-      const spyBB = function (e) {
-        e.stop()
-        spyB()
-      }
-
-      vm.$on('customTypeA', spyAA)
-      subVm.$on('customTypeA', spyBB)
-      vm.$off()
-      vm.$off('unknownTypeA', spyA)
-
-      detail = { aaa: 111 }
-      vm.$emit('customTypeA', detail)
-      expect(spyA.args.length).eql(5)
-      expect(spyB.args.length).eql(4)
-      detail = { aaa: 111 }
-      subVm.$emit('customTypeA', detail)
-      expect(spyA.args.length).eql(5)
-      expect(spyB.args.length).eql(5)
-      detail = { aaa: 111 }
-      vm.$broadcast('customTypeA', detail)
-      expect(spyA.args.length).eql(6)
-      expect(spyB.args.length).eql(5)
-      detail = { aaa: 111 }
-      subVm.$broadcast('customTypeA', detail)
-      expect(spyA.args.length).eql(6)
-      expect(spyB.args.length).eql(6)
-      detail = { aaa: 111 }
-      vm.$dispatch('customTypeA', detail)
-      expect(spyA.args.length).eql(7)
-      expect(spyB.args.length).eql(6)
-      detail = { aaa: 111 }
-      subVm.$dispatch('customTypeA', detail)
-      expect(spyA.args.length).eql(7)
-      expect(spyB.args.length).eql(7)
-
-      done()
-    })
-  })
-
-  it('broadcast for repeat vms', (done) => {
-    const vmSpy = sinon.spy()
-    const subVmSpy = sinon.spy()
-
-    customComponentMap.foo = {
-      data: function () {
-        return { list: [{ a: 1 }, { a: 2 }, { a: 3 }] }
-      },
-      template: {
-        type: 'container',
-        children: [{
-          type: 'bar', component: true,
-          repeat: function () { return this.list }
-        }]
-      },
-      events: {
-        customTypeA: function (e) {
-          vmSpy(this, e)
-        }
-      }
-    }
-    customComponentMap.bar = {
-      template: {
-        type: 'aaa'
-      },
-      events: {
-        customTypeA: function (e) {
-          subVmSpy(this, e)
-        }
-      }
-    }
-
-    const app = { doc, customComponentMap }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    checkReady(vm, function () {
-      doc.close()
-      expect(vm._childrenVms.length).eql(3)
-
-      let detail = { aaa: 111 }
-      vm.$emit('customTypeA', detail)
-      expect(vmSpy.args.length).eql(1)
-      expect(subVmSpy.args.length).eql(0)
-      expect(vmSpy.args[0][0]).equal(vm)
-      expect(vmSpy.args[0][1]).is.an.object
-      expect(vmSpy.args[0][1].detail).equal(detail)
-
-      detail = { aaa: 111 }
-      vm.$broadcast('customTypeA', detail)
-      expect(vmSpy.args.length).eql(2)
-      expect(subVmSpy.args.length).eql(3)
-      expect(vmSpy.args[1][0]).equal(vm)
-      expect(vmSpy.args[1][1]).is.an.object
-      expect(vmSpy.args[1][1].detail).equal(detail)
-      expect(subVmSpy.args[1][0]).equal(vm._childrenVms[1])
-      expect(subVmSpy.args[1][1]).is.an.object
-      expect(subVmSpy.args[1][1].detail).equal(detail)
-
-      done()
-    })
-  })
-
-  it('dispatch from repeat vms', (done) => {
-    const vmSpy = sinon.spy()
-    const subVmSpy = sinon.spy()
-
-    customComponentMap.foo = {
-      data: function () {
-        return { list: [{ a: 1 }, { a: 2 }, { a: 3 }] }
-      },
-      template: {
-        type: 'container',
-        children: [{
-          type: 'bar', component: true,
-          repeat: function () { return this.list }
-        }]
-      },
-      events: {
-        customTypeA: function (e) {
-          vmSpy(this, e)
-        }
-      }
-    }
-    customComponentMap.bar = {
-      template: {
-        type: 'aaa'
-      },
-      events: {
-        customTypeA: function (e) {
-          subVmSpy(this, e)
-        }
-      }
-    }
-
-    const app = { doc, customComponentMap }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    checkReady(vm, function () {
-      doc.close()
-      expect(vm._childrenVms.length).eql(3)
-
-      let detail = { aaa: 111 }
-      const subVm = vm._childrenVms[1]
-      subVm.$emit('customTypeA', detail)
-      expect(vmSpy.args.length).eql(0)
-      expect(subVmSpy.args.length).eql(1)
-      expect(subVmSpy.args[0][0]).equal(subVm)
-      expect(subVmSpy.args[0][1]).is.an.object
-      expect(subVmSpy.args[0][1].detail).equal(detail)
-
-      detail = { aaa: 111 }
-      subVm.$dispatch('customTypeA', detail)
-      expect(vmSpy.args.length).eql(1)
-      expect(subVmSpy.args.length).eql(2)
-      expect(vmSpy.args[0][0]).equal(vm)
-      expect(vmSpy.args[0][1]).is.an.object
-      expect(vmSpy.args[0][1].detail).equal(detail)
-      expect(subVmSpy.args[1][0]).equal(subVm)
-      expect(subVmSpy.args[1][1]).is.an.object
-      expect(subVmSpy.args[1][1].detail).equal(detail)
-
-      done()
-    })
-  })
-
-  it('lifecycel events', (done) => {
-    const vmSpy = sinon.spy()
-
-    customComponentMap.foo = {
-      template: {
-        type: 'aaa',
-        children: [{ type: 'bar', component: true }]
-      },
-      data: function () {
-        return {
-          x: 1
-        }
-      },
-      init: function (e) {
-        vmSpy(this, e)
-        expect(this._data).is.not.ok
-        expect(this.x).is.not.ok
-        expect(this._parentEl).is.not.ok
-      },
-      created: function (e) {
-        vmSpy(this, e)
-        expect(this._data).is.ok
-        expect(this.x).is.ok
-        expect(this._parentEl).is.not.ok
-      },
-      ready: function (e) {
-        vmSpy(this, e)
-        expect(this._data).is.ok
-        expect(this.x).is.ok
-        expect(this._parentEl).is.ok
-        expect(this._parentEl.children.length).eql(1)
-      }
-    }
-    customComponentMap.bar = {
-      template: {
-        type: 'bbb'
-      },
-      created: function (e) {
-        vmSpy(this, e)
-      }
-    }
-
-    const app = { doc, customComponentMap }
-    const evSpy = sinon.spy()
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app }, null, null,
-      {
-        'hook:init': () => evSpy('hook:init'),
-        'hook:created': () => evSpy('hook:created'),
-        'hook:ready': () => evSpy('hook:ready')
-      }
-    )
-
-    checkReady(vm, function () {
-      doc.close()
-
-      expect(vmSpy.args.length).eql(4)
-
-      const subVm = vm._childrenVms[0]
-      const calls = vmSpy.args.map(args => [args[0], args[1].type])
-      expect(calls).eql([
-        [vm, 'hook:init'],
-        [vm, 'hook:created'],
-        [subVm, 'hook:created'],
-        [vm, 'hook:ready']
-      ])
-
-      expect(evSpy.callCount).to.be.equal(3)
-      expect(evSpy.args).to.deep.equal([
-        ['hook:init'],
-        ['hook:created'],
-        ['hook:ready']
-      ])
-
-      done()
-    })
-  })
-})
diff --git a/test/js-framework/unit/default/vm/vm.js b/test/js-framework/unit/default/vm/vm.js
deleted file mode 100644
index 761c913..0000000
--- a/test/js-framework/unit/default/vm/vm.js
+++ /dev/null
@@ -1,1975 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-import chai from 'chai'
-import sinon from 'sinon'
-import sinonChai from 'sinon-chai'
-const { expect } = chai
-chai.use(sinonChai)
-
-import Vm from '../../../../../runtime/frameworks/legacy/vm'
-import { Document } from '../../../../../runtime/vdom'
-import { init as resetTaskHandler } from '../../../../../runtime/bridge/TaskCenter'
-import Differ from '../../../../../runtime/frameworks/legacy/app/differ'
-
-const oriCallNative = global.callNative
-
-describe('generate virtual dom for a single vm', () => {
-  const spy = sinon.spy()
-  const spy1 = sinon.spy()
-  let doc
-  let customComponentMap
-  let differ
-
-  beforeEach(() => {
-    differ = new Differ('test')
-    doc = new Document('test', '', function (actions) {
-      actions.forEach((action) => {
-        spy.apply(null, ['test', action.method].concat(action.args))
-      })
-    })
-    customComponentMap = {}
-  })
-
-  afterEach(() => {
-    spy.reset()
-    spy1.reset()
-    doc.destroy()
-  })
-
-  it('$watch', () => {
-    const data = {
-      a: {
-        b: 1
-      }
-    }
-
-    customComponentMap.foo = {
-      template: {
-        type: 'container'
-      },
-      data: data
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(vm._app).equal(app)
-    expect(doc.body).is.an.object
-
-    vm.$watch(function () {
-      return this.a.b
-    }, (value) => {
-      expect(value).eql(2)
-    })
-
-    data.a.b = 2
-  })
-
-  it('vm.data is not a object', () => {
-    const data = 'hello'
-
-    customComponentMap.foo = {
-      template: {
-        type: 'container'
-      },
-      data: data
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(vm._app).equal(app)
-    expect(doc.body).is.an.object
-  })
-
-  it('no param parentVm', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'container'
-      }
-    }
-
-    const vm = new Vm('foo', customComponentMap.foo, null)
-
-    expect(vm._app).is.an.object
-    expect(doc.body).is.an.object
-  })
-
-  it('no param options', () => {
-    const app = {}
-    const vm = new Vm('foo', null, { _app: app })
-
-    expect(vm._app).is.an.object
-    expect(doc.body).is.an.object
-  })
-
-  it('old method.ready', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'container'
-      },
-      methods: {
-        ready: spy1
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(vm._app).equal(app)
-    expect(doc.body).is.an.object
-    expect(doc.body.type).eql('container')
-    expect(spy1).callCount(1)
-  })
-
-  it('generate an static element ', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'container',
-        attr: {
-          a: 1,
-          b: 2,
-          static: ''
-        },
-        style: {
-          c: 3,
-          d: 4
-        }
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(vm._app).equal(app)
-    expect(vm._static).eql(true)
-    expect(doc.body).is.an.object
-    expect(doc.body.type).eql('container')
-    expect(doc.body.attr).eql({ a: 1, b: 2, static: '' })
-    expect(doc.body.style).eql({ c: 3, d: 4 })
-    expect(doc.body.children).is.an.array
-    expect(doc.body.children.length).eql(0)
-  })
-
-  it('generate an single element', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'container',
-        attr: {
-          a: 1,
-          b: 2
-        },
-        style: {
-          c: 3,
-          d: 4
-        }
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(vm._app).equal(app)
-    expect(doc.body).is.an.object
-    expect(doc.body.type).eql('container')
-    expect(doc.body.attr).eql({ a: 1, b: 2 })
-    expect(doc.body.style).eql({ c: 3, d: 4 })
-    expect(doc.body.children).is.an.array
-    expect(doc.body.children.length).eql(0)
-  })
-
-  it('generate an element tree', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'container', attr: { a: 1, b: 2 }, style: { c: 3, d: 4 },
-        children: [
-          { type: 'image', attr: { src: '<some image url>' }},
-          { type: 'text', attr: { value: '<some text content>' }}
-        ]
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(vm._app).equal(app)
-    const el = doc.body
-    expect(el.type).eql('container')
-    expect(el.attr).eql({ a: 1, b: 2 })
-    expect(el.style).eql({ c: 3, d: 4 })
-    expect(el.children).is.an.array
-    expect(el.children.length).eql(2)
-
-    const image = el.children[0]
-    const text = el.children[1]
-    expect(image.type).eql('image')
-    expect(image.attr).eql({ src: '<some image url>' })
-    expect(text.type).eql('text')
-    expect(text.attr).eql({ value: '<some text content>' })
-  })
-
-  it('generate an element tree with component options', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'cell',
-        children: [
-          { type: 'text', attr: { value: '<some text content>' }}
-        ]
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(spy.firstCall.args[0]).to.be.equal('test')
-    expect(spy.firstCall.args[1]).to.be.equal('createBody')
-    expect(spy.firstCall.args[2]).to.deep.equal({
-      ref: '_root',
-      type: 'cell',
-      attr: {
-        append: 'tree'
-      },
-      children: [{
-        ref: spy.firstCall.args[2].children[0].ref,
-        type: 'text',
-        attr: {
-          value: '<some text content>'
-        },
-        style: {}
-      }],
-      style: {}
-    })
-
-    expect(vm._app).equal(app)
-    const el = doc.body
-    expect(el.type).eql('cell')
-    expect(el.children).is.an.array
-    expect(el.children.length).eql(1)
-
-    const text = el.children[0]
-    expect(text.type).eql('text')
-    expect(text.attr).eql({ value: '<some text content>' })
-  })
-
-  it('generate an element tree with data binding', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'container', attr: { a: 1, b: 2 }, style: { c: 3, d: 4 },
-        children: [
-          { type: 'image', attr: { src: function () { return this.x } }},
-          { type: 'text', attr: { value: function () { return this.n } }},
-          { type: 'text', attr: { value: function () { return this.m } }}
-        ]
-      },
-      data: {
-        x: '<some image url>', y: '<some text content>'
-      },
-      computed: {
-        n: function () {
-          return this.y.toUpperCase()
-        },
-        m: {
-          get: function () {
-            return this.y.toUpperCase()
-          },
-          set: function (v) {
-            this.y = v
-          }
-        }
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(vm._app).equal(app)
-    expect(vm.x).eql('<some image url>')
-    expect(vm.y).eql('<some text content>')
-    expect(vm.n).eql('<SOME TEXT CONTENT>')
-    expect(vm.m).eql('<SOME TEXT CONTENT>')
-
-    const el = doc.body
-    expect(el.type).eql('container')
-    expect(el.attr).eql({ a: 1, b: 2 })
-    expect(el.style).eql({ c: 3, d: 4 })
-    expect(el.children).is.an.array
-    expect(el.children.length).eql(3)
-
-    const image = el.children[0]
-    const text = el.children[1]
-    const text2 = el.children[2]
-    expect(image.type).eql('image')
-    expect(image.attr).eql({ src: '<some image url>' })
-    expect(text.type).eql('text')
-    expect(text.attr).eql({ value: '<SOME TEXT CONTENT>' })
-    expect(text2.type).eql('text')
-    expect(text2.attr).eql({ value: '<SOME TEXT CONTENT>' })
-
-    vm.x = '<some image url>'
-    differ.flush()
-    expect(el).equal(doc.body)
-    expect(image).equal(el.children[0])
-    expect(text).equal(el.children[1])
-    expect(text2).equal(el.children[2])
-
-    vm.x = 'other string value'
-    differ.flush()
-    expect(el).equal(doc.body)
-    expect(image).equal(el.children[0])
-    expect(image.attr).eql({ src: 'other string value' })
-
-    vm.y = 'other string value'
-    differ.flush()
-    expect(el).equal(doc.body)
-    expect(text).equal(el.children[1])
-    expect(text.attr).eql({ value: 'OTHER STRING VALUE' })
-    expect(text2).equal(el.children[2])
-    expect(text2.attr).eql({ value: 'OTHER STRING VALUE' })
-
-    vm.m = 'third string value'
-    differ.flush()
-    expect(vm.x).eql('other string value')
-    expect(vm.y).eql('third string value')
-    expect(vm.n).eql('THIRD STRING VALUE')
-    expect(vm.m).eql('THIRD STRING VALUE')
-    expect(el).equal(doc.body)
-    expect(text).equal(el.children[1])
-    expect(text.attr).eql({ value: 'THIRD STRING VALUE' })
-    expect(text2).equal(el.children[2])
-    expect(text2.attr).eql({ value: 'THIRD STRING VALUE' })
-  })
-
-  it('generate an element tree with shown', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'container',
-        children: [
-          { type: 'prev' },
-          {
-            shown: function () { return this.y },
-            type: 'image', attr: { src: function () { return this.x } }
-          },
-          { type: 'next' }
-        ]
-      },
-      data: {
-        x: '<some image url>', y: true
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(vm._app).equal(app)
-    expect(vm.x).eql('<some image url>')
-    expect(vm.y).eql(true)
-
-    const el = doc.body
-    expect(el.type).eql('container')
-    expect(el.children).is.an.array
-    expect(el.children.length).eql(5)
-
-    const prev = el.children[0]
-    const starter = el.children[1]
-    const image = el.children[2]
-    const ender = el.children[3]
-    const next = el.children[4]
-    expect(prev.type).eql('prev')
-    expect(starter.type).eql('comment')
-    expect(ender.type).eql('comment')
-    expect(next.type).eql('next')
-    expect(image.type).eql('image')
-    expect(image.attr).eql({ src: '<some image url>' })
-
-    vm.y = false
-    differ.flush()
-
-    expect(el).equal(doc.body)
-    expect(el.children).is.an.array
-    expect(el.children.length).eql(4)
-    expect(prev).equal(el.children[0])
-    expect(starter).equal(el.children[1])
-    expect(ender).equal(el.children[2])
-    expect(next).equal(el.children[3])
-
-    vm.y = true
-    differ.flush()
-
-    expect(el).equal(doc.body)
-    expect(el.children).is.an.array
-    expect(el.children.length).eql(5)
-    expect(prev).equal(el.children[0])
-    expect(starter).equal(el.children[1])
-
-    const image2 = el.children[2]
-    expect(image2.type).eql('image')
-    expect(image2.attr).eql({ src: '<some image url>' })
-    expect(ender).equal(el.children[3])
-    expect(next).equal(el.children[4])
-  })
-
-  it('generate an element tree with repeat', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'container',
-        children: [
-          { type: 'prev' },
-          {
-            repeat: function () { return this.list },
-            type: 'image', attr: { src: function () { return this.x } }
-          },
-          { type: 'next' }
-        ]
-      },
-      data: {
-        x: '<some image url>',
-        list: [
-          { uid: 1, x: 1 }, { uid: 2, x: 2 }, { uid: 3 }
-        ]
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(vm._app).equal(app)
-    expect(vm.x).eql('<some image url>')
-    expect(vm.list).eql([
-      { uid: 1, x: 1, $index: 0 },
-      { uid: 2, x: 2, $index: 1 },
-      { uid: 3, $index: 2 }])
-
-    const el = doc.body
-    expect(el.type).eql('container')
-    expect(el.children).is.an.array
-    expect(el.children.length).eql(7)
-
-    const prev = el.children[0]
-    const starter = el.children[1]
-    const ender = el.children[5]
-    const next = el.children[6]
-    expect(prev.type).eql('prev')
-    expect(starter.type).eql('comment')
-    expect(ender.type).eql('comment')
-    expect(next.type).eql('next')
-
-    expect(el.children[2].type).eql('image')
-    expect(el.children[2].attr).eql({ src: 1 })
-    expect(el.children[3].type).eql('image')
-    expect(el.children[3].attr).eql({ src: 2 })
-    expect(el.children[4].type).eql('image')
-    expect(el.children[4].attr).eql({ src: '<some image url>' })
-
-    vm.list[1].x = 3
-    differ.flush()
-    expect(el.children.length).eql(7)
-    expect(el.children[2].attr).eql({ src: 1 })
-    expect(el.children[3].attr).eql({ src: 3 })
-    expect(el.children[4].attr).eql({ src: '<some image url>' })
-
-    vm.x = 'other string value'
-    differ.flush()
-    expect(el.children.length).eql(7)
-    expect(el.children[2].attr).eql({ src: 1 })
-    expect(el.children[3].attr).eql({ src: 3 })
-    expect(el.children[4].attr).eql({ src: 'other string value' })
-
-    vm.list.push({ uid: 4, x: 4 })
-    vm.list.push({ uid: 5 }, { uid: 6, x: 6 })
-
-    differ.flush()
-
-    expect(el.children.length).eql(10)
-    expect(el.children[2].attr).eql({ src: 1 })
-    expect(el.children[3].attr).eql({ src: 3 })
-    expect(el.children[4].attr).eql({ src: 'other string value' })
-    expect(el.children[5].attr).eql({ src: 4 })
-    expect(el.children[6].attr).eql({ src: 'other string value' })
-    expect(el.children[7].attr).eql({ src: 6 })
-
-    vm.list.splice(1, 2, { uid: 7, x: 7 })
-    differ.flush()
-
-    expect(el.children.length).eql(9)
-    expect(el.children[2].attr).eql({ src: 1 })
-    expect(el.children[3].attr).eql({ src: 7 })
-    expect(el.children[4].attr).eql({ src: 4 })
-    expect(el.children[5].attr).eql({ src: 'other string value' })
-    expect(el.children[6].attr).eql({ src: 6 })
-
-    vm.list.$set(0, { uid: 321, x: 32 })
-    vm.list.$set(10, { uid: 8889, x: 8888 })
-    differ.flush()
-
-    expect(el.children.length).eql(10)
-    expect(el.children[2].attr).eql({ src: 32 })
-    expect(el.children[7].attr).eql({ src: 8888 })
-
-    vm.list.unshift({ uid: 12345, x: 123456 })
-    differ.flush()
-
-    expect(el.children.length).eql(11)
-    expect(el.children[2].attr).eql({ src: 123456 })
-  })
-
-  it('generate an static element tree with shown and repeat', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'container',
-        attr: {
-          static: ''
-        },
-        children: [
-          { type: 'prev' },
-          {
-            shown: function () { return this.x % 2 === 0 },
-            repeat: function () { return this.list },
-            type: 'image', attr: { src: function () { return this.x } }
-          },
-          { type: 'next' }
-        ]
-      },
-      data: {
-        x: '<some image url>',
-        list: [
-          { uid: 1, x: 1 }, { uid: 2, x: 2 }, { uid: 3 }
-        ]
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(vm._app).equal(app)
-    expect(vm._static).equal(true)
-    expect(vm.x).eql('<some image url>')
-    expect(vm.list).eql([
-      { uid: 1, x: 1, $index: 0 },
-      { uid: 2, x: 2, $index: 1 },
-      { uid: 3, $index: 2 }])
-
-    const el = doc.body
-    expect(el.type).eql('container')
-    expect(el.children).is.an.array
-    expect(el.children.length).eql(11)
-
-    const prev = el.children[0]
-    const next = el.children[10]
-    expect(prev.type).eql('prev')
-    expect(el.children[1].type).eql('comment')
-    expect(el.children[1].value).eql('start')
-    expect(el.children[9].type).eql('comment')
-    expect(el.children[9].value).eql('end')
-
-    expect(el.children[2].type).eql('comment')
-    expect(el.children[2].value).eql('start')
-    expect(el.children[3].type).eql('comment')
-    expect(el.children[3].value).eql('end')
-
-    expect(el.children[4].type).eql('comment')
-    expect(el.children[4].value).eql('start')
-    expect(el.children[5].type).eql('image')
-    expect(el.children[5].attr).eql({ src: 2 })
-    expect(el.children[6].type).eql('comment')
-    expect(el.children[6].value).eql('end')
-
-    expect(el.children[7].type).eql('comment')
-    expect(el.children[7].value).eql('start')
-    expect(el.children[8].type).eql('comment')
-    expect(el.children[8].value).eql('end')
-    expect(next.type).eql('next')
-
-    vm.list[0].x = 4
-    differ.flush()
-
-    expect(el.children.length).eql(11)
-    expect(el.children[5].type).eql('image')
-    expect(el.children[5].attr).eql({ src: 2 })
-  })
-
-  it('generate an element tree which root element with shown', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'container',
-        shown: function () { return this.x % 2 === 0 }
-      },
-      data: {
-        x: 2
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(vm._app).equal(app)
-    expect(vm.x).eql(2)
-  })
-
-  it('append tree', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'container',
-        attr: {
-          append: 'tree'
-        },
-        children: [
-          { type: 'a' },
-          { repeat: {}}
-        ]
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(vm._app).equal(app)
-  })
-
-  it('repeat is not a function', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'container',
-        children: [
-          { type: 'a' },
-          { repeat: {}}
-        ]
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(vm._app).equal(app)
-  })
-
-  it('repeat oldStyle with item which not a object', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'container',
-        children: [
-          { type: 'a' },
-          { repeat: function () { return [1, 2, 3] } }
-        ]
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(vm._app).equal(app)
-  })
-
-  it('classList length is zero', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'container',
-        classList: []
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(vm._app).equal(app)
-  })
-
-  it('classList is a function', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'container',
-        classList: function () { return [] }
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(vm._app).equal(app)
-  })
-
-  it('generate an element tree which root element with repeat', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'container',
-        repeat: function () { return this.list }
-      },
-      data: {
-        list: [
-          { uid: 1, x: 1 }, { uid: 2, x: 2 }, { uid: 3 }
-        ]
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(vm._app).equal(app)
-    expect(vm.list).eql([
-      { uid: 1, x: 1 },
-      { uid: 2, x: 2 },
-      { uid: 3 }
-    ])
-  })
-
-  it('generate an element tree with shown and repeat', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'container',
-        children: [
-          { type: 'prev' },
-          {
-            shown: function () { return this.x % 2 === 0 },
-            repeat: function () { return this.list },
-            type: 'image', attr: { src: function () { return this.x } }
-          },
-          { type: 'next' }
-        ]
-      },
-      data: {
-        x: '<some image url>',
-        list: [
-          { uid: 1, x: 1 }, { uid: 2, x: 2 }, { uid: 3 }
-        ]
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(vm._app).equal(app)
-    expect(vm.x).eql('<some image url>')
-    expect(vm.list).eql([
-      { uid: 1, x: 1, $index: 0 },
-      { uid: 2, x: 2, $index: 1 },
-      { uid: 3, $index: 2 }])
-
-    const el = doc.body
-    expect(el.type).eql('container')
-    expect(el.children).is.an.array
-    expect(el.children.length).eql(11)
-
-    const prev = el.children[0]
-    const next = el.children[10]
-    expect(prev.type).eql('prev')
-    expect(el.children[1].type).eql('comment')
-    expect(el.children[1].value).eql('start')
-    expect(el.children[9].type).eql('comment')
-    expect(el.children[9].value).eql('end')
-
-    expect(el.children[2].type).eql('comment')
-    expect(el.children[2].value).eql('start')
-    expect(el.children[3].type).eql('comment')
-    expect(el.children[3].value).eql('end')
-
-    expect(el.children[4].type).eql('comment')
-    expect(el.children[4].value).eql('start')
-    expect(el.children[5].type).eql('image')
-    expect(el.children[5].attr).eql({ src: 2 })
-    expect(el.children[6].type).eql('comment')
-    expect(el.children[6].value).eql('end')
-
-    expect(el.children[7].type).eql('comment')
-    expect(el.children[7].value).eql('start')
-    expect(el.children[8].type).eql('comment')
-    expect(el.children[8].value).eql('end')
-    expect(next.type).eql('next')
-
-    vm.list[0].x = 4
-    differ.flush()
-
-    expect(el.children.length).eql(12)
-    expect(el.children[3].type).eql('image')
-    expect(el.children[3].attr).eql({ src: 4 })
-    expect(el.children[6].type).eql('image')
-    expect(el.children[6].attr).eql({ src: 2 })
-  })
-
-  it('generate more than one group of elements with the same repeat data', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'container',
-        children: [
-          { type: 'begin' },
-          {
-            repeat: {
-              expression: function () { return this.list },
-              value: 'v1'
-            },
-            type: 'image', attr: { src: function () { return this.v1.x } }
-          },
-          { type: 'middle' },
-          {
-            repeat: {
-              expression: function () { return this.list },
-              value: 'v2'
-            },
-            type: 'text', attr: { value: function () { return this.v2.x } }
-          },
-          { type: 'end' }
-        ]
-      },
-      data: {
-        list: [
-          { uid: 1, x: 1 }, { uid: 2, x: 2 }, { uid: 3 }
-        ]
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(vm._app).equal(app)
-    expect(vm.list).eql([
-      { uid: 1, x: 1 },
-      { uid: 2, x: 2 },
-      { uid: 3 }])
-
-    const el = doc.body
-    expect(el.type).eql('container')
-    expect(el.children).is.an.array
-
-    // [begin, comment, image x 3, comment, middle, comment, text x 3, comment, end]
-    expect(el.children.length).eql(13)
-
-    expect(el.children[0].type).eql('begin')
-    expect(el.children[1].type).eql('comment')
-    expect(el.children[1].value).eql('start')
-    expect(el.children[2].type).eql('image')
-    expect(el.children[2].attr).eql({ src: 1 })
-    expect(el.children[3].type).eql('image')
-    expect(el.children[3].attr).eql({ src: 2 })
-    expect(el.children[4].type).eql('image')
-    expect(el.children[4].attr).eql({})
-    expect(el.children[5].type).eql('comment')
-    expect(el.children[5].value).eql('end')
-    expect(el.children[6].type).eql('middle')
-    expect(el.children[7].type).eql('comment')
-    expect(el.children[7].value).eql('start')
-    expect(el.children[8].type).eql('text')
-    expect(el.children[8].attr).eql({ value: 1 })
-    expect(el.children[9].type).eql('text')
-    expect(el.children[9].attr).eql({ value: 2 })
-    expect(el.children[10].type).eql('text')
-    expect(el.children[10].attr).eql({})
-    expect(el.children[11].type).eql('comment')
-    expect(el.children[11].value).eql('end')
-    expect(el.children[12].type).eql('end')
-
-    vm.list[0].x = 4
-    differ.flush()
-
-    expect(el.children.length).eql(13)
-    expect(el.children[2].attr).eql({ src: 4 })
-    expect(el.children[8].attr).eql({ value: 4 })
-
-    // [begin, comment, image x 4, comment, middle, comment, text x 4, comment, end]
-    vm.list.push({ uid: 10, x: 10 })
-    differ.flush()
-
-    expect(el.children.length).eql(15)
-    expect(el.children[5].attr).eql({ src: 10 })
-    expect(el.children[12].attr).eql({ value: 10 })
-
-    // [begin, comment, image x 2, comment, middle, comment, text x 2, comment, end]
-    vm.list = [
-      { uid: 100, x: 100 }, { uid: 1, x: 1 }
-    ]
-    differ.flush()
-
-    expect(el.children.length).eql(11)
-    expect(el.children[2].attr).eql({ src: 100 })
-    expect(el.children[3].attr).eql({ src: 1 })
-    expect(el.children[7].attr).eql({ value: 100 })
-    expect(el.children[8].attr).eql({ value: 1 })
-
-    vm.list[0].x = 4
-    differ.flush()
-
-    expect(el.children.length).eql(11)
-    expect(el.children[2].attr).eql({ src: 4 })
-    expect(el.children[3].attr).eql({ src: 1 })
-    expect(el.children[7].attr).eql({ value: 4 })
-    expect(el.children[8].attr).eql({ value: 1 })
-
-    vm.list[1].x = 5
-    differ.flush()
-
-    expect(el.children.length).eql(11)
-    expect(el.children[2].attr).eql({ src: 4 })
-    expect(el.children[3].attr).eql({ src: 5 })
-    expect(el.children[7].attr).eql({ value: 4 })
-    expect(el.children[8].attr).eql({ value: 5 })
-  })
-
-  it('generate an element with external data', () => {
-    customComponentMap.foo = {
-      data: () => {
-        return { a: 10, b: 20 }
-      },
-      template: {
-        type: 'container',
-        attr: {
-          x: function () { return this.a },
-          y: function () { return this.b }
-        }
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app }, null, { a: 1000 })
-
-    expect(vm._app).equal(app)
-
-    const el = doc.body
-    expect(el.type).eql('container')
-    expect(el.attr).eql({ x: 1000, y: 20 })
-
-    vm.a = 100
-    vm.b = 200
-    differ.flush()
-
-    expect(el).equal(doc.body)
-    expect(el.attr).eql({ x: 100, y: 200 })
-  })
-})
-
-describe('generate virtual dom for sub vm', () => {
-  let doc
-  let customComponentMap
-  let differ
-
-  beforeEach(() => {
-    global.callNative = function () {}
-    resetTaskHandler()
-    doc = new Document('test', null, null)
-    customComponentMap = {}
-    differ = new Differ('test')
-  })
-
-  afterEach(() => {
-    doc.destroy()
-    global.callNative = oriCallNative
-  })
-
-  it('generate sub elements', () => {
-    customComponentMap.foo = {
-      data: function () {
-        return {
-          showbar1: false,
-          showbar2: false,
-          bar2list: [{
-            id: 'bar2-1'
-          }, {
-            id: 'bar2-2'
-          }]
-        }
-      },
-      template: {
-        type: 'div',
-        children: [
-          { type: 'bar', id: 'bar', component: true,
-            events: { click: 'handleClick' }
-          },
-          { type: 'bar1',
-            shown: function () { return this.showbar1 },
-            id: 'bar1', component: true
-          },
-          { type: 'bar2',
-              shown: function () { return this.showbar2 },
-              repeat: function () { return this.bar2list },
-              id: function () { return this.id },
-              component: true
-          }
-        ]
-      },
-      methods: {
-        handleClick: sinon.spy()
-      }
-    }
-    customComponentMap.bar = {
-      template: {
-        type: 'container',
-        children: [{ type: 'aaa' }, { type: 'bbb' }]
-      }
-    }
-    customComponentMap.bar1 = {
-      template: {
-        type: 'container',
-        children: [{ type: 'aaaa' }, { type: 'bbbb' }]
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(vm._app).equal(app)
-    expect(vm._rootEl).to.deep.equal(vm._parentEl.children[0])
-
-    expect(vm._childrenVms.length).to.be.equal(1)
-    expect(vm._childrenVms[0]).to.deep.equal(vm._ids['bar'].vm)
-    expect(vm._childrenVms[0]._rootEl).to.deep.equal(vm._ids['bar'].el)
-
-    const el = doc.body
-    expect(el.type).eql('div')
-    expect(el.pureChildren).is.an.array
-    expect(el.pureChildren.length).eql(1)
-
-    const sub = el.children[0]
-    expect(sub.type).eql('container')
-    expect(sub.children).is.an.array
-    expect(sub.children.length).eql(2)
-    expect(sub.children[0].type).eql('aaa')
-    expect(sub.children[1].type).eql('bbb')
-    expect(sub.event.click).is.a.function
-
-    const spy = customComponentMap.foo.methods.handleClick
-    sub.event.click.handler(1, 2, 3)
-    expect(spy.args.length).eql(1)
-    expect(spy.args[0]).eql([1, 2, 3])
-
-    vm.showbar1 = true
-    differ.flush()
-
-    expect(vm._childrenVms.length).to.be.equal(2)
-    expect(vm._childrenVms[1]).to.deep.equal(vm._ids['bar1'].vm)
-    expect(vm._childrenVms[1]._rootEl).to.deep.equal(vm._ids['bar1'].el)
-
-    vm.showbar2 = true
-    differ.flush()
-
-    expect(vm._ids['bar2-1'].vm).to.be.not.undefined
-    expect(vm._ids['bar2-1'].el).to.be.not.undefined
-    expect(vm._ids['bar2-2'].vm).to.be.not.undefined
-    expect(vm._ids['bar2-2'].el).to.be.not.undefined
-  })
-
-  it('generate sub element with static', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'container',
-        attr: {
-          static: ''
-        },
-        children: [{ type: 'bar', component: true }]
-      }
-    }
-    customComponentMap.bar = {
-      replace: true,
-      template: {
-        type: 'container',
-        children: [{ type: 'aaa' }]
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(vm._app).equal(app)
-    expect(vm._static).eql(true)
-    const el = doc.body
-    expect(el.type).eql('container')
-    expect(el.children).is.an.array
-    expect(el.children.length).eql(1)
-
-    const aaa = el.children[0]
-    expect(aaa.type).eql('aaa')
-    expect(vm._childrenVms.length).to.be.equal(1)
-    expect(vm._childrenVms[0]._static).eql(true)
-  })
-
-  it('generate replaced sub element', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'container',
-        children: [{ type: 'bar', component: true }]
-      }
-    }
-    customComponentMap.bar = {
-      replace: true,
-      template: {
-        type: 'container',
-        children: [{ type: 'aaa' }]
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(vm._app).equal(app)
-    const el = doc.body
-    expect(el.type).eql('container')
-    expect(el.children).is.an.array
-    expect(el.children.length).eql(1)
-
-    const aaa = el.children[0]
-    expect(aaa.type).eql('aaa')
-  })
-
-  it('generate replaced sub elements', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'container',
-        children: [{ type: 'bar', component: true }]
-      }
-    }
-    customComponentMap.bar = {
-      replace: true,
-      template: {
-        type: 'container',
-        children: [{ type: 'aaa' }, { type: 'bbb' }]
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(vm._app).equal(app)
-    const el = doc.body
-    expect(el.type).eql('container')
-    expect(el.children).is.an.array
-    expect(el.children.length).eql(4)
-
-    expect(el.children[0].type).eql('comment')
-    const aaa = el.children[1]
-    expect(aaa.type).eql('aaa')
-    const bbb = el.children[2]
-    expect(bbb.type).eql('bbb')
-    expect(el.children[3].type).eql('comment')
-  })
-
-  it('generate sub elements with no props', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'container',
-        children: [{ type: 'bar', component: true, attr: { x: 10, y: 20 }}]
-      }
-    }
-    customComponentMap.bar = {
-      data: () => {
-        return { x: 1, y: 2 }
-      },
-      template: {
-        type: 'container',
-        children: [
-          { type: 'aaa', attr: { a: function () { return this.x } }},
-          { type: 'bbb', attr: { b: function () { return this.y } }}
-        ]
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(vm._app).equal(app)
-    const el = doc.body
-    expect(el.type).eql('container')
-    expect(el.children).is.an.array
-    expect(el.children.length).eql(1)
-
-    const sub = el.children[0]
-    const aaa = sub.children[0]
-    expect(aaa.type).eql('aaa')
-    expect(aaa.attr).eql({ a: 10 })
-    const bbb = sub.children[1]
-    expect(bbb.type).eql('bbb')
-    expect(bbb.attr).eql({ b: 20 })
-  })
-
-  it('generate sub elements with array props', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'container',
-        children: [{ type: 'bar', component: true, attr: { x: 10, y: 20 }}]
-      }
-    }
-    customComponentMap.bar = {
-      props: ['x'],
-      data: () => {
-        return { x: 1, y: 2 }
-      },
-      template: {
-        type: 'container',
-        children: [
-          { type: 'aaa', attr: { a: function () { return this.x } }},
-          { type: 'bbb', attr: { b: function () { return this.y } }}
-        ]
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(vm._app).equal(app)
-    const el = doc.body
-    expect(el.type).eql('container')
-    expect(el.children).is.an.array
-    expect(el.children.length).eql(1)
-
-    const sub = el.children[0]
-    const aaa = sub.children[0]
-    expect(aaa.type).eql('aaa')
-    expect(aaa.attr).eql({ a: 10 })
-    const bbb = sub.children[1]
-    expect(bbb.type).eql('bbb')
-    expect(bbb.attr).eql({ b: 2 })
-  })
-
-  it('generate sub elements with props', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'container',
-        children: [{ type: 'bar', component: true, attr: { x: 10, y: 20 }}]
-      }
-    }
-    customComponentMap.bar = {
-      props: { x: Number },
-      data: () => {
-        return { x: 1, y: 2 }
-      },
-      template: {
-        type: 'container',
-        children: [
-          { type: 'aaa', attr: { a: function () { return this.x } }},
-          { type: 'bbb', attr: { b: function () { return this.y } }}
-        ]
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(vm._app).equal(app)
-
-    const el = doc.body
-    expect(el.type).eql('container')
-    expect(el.children).is.an.array
-    expect(el.children.length).eql(1)
-
-    const sub = el.children[0]
-    const aaa = sub.children[0]
-    expect(aaa.type).eql('aaa')
-    expect(aaa.attr).eql({ a: 10 })
-    const bbb = sub.children[1]
-    expect(bbb.type).eql('bbb')
-    expect(bbb.attr).eql({ b: 2 })
-  })
-
-  it('generate sub elements with data', () => {
-    customComponentMap.foo = {
-      data: () => {
-        return { a: 10, b: 20 }
-      },
-      template: {
-        type: 'container',
-        children: [{ type: 'bar', component: true, attr: {
-          x: function () { return this.a },
-          y: function () { return this.b }
-        }}]
-      }
-    }
-    customComponentMap.bar = {
-      props: { x: Number },
-      data: () => {
-        return { x: 1, y: 2 }
-      },
-      template: {
-        type: 'container',
-        children: [
-          { type: 'aaa', attr: { a: function () { return this.x } }},
-          { type: 'bbb', attr: { b: function () { return this.y } }}
-        ]
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(vm._app).equal(app)
-
-    const el = doc.body
-    expect(el.type).eql('container')
-    expect(el.children).is.an.array
-    expect(el.children.length).eql(1)
-
-    const sub = el.children[0]
-    const aaa = sub.children[0]
-    expect(aaa.type).eql('aaa')
-    expect(aaa.attr).eql({ a: 10 })
-    const bbb = sub.children[1]
-    expect(bbb.type).eql('bbb')
-    expect(bbb.attr).eql({ b: 2 })
-
-    vm.a = 100
-    vm.b = 200
-    differ.flush()
-
-    expect(el).equal(doc.body)
-    expect(sub).equal(el.children[0])
-    expect(aaa).equal(sub.children[0])
-    expect(aaa.attr).eql({ a: 100 })
-    expect(bbb).equal(sub.children[1])
-    expect(bbb.attr).eql({ b: 2 })
-  })
-
-  it('generate sub elements with shown data', () => {
-    customComponentMap.foo = {
-      data: () => {
-        return { a: 10, b: 20 }
-      },
-      template: {
-        type: 'container',
-        children: [{ type: 'bar', component: true, attr: {
-          x: function () { return this.a },
-          y: function () { return this.b }
-        }, shown: function () { return this.a < 15 } }]
-      }
-    }
-    customComponentMap.bar = {
-      props: { x: Number },
-      data: () => {
-        return { x: 1, y: 2 }
-      },
-      template: {
-        type: 'container',
-        children: [
-          { type: 'aaa', attr: { a: function () { return this.x } }},
-          { type: 'bbb', attr: { b: function () { return this.y } }}
-        ]
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(vm._app).equal(app)
-
-    const el = doc.body
-    expect(el.type).eql('container')
-    expect(el.children).is.an.array
-    expect(el.children.length).eql(3)
-
-    const sub = el.children[1]
-    const aaa = sub.children[0]
-    expect(aaa.type).eql('aaa')
-    expect(aaa.attr).eql({ a: 10 })
-    const bbb = sub.children[1]
-    expect(bbb.type).eql('bbb')
-    expect(bbb.attr).eql({ b: 2 })
-
-    vm.a = 20
-    differ.flush()
-
-    expect(el).equal(doc.body)
-    expect(el.children).is.an.array
-    expect(el.children.length).eql(2)
-  })
-
-  it('generate sub elements with repeat data', () => {
-    customComponentMap.foo = {
-      data: () => {
-        return { list: [{ uid: 1, a: 1 }, { uid: 2, a: 2 }, { uid: 3, a: 3 }] }
-      },
-      template: {
-        type: 'container',
-        children: [{ type: 'bar', component: true, attr: {
-          x: function () { return this.a },
-          y: function () { return this.b }
-        }, repeat: function () { return this.list } }]
-      }
-    }
-    customComponentMap.bar = {
-      props: { x: Number },
-      data: () => {
-        return { x: 1, y: 2 }
-      },
-      template: {
-        type: 'container',
-        children: [
-          { type: 'aaa', attr: { a: function () { return this.x } }},
-          { type: 'bbb', attr: { b: function () { return this.y } }}
-        ]
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(vm._app).equal(app)
-
-    const el = doc.body
-    expect(el.type).eql('container')
-    expect(el.children).is.an.array
-    expect(el.children.length).eql(5)
-
-    const sub1 = el.children[1]
-    const aaa1 = sub1.children[0]
-    expect(aaa1.type).eql('aaa')
-    expect(aaa1.attr).eql({ a: 1 })
-    const bbb1 = sub1.children[1]
-    expect(bbb1.type).eql('bbb')
-    expect(bbb1.attr).eql({ b: 2 })
-
-    const sub2 = el.children[2]
-    const aaa2 = sub2.children[0]
-    expect(aaa2.type).eql('aaa')
-    expect(aaa2.attr).eql({ a: 2 })
-    const bbb2 = sub2.children[1]
-    expect(bbb2.type).eql('bbb')
-    expect(bbb2.attr).eql({ b: 2 })
-
-    const sub3 = el.children[3]
-    const aaa3 = sub3.children[0]
-    expect(aaa3.type).eql('aaa')
-    expect(aaa3.attr).eql({ a: 3 })
-    const bbb3 = sub3.children[1]
-    expect(bbb3.type).eql('bbb')
-    expect(bbb3.attr).eql({ b: 2 })
-  })
-
-  it('generate sub elements with content', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'container',
-        children: [{ type: 'bar', component: true, children: [
-          { type: 'a' }, { type: 'b', attr: { bbb: function () { return this.x } }}
-        ] }]
-      },
-      data: () => {
-        return {
-          x: 1, y: 2
-        }
-      }
-    }
-    customComponentMap.bar = {
-      replace: true,
-      template: {
-        type: 'container',
-        children: [{ type: 'aaa' }, { type: 'content' }, { type: 'bbb' }]
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    const el = doc.body
-
-    expect(el.type).eql('container')
-    // [comment, aaa, comment, a, b, comment, bbb, comment]
-    expect(el.children.length).eql(8)
-    expect(el.children[0].type).eql('comment')
-    expect(el.children[2].type).eql('comment')
-    expect(el.children[5].type).eql('comment')
-    expect(el.children[7].type).eql('comment')
-
-    expect(el.pureChildren.length).eql(4)
-    expect(el.pureChildren[0].type).eql('aaa')
-    expect(el.pureChildren[1].type).eql('a')
-    expect(el.pureChildren[2].type).eql('b')
-    expect(el.pureChildren[2].attr).eql({ bbb: 1 })
-    expect(el.pureChildren[3].type).eql('bbb')
-
-    vm.x = 10
-    differ.flush()
-    expect(el.pureChildren[2].attr).eql({ bbb: 10 })
-  })
-
-  it('generate sub elements with dynamic types', (done) => {
-    customComponentMap.foo = {
-      data: {
-        x: 'bar',
-        y: 'hello'
-      },
-      template: {
-        type: 'div',
-        children: [{
-          type: function () { return this.x },
-          attr: { value: function () { return this.y } }
-        }]
-      }
-    }
-    customComponentMap.bar = {
-      template: {
-        type: 'text',
-        attr: { value: 'bar' }
-      }
-    }
-    customComponentMap.baz = {
-      data: function () {
-        return {
-          value: ''
-        }
-      },
-      template: {
-        type: 'text',
-        attr: { value: function () { return this.value + ' baz' } }
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(doc.body.pureChildren[0].type).eql('text')
-    expect(doc.body.pureChildren[0].attr).eql({ value: 'bar' })
-
-    vm.x = 'baz'
-    expect(doc.body.pureChildren[0].type).eql('text')
-    expect(doc.body.pureChildren[0].attr).eql({ value: 'hello baz' })
-
-    vm.y = 'bye'
-    setTimeout(() => {
-      expect(doc.body.pureChildren[0].type).eql('text')
-      expect(doc.body.pureChildren[0].attr).eql({ value: 'bye baz' })
-
-      vm.x = 'text'
-      expect(doc.body.pureChildren[0].type).eql('text')
-      expect(doc.body.pureChildren[0].attr).eql({ value: 'bye' })
-
-      done()
-    })
-  })
-
-  it('generate sub elements with repeat dynamic types', (done) => {
-    customComponentMap.foo = {
-      data: {
-        list: [
-          { uid: 1, type: 'bar' },
-          { uid: 2, type: 'baz' },
-          { uid: 3, type: 'bar' },
-          { uid: 4, type: 'baz' }
-        ]
-      },
-      template: {
-        type: 'div',
-        children: [{
-          type: function () { return this.v.type },
-          repeat: {
-            expression: function () { return this.list },
-            trackBy: 'uid',
-            value: 'v'
-          }
-        }]
-      }
-    }
-    customComponentMap.bar = {
-      template: {
-        type: 'text',
-        attr: { value: 'bar' }
-      }
-    }
-    customComponentMap.baz = {
-      template: {
-        type: 'text',
-        attr: { value: 'baz' }
-      }
-    }
-
-    const app = { doc, customComponentMap, differ }
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(doc.body.pureChildren.length).eql(4)
-    expect(doc.body.pureChildren.map(el => el.attr.value)).eql(['bar', 'baz', 'bar', 'baz'])
-
-    vm.list.splice(2, 0, { uid: 5, type: 'baz' })
-    setTimeout(() => {
-      expect(doc.body.pureChildren.length).eql(5)
-      expect(doc.body.pureChildren.map(el => el.attr.value)).eql(['bar', 'baz', 'baz', 'bar', 'baz'])
-
-      done()
-    })
-  })
-})
-
-describe('generate dom actions', () => {
-  let doc, app, spy, customComponentMap, differ
-
-  beforeEach(() => {
-    spy = sinon.spy()
-    doc = new Document('foo', '', function (actions) {
-      actions.forEach((action) => {
-        spy.apply(null, ['bar', action.method].concat(action.args))
-      })
-    })
-    differ = new Differ('foo')
-    customComponentMap = {}
-    app = { doc, customComponentMap, differ }
-  })
-
-  afterEach(() => {
-    customComponentMap = {}
-    doc.destroy()
-    app = doc = spy = null
-  })
-
-  it('received create body and add element actions', () => {
-    const handler = sinon.spy()
-
-    customComponentMap.foo = {
-      template: {
-        type: 'container',
-        attr: {
-          a: 1,
-          b: 2
-        },
-        style: {
-          c: 3,
-          d: 4
-        },
-        classList: ['classA'],
-        events: { click: 'handleClick' }
-      },
-      style: {
-        classA: { d: 5, e: 6 }
-      },
-      methods: {
-        handleClick: handler
-      }
-    }
-
-    new Vm('foo', customComponentMap.foo, { _app: app })
-    const el = {
-      ref: '_root',
-      type: 'container',
-      attr: { a: 1, b: 2 }, style: { c: 3, d: 4, e: 6 },
-      event: ['click']
-    }
-
-    expect(spy.args.length).eql(1)
-    expect(spy.args[0]).eql(['bar', 'createBody', el])
-    expect(doc.body.event.click).is.a.function
-    expect(handler.args.length).eql(0)
-    doc.body.fireEvent('click')
-    expect(handler.args.length).eql(0)
-  })
-
-  it('received actions for a template with if & repeat', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'container',
-        children: [
-          { type: 'prev' },
-          {
-            shown: function () { return this.x % 2 === 0 },
-            repeat: function () { return this.list },
-            trackBy: 'uid',
-            type: 'image', attr: { src: function () { return this.x } }
-          },
-          { type: 'next' }
-        ]
-      },
-      data: {
-        x: '<some image url>',
-        list: [
-          { uid: 1, x: 1 }, { uid: 2, x: 2 }, { uid: 3 }
-        ]
-      }
-    }
-
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    const pureChildren = doc.body.pureChildren
-    const el = { ref: '_root', type: 'container', attr: {}, style: {}}
-    const prev = {
-      ref: pureChildren[0].ref,
-      type: 'prev', attr: {}, style: {}
-    }
-    const img = {
-      ref: pureChildren[1].ref,
-      type: 'image', attr: { src: 2 }, style: {}
-    }
-    const next = {
-      ref: pureChildren[2].ref,
-      type: 'next', attr: {}, style: {}
-    }
-
-    expect(spy.args.length).eql(4)
-    expect(spy.args[0]).eql(['bar', 'createBody', el])
-    expect(spy.args[1]).eql(['bar', 'addElement', '_root', prev, -1])
-    expect(spy.args[2]).eql(['bar', 'addElement', '_root', img, 1])
-    expect(spy.args[3]).eql(['bar', 'addElement', '_root', next, -1])
-
-    vm.list[1].x = 3
-    differ.flush()
-
-    // [1, 3, undefined]
-    expect(spy.args.length).eql(5)
-    expect(spy.args[4]).eql(['bar', 'removeElement', img.ref])
-
-    vm.list[1].x = 12
-    differ.flush()
-
-    // [1, !12, undefined]
-    expect(spy.args.length).eql(6)
-    img.ref = pureChildren[1].ref
-    img.attr.src = 12
-    expect(spy.args[5]).eql(['bar', 'addElement', '_root', img, 1])
-
-    vm.x = 'other string value'
-    differ.flush()
-
-    expect(spy.args.length).eql(6)
-
-    vm.list.push({ uid: 4, x: 4 })
-    vm.list.push({ uid: 5 }, { uid: 6, x: 6 })
-    differ.flush()
-
-    // [1, !12, undefined, !4, undefined, !6]
-    const img2 = {
-      ref: pureChildren[2].ref,
-      type: 'image', attr: { src: 4 }, style: {}
-    }
-    const img3 = {
-      ref: pureChildren[3].ref,
-      type: 'image', attr: { src: 6 }, style: {}
-    }
-    expect(spy.args.length).eql(8)
-    expect(spy.args[6]).eql(['bar', 'addElement', '_root', img2, 2])
-    expect(spy.args[7]).eql(['bar', 'addElement', '_root', img3, 3])
-
-    const temp1 = vm.list[1] // 12
-    const temp2 = vm.list[5] // 6
-    // vm.list.splice(0, 6, temp2, {uid: 7, x: 7}, temp1)
-    vm.list = []
-    vm.list.push(temp2, { uid: 7, x: 7 }, temp1)
-    differ.flush()
-
-    // [!6, 7, !12]
-    expect(spy.args.length).eql(10)
-    expect(spy.args[8]).eql(['bar', 'removeElement', img2.ref])
-    expect(spy.args[9]).eql(['bar', 'moveElement', img3.ref, '_root', 1])
-  })
-
-  it('received actions for element updates', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'container', attr: { a: 1, b: 2 }, style: { c: 3, d: 4 },
-        children: [
-          { type: 'image', attr: { src: function () { return this.x } }},
-          { type: 'text', attr: { value: function () { return this.y } }}
-        ]
-      },
-      data: {
-        x: '<some image url>', y: '<some text content>'
-      }
-    }
-
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-    const pureChildren = doc.body.pureChildren
-    const length = spy.args.length
-
-    vm.x = '<some image url>'
-    differ.flush()
-    expect(spy.args.length - length).eql(0)
-
-    vm.x = 'other string value'
-    differ.flush()
-    const change = [
-      'bar', 'updateAttrs',
-      pureChildren[0].ref,
-      { src: 'other string value' }
-    ]
-    expect(spy.args.length - length).eql(1)
-    expect(spy.args[length]).eql(change)
-  })
-
-  it('received no action when no virtual dom different', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'container', children: [
-          {
-            type: 'text',
-            shown: function () { return this.name.length > 3 },
-            attr: {
-              value: function () { return this.name.toUpperCase() }
-            }
-          }
-        ]
-      },
-      data: {
-        name: 'Mike'
-      }
-    }
-
-    const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
-    expect(doc.body.pureChildren.length).eql(1)
-    const text = doc.body.pureChildren[0]
-    expect(text.attr.value).eql('MIKE')
-
-    const initCalls = spy.args.length
-
-    vm.name = 'MiKe'
-    differ.flush()
-
-    expect(spy.args.length).eql(initCalls)
-
-    text.setAttr('value', 'MIKE')
-    differ.flush()
-
-    expect(spy.args.length).eql(initCalls)
-
-    text.setAttr('value', 'STEVE')
-    differ.flush()
-
-    expect(spy.args.length).eql(initCalls + 1)
-    expect(spy.args[initCalls]).eql([
-      'bar', 'updateAttrs', text.ref, { value: 'STEVE' }])
-
-    vm.name = 'Steve'
-    differ.flush()
-
-    expect(spy.args.length).eql(initCalls + 1)
-  })
-
-  it('received actions for components', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'container',
-        children: [{ type: 'bar', component: true }]
-      }
-    }
-    customComponentMap.bar = {
-      template: {
-        type: 'container',
-        children: [{ type: 'aaa' }, { type: 'bbb' }]
-      }
-    }
-
-    new Vm('foo', customComponentMap.foo, { _app: app })
-    const pureChildren = doc.body.pureChildren
-    const first = pureChildren[0]
-    const second = first.pureChildren[0]
-    const third = first.pureChildren[1]
-    expect(spy.args.length).eql(4)
-    let el = { ref: '_root', type: 'container', attr: {}, style: {}}
-    expect(spy.args[0]).eql(['bar', 'createBody', el])
-    el = { ref: first.ref, type: 'container', attr: {}, style: {}}
-    expect(spy.args[1]).eql(['bar', 'addElement', '_root', el, -1])
-    el = { ref: second.ref, type: 'aaa', attr: {}, style: {}}
-    expect(spy.args[2]).eql(['bar', 'addElement', first.ref, el, -1])
-    el = { ref: third.ref, type: 'bbb', attr: {}, style: {}}
-    expect(spy.args[3]).eql(['bar', 'addElement', first.ref, el, -1])
-  })
-
-  it('received actions for complicated components', () => {
-    customComponentMap.foo = {
-      data: () => {
-        return { list: [{ uid: 1, a: 1 }, { uid: 2, a: 2 }, { uid: 3, a: 3 }] }
-      },
-      template: {
-        type: 'container',
-        children: [{ type: 'bar', component: true, attr: {
-          x: function () { return this.a },
-          y: function () { return this.b }
-        }, repeat: function () { return this.list } }]
-      }
-    }
-    customComponentMap.bar = {
-      props: { x: Number },
-      data: () => {
-        return { x: 1, y: 2 }
-      },
-      template: {
-        type: 'container',
-        children: [
-          { type: 'aaa', attr: { a: function () { return this.x } }},
-          { type: 'bbb', attr: { b: function () { return this.y } }}
-        ]
-      }
-    }
-
-    new Vm('foo', customComponentMap.foo, { _app: app })
-    const pureChildren = doc.body.pureChildren
-    const first = pureChildren[0]
-    const second = pureChildren[1]
-    const third = pureChildren[2]
-
-    /* eslint-disable indent */
-    // expect(spy.args[0]).eql([ 'bar', 'createBody', 'container' ])
-    expect(spy.args[0]).eql(['bar', 'createBody', { ref: '_root', type: 'container', attr: {}, style: {}}])
-      expect(spy.args[1]).eql(['bar', 'addElement', '_root', { ref: first.ref, type: 'container', attr: {}, style: {}}, 0])
-        expect(spy.args[2]).eql(['bar', 'addElement', first.ref, { ref: first.pureChildren[0].ref, type: 'aaa', attr: { a: 1 }, style: {}}, -1])
-        expect(spy.args[3]).eql(['bar', 'addElement', first.ref, { ref: first.pureChildren[1].ref, type: 'bbb', attr: { b: 2 }, style: {}}, -1])
-      expect(spy.args[4]).eql(['bar', 'addElement', '_root', { ref: second.ref, type: 'container', attr: {}, style: {}}, 1])
-        expect(spy.args[5]).eql(['bar', 'addElement', second.ref, { ref: second.pureChildren[0].ref, type: 'aaa', attr: { a: 2 }, style: {}}, -1])
-        expect(spy.args[6]).eql(['bar', 'addElement', second.ref, { ref: second.pureChildren[1].ref, type: 'bbb', attr: { b: 2 }, style: {}}, -1])
-      expect(spy.args[7]).eql(['bar', 'addElement', '_root', { ref: third.ref, type: 'container', attr: {}, style: {}}, 2])
-        expect(spy.args[8]).eql(['bar', 'addElement', third.ref, { ref: third.pureChildren[0].ref, type: 'aaa', attr: { a: 3 }, style: {}}, -1])
-        expect(spy.args[9]).eql(['bar', 'addElement', third.ref, { ref: third.pureChildren[1].ref, type: 'bbb', attr: { b: 2 }, style: {}}, -1])
-    /* eslint-enable indent */
-  })
-
-  it('received actions for add a tree element', () => {
-    customComponentMap.foo = {
-      template: {
-        type: 'r',
-        children: [
-          { type: 'a' }, { type: 'b', children: [
-            { type: 'd' }, { type: 'e', append: 'tree', children: [
-              { type: 'g' }, { type: 'h' }, { type: 'i' }
-            ] }, { type: 'f' }
-          ] }, { type: 'c' }
-        ]
-      }
-    }
-
-    new Vm('foo', customComponentMap.foo, { _app: app })
-    const pureChildren = doc.body.pureChildren
-
-    expect(spy.args.length).eql(7)
-    // body, r, r.a, r.b, r.b.d, r.b.e(tree), r.b.f, r.c
-
-    expect(spy.args[0][2].ref).eql('_root')
-    expect(spy.args[0][2].type).eql('r')
-
-    expect(spy.args[1][3].ref).eql(pureChildren[0].ref)
-    expect(spy.args[1][3].type).eql('a')
-    expect(spy.args[1][2]).eql('_root')
-    expect(spy.args[1][4]).eql(-1)
-
-    expect(spy.args[2][3].ref).eql(pureChildren[1].ref)
-    expect(spy.args[2][3].type).eql('b')
-    expect(spy.args[2][2]).eql('_root')
-    expect(spy.args[2][4]).eql(-1)
-
-    expect(spy.args[3][3].ref).eql(pureChildren[1].pureChildren[0].ref)
-    expect(spy.args[3][3].type).eql('d')
-    expect(spy.args[3][2]).eql(pureChildren[1].ref)
-    expect(spy.args[3][4]).eql(-1)
-
-    const tree = pureChildren[1].pureChildren[1]
-    expect(spy.args[4][3].ref).eql(tree.ref)
-    expect(spy.args[4][3].type).eql('e')
-    expect(spy.args[4][2]).eql(pureChildren[1].ref)
-    expect(spy.args[4][4]).eql(-1)
-    expect(spy.args[4][3].children).eql([
-      { ref: tree.pureChildren[0].ref, type: 'g', attr: {}, style: {}},
-      { ref: tree.pureChildren[1].ref, type: 'h', attr: {}, style: {}},
-      { ref: tree.pureChildren[2].ref, type: 'i', attr: {}, style: {}}])
-
-    expect(spy.args[5][3].ref).eql(pureChildren[1].pureChildren[2].ref)
-    expect(spy.args[5][3].type).eql('f')
-    expect(spy.args[5][2]).eql(pureChildren[1].ref)
-    expect(spy.args[5][4]).eql(-1)
-
-    expect(spy.args[6][3].ref).eql(pureChildren[2].ref)
-    expect(spy.args[6][3].type).eql('c')
-    expect(spy.args[6][2]).eql('_root')
-    expect(spy.args[6][4]).eql(-1)
-  })
-})
diff --git a/test/js-framework/unit/runtime/legacy-framework.js b/test/js-framework/unit/runtime/legacy-framework.js
deleted file mode 100644
index c9e37d0..0000000
--- a/test/js-framework/unit/runtime/legacy-framework.js
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-import chai from 'chai'
-import sinon from 'sinon'
-import sinonChai from 'sinon-chai'
-const {
-  expect
-} = chai
-chai.use(sinonChai)
-
-import runtime from '../../../../runtime/api'
-import frameworks from '../../../../runtime/frameworks'
-import defaultConfig from '../../../../runtime/frameworks/legacy/config'
-import { init as resetTaskHandler } from '../../../../runtime/bridge/TaskCenter'
-
-const { init, config } = runtime
-config.frameworks = frameworks
-runtime.setNativeConsole()
-
-import Vm from '../../../../runtime/frameworks/legacy/vm'
-import { clearModules, getModule } from '../../../../runtime/frameworks/legacy/app/register'
-
-const framework = init(config)
-
-function clearRefs (json) {
-  delete json.ref
-  if (json.children) {
-    json.children.forEach(clearRefs)
-  }
-}
-
-describe('framework entry', () => {
-  const oriCallNative = global.callNative
-  const oriCallAddElement = global.callAddElement
-  const oriDocumentHandler = config.Document.handler
-  const callNativeSpy = sinon.spy()
-  const callAddElementSpy = sinon.spy()
-  const documentHandlerSpy = sinon.spy()
-  const instanceId = Date.now() + ''
-
-  before(() => {
-    global.callNative = (id, tasks, callbackId) => {
-      callNativeSpy(id, tasks, callbackId)
-      /* istanbul ignore if */
-      if (callbackId !== '-1') {
-        framework.callJS(id, [{
-          method: 'callback',
-          args: [callbackId, null, true]
-        }])
-      }
-    }
-    global.callAddElement = (name, id, ref, json, index, callbackId) => {
-      callAddElementSpy(name, ref, json, index, callbackId)
-      /* istanbul ignore if */
-      if (callbackId !== '-1') {
-        framework.callJS(id, [{
-          method: 'callback',
-          args: [callbackId, null, true]
-        }])
-      }
-    }
-    config.Document.handler = oriDocumentHandler
-    resetTaskHandler()
-  })
-
-  afterEach(() => {
-    callNativeSpy.reset()
-    callAddElementSpy.reset()
-    documentHandlerSpy.reset()
-  })
-
-  after(() => {
-    config.Document.handler = oriDocumentHandler
-    global.callNative = oriCallNative
-    global.callAddElement = oriCallAddElement
-  })
-
-  describe('createInstance', () => {
-    it('a simple bundle', () => {
-      const code = `
-        define('@weex-component/main',
-          function(require, exports, module) {
-            module.exports = {
-              data: function() {
-                return {
-                  text: 'Hello World',
-                  showText: true
-                };
-              }
-            }
-
-            ;module.exports.style = {}
-
-            ;module.exports.template = {
-              'type': 'container',
-              'children': [{
-                'type': 'text',
-                'shown': function() {
-                  return this.showText
-                },
-                'attr': {
-                  'value': function() {
-                    return this.text
-                  }
-                }
-              }]
-            }
-          }
-        )
-
-        bootstrap('@weex-component/main')
-      `
-      framework.createInstance(instanceId, code)
-      expect(callNativeSpy.callCount).to.be.equal(2)
-      expect(callAddElementSpy.callCount).to.be.equal(1)
-
-      expect(callNativeSpy.firstCall.args[0]).to.be.equal(instanceId)
-      expect(callNativeSpy.firstCall.args[1]).to.deep.equal([{
-        module: 'dom',
-        method: 'createBody',
-        args: [{
-          ref: '_root',
-          type: 'container',
-          attr: {},
-          style: {}
-        }]
-      }])
-      // expect(callNativeSpy.firstCall.args[2]).to.not.equal('-1')
-
-      expect(callAddElementSpy.firstCall.args[0]).to.be.equal(instanceId)
-      delete callAddElementSpy.firstCall.args[1].ref
-      expect(callAddElementSpy.firstCall.args[1]).to.deep.equal({
-        type: 'text',
-        attr: { value: 'Hello World' },
-        style: {}
-      })
-
-      // expect(callNativeSpy.secondCall.args[2]).to.not.equal('-1')
-
-      expect(callNativeSpy.secondCall.args[0]).to.be.equal(instanceId)
-      expect(callNativeSpy.secondCall.args[1]).to.deep.equal([{
-        module: 'dom',
-        method: 'createFinish',
-        args: []
-      }])
-      // expect(callNativeSpy.thirdCall.args[2]).to.not.equal('-1')
-    })
-
-    it('with a exist instanceId', () => {
-      const code = ''
-      const result = framework.createInstance(instanceId, code)
-      expect(result).to.be.an.instanceof(Error)
-    })
-  })
-
-  describe('getRoot', () => {
-    it('with a exist instanceId', () => {
-      const json = framework.getRoot(instanceId)
-      expect(json.ref).eql('_root')
-      clearRefs(json)
-      const expectJSON = {
-        type: 'container',
-        attr: {},
-        style: {},
-        children: [{
-          type: 'text',
-          attr: {
-            value: 'Hello World'
-          },
-          style: {}
-        }]
-      }
-      expect(json).to.be.deep.equal(expectJSON)
-    })
-  })
-
-  describe('callJS', () => {
-    it('fireEvent with no params', () => {
-      framework.callJS()
-    })
-
-    it('fireEvent with a exist instanceId', () => {
-      framework.callJS(instanceId, [{
-        method: 'fireEvent',
-        args: []
-      }])
-    })
-
-    it('callback with a exist instanceId', () => {
-      framework.callJS(instanceId, [{
-        method: 'callback',
-        args: []
-      }])
-    })
-
-    it('with a non-exist instanceId', () => {
-      const result = framework.callJS('123', [{
-        method: 'fireEvent',
-        args: []
-      }])
-      expect(result).to.be.an.instanceof(Error)
-    })
-
-    it('with a non-array tasks', () => {
-      const result = framework.callJS(instanceId, {
-        method: 'fireEvent',
-        args: []
-      })
-      expect(result).to.be.an.instanceof(Error)
-    })
-  })
-
-  describe('refreshInstance', () => {
-    it('modify showText to false', () => {
-      const json = framework.getRoot(instanceId)
-      const textRef = json.children[0].ref
-      framework.refreshInstance(instanceId, { showText: false })
-      expect(callNativeSpy.callCount).to.be.equal(2)
-      expect(callNativeSpy.firstCall.args[0]).to.be.equal(instanceId)
-      expect(callNativeSpy.firstCall.args[1]).to.deep.equal([{
-        module: 'dom',
-        method: 'removeElement',
-        args: [textRef]
-      }])
-      // expect(callNativeSpy.firstCall.args[2]).to.be.equal('-1')
-
-      expect(callNativeSpy.secondCall.args[0]).to.be.equal(instanceId)
-      expect(callNativeSpy.secondCall.args[1]).to.deep.equal([{
-        module: 'dom',
-        method: 'refreshFinish',
-        args: []
-      }])
-      // expect(callNativeSpy.secondCall.args[2]).to.be.equal('-1')
-    })
-
-    it('with a non-exist instanceId', () => {
-      const result = framework.refreshInstance('123', {})
-      expect(result).to.be.an.instanceof(Error)
-    })
-  })
-
-  describe('destroyInstance', () => {
-    it('with no params', () => {
-      framework.destroyInstance()
-    })
-
-    it('with a exist instanceId', () => {
-      const result = framework.destroyInstance(instanceId)
-      expect(result[instanceId]).to.be.undefined
-    })
-
-    it('with a non-exist instanceId', () => {
-      const result = framework.destroyInstance('123')
-      expect(result).to.be.an.instanceof(Error)
-    })
-  })
-
-  describe('registerComponents', () => {
-    it('with old format', () => {
-      framework.registerComponents(['a', 'b', 'c'])
-      expect(defaultConfig.nativeComponentMap).to.contain.keys('a', 'b', 'c')
-    })
-
-    it('with new format', () => {
-      framework.registerComponents([{
-        type: 'd',
-        append: 'tree'
-      }])
-      expect(defaultConfig.nativeComponentMap).to.contain.keys('d')
-      expect(defaultConfig.nativeComponentMap['d']).to.be.deep.equal({
-        type: 'd',
-        append: 'tree'
-      })
-    })
-
-    it('with non-array', () => {
-      framework.registerComponents({
-        type: 'e'
-      })
-      expect(defaultConfig.nativeComponentMap).not.contain.keys('e')
-    })
-
-    it('with methods', () => {
-      const components = [{
-        type: 'x',
-        methods: ['foo', 'bar']
-      }, {
-        type: 'y',
-        methods: []
-      }, {
-        type: 'z',
-        methods: null
-      }]
-      framework.registerComponents(components)
-      expect(defaultConfig.nativeComponentMap).to.contain.keys('x', 'y', 'z')
-    })
-  })
-
-  describe('register modules', () => {
-    it('with object of modules', () => {
-      clearModules()
-      const modules = {
-        a: [{
-          name: 'b',
-          args: ['string']
-        }]
-      }
-
-      framework.registerModules(modules)
-      expect(getModule('b')).an.object
-      clearModules()
-    })
-  })
-
-  describe('register methods', () => {
-    it('with object of methods', () => {
-      const methods = {
-        a: sinon.spy()
-      }
-
-      framework.registerMethods(methods)
-      expect(Vm.prototype.a).a.function
-      delete Vm.prototype.a
-    })
-  })
-})
-
-describe('config', () => {
-  it('config is an object', () => {
-    init({})
-  })
-})