http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/e10881f6/pre-build/native-bundle-main.js
----------------------------------------------------------------------
diff --git a/pre-build/native-bundle-main.js b/pre-build/native-bundle-main.js
index 9e1608c..010c772 100644
--- a/pre-build/native-bundle-main.js
+++ b/pre-build/native-bundle-main.js
@@ -1,5 +1,5 @@
-(this.nativeLog || function(s) {console.log(s)})('START JS FRAMEWORK 0.22.0, 
Build 2017-09-20 19:51.');
-(this.getJSFMVersion = function(){return "0.22.0"});var global = this, process 
= { env: {} };var setTimeout = global.setTimeout;
+(this.nativeLog || function(s) {console.log(s)})('START JS FRAMEWORK 
0.22.0-beta.2, Build 2017-09-19 14:51.');
+(this.getJSFMVersion = function(){return "0.22.0-beta.2"});var global = this, 
process = { env: {} };var setTimeout = global.setTimeout;
 
 (function (global, factory) {
        typeof exports === 'object' && typeof module !== 'undefined' ? 
factory() :
@@ -310,9 +310,12 @@ var capitalize = cached(function (str) {
 /**
  * Hyphenate a camelCase string.
  */
-var hyphenateRE = /\B([A-Z])/g;
+var hyphenateRE = /([^-])([A-Z])/g;
 var hyphenate = cached(function (str) {
-  return str.replace(hyphenateRE, '-$1').toLowerCase()
+  return str
+    .replace(hyphenateRE, '$1-$2')
+    .replace(hyphenateRE, '$1-$2')
+    .toLowerCase()
 });
 
 /**
@@ -727,7 +730,7 @@ var isAndroid = UA && UA.indexOf('android') > 0;
 var isIOS = UA && /iphone|ipad|ipod|ios/.test(UA);
 var isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge;
 
-// Firefox has a "watch" function on Object.prototype...
+// Firefix has a "watch" function on Object.prototype...
 var nativeWatch = ({}).watch;
 
 var supportsPassive = false;
@@ -1296,7 +1299,7 @@ function mergeDataOrFn (
         : childVal;
       var defaultData = typeof parentVal === 'function'
         ? parentVal.call(vm)
-        : parentVal;
+        : undefined;
       if (instanceData) {
         return mergeData(instanceData, defaultData)
       } else {
@@ -1699,12 +1702,7 @@ function assertType (value, type) {
   var valid;
   var expectedType = getType(type);
   if (simpleCheckRE.test(expectedType)) {
-    var t = typeof value;
-    valid = t === expectedType.toLowerCase();
-    // for primitive wrapper objects
-    if (!valid && t === 'object') {
-      valid = value instanceof type;
-    }
+    valid = typeof value === expectedType.toLowerCase();
   } else if (expectedType === 'Object') {
     valid = isPlainObject(value);
   } else if (expectedType === 'Array') {
@@ -1902,7 +1900,7 @@ function createTextVNode (val) {
 // used for static nodes and slot nodes because they may be reused across
 // multiple renders, cloning them avoids errors when DOM manipulations rely
 // on their elm reference.
-function cloneVNode (vnode, deep) {
+function cloneVNode (vnode) {
   var cloned = new VNode(
     vnode.tag,
     vnode.data,
@@ -1918,17 +1916,14 @@ function cloneVNode (vnode, deep) {
   cloned.key = vnode.key;
   cloned.isComment = vnode.isComment;
   cloned.isCloned = true;
-  if (deep && vnode.children) {
-    cloned.children = cloneVNodes(vnode.children);
-  }
   return cloned
 }
 
-function cloneVNodes (vnodes, deep) {
+function cloneVNodes (vnodes) {
   var len = vnodes.length;
   var res = new Array(len);
   for (var i = 0; i < len; i++) {
-    res[i] = cloneVNode(vnodes[i], deep);
+    res[i] = cloneVNode(vnodes[i]);
   }
   return res
 }
@@ -1976,15 +1971,11 @@ function updateListeners (
   remove$$1,
   vm
 ) {
-  var name, def$$1, cur, old, event;
+  var name, cur, old, event;
   for (name in on) {
-    def$$1 = cur = on[name];
+    cur = on[name];
     old = oldOn[name];
     event = normalizeEvent(name);
-    if (isPlainObject(def$$1)) {
-      cur = def$$1.handler;
-      event.params = def$$1.params;
-    }
     if (isUndef(cur)) {
       "development" !== 'production' && warn(
         "Invalid handler for event \"" + (event.name) + "\": got " + 
String(cur),
@@ -1994,7 +1985,7 @@ function updateListeners (
       if (isUndef(cur.fns)) {
         cur = on[name] = createFnInvoker(cur);
       }
-      add(event.name, cur, event.once, event.capture, event.passive, 
event.params);
+      add(event.name, cur, event.once, event.capture, event.passive);
     } else if (cur !== old) {
       old.fns = cur;
       on[name] = old;
@@ -2312,17 +2303,11 @@ function resolveAsyncComponent (
 
 /*  */
 
-function isAsyncPlaceholder (node) {
-  return node.isComment && node.asyncFactory
-}
-
-/*  */
-
 function getFirstComponentChild (children) {
   if (Array.isArray(children)) {
     for (var i = 0; i < children.length; i++) {
       var c = children[i];
-      if (isDef(c) && (isDef(c.componentOptions) || isAsyncPlaceholder(c))) {
+      if (isDef(c) && isDef(c.componentOptions)) {
         return c
       }
     }
@@ -2741,8 +2726,8 @@ function updateChildComponent (
   // update $attrs and $listensers hash
   // these are also reactive so they may trigger child update if the child
   // used them during render
-  vm.$attrs = (parentVnode.data && parentVnode.data.attrs) || emptyObject;
-  vm.$listeners = listeners || emptyObject;
+  vm.$attrs = parentVnode.data && parentVnode.data.attrs;
+  vm.$listeners = listeners;
 
   // update props
   if (propsData && vm.$options.props) {
@@ -3325,7 +3310,7 @@ function initData (vm) {
     {
       if (methods && hasOwn(methods, key)) {
         warn(
-          ("Method \"" + key + "\" has already been defined as a data 
property."),
+          ("method \"" + key + "\" has already been defined as a data 
property."),
           vm
         );
       }
@@ -3358,8 +3343,6 @@ var computedWatcherOptions = { lazy: true };
 function initComputed (vm, computed) {
   "development" !== 'production' && checkOptionType(vm, 'computed');
   var watchers = vm._computedWatchers = Object.create(null);
-  // computed properties are just getters during SSR
-  var isSSR = isServerRendering();
 
   for (var key in computed) {
     var userDef = computed[key];
@@ -3370,16 +3353,8 @@ function initComputed (vm, computed) {
         vm
       );
     }
-
-    if (!isSSR) {
-      // create internal watcher for the computed property.
-      watchers[key] = new Watcher(
-        vm,
-        getter || noop,
-        noop,
-        computedWatcherOptions
-      );
-    }
+    // create internal watcher for the computed property.
+    watchers[key] = new Watcher(vm, getter || noop, noop, 
computedWatcherOptions);
 
     // component-defined computed properties are already defined on the
     // component prototype. We only need to define computed properties defined
@@ -3396,20 +3371,13 @@ function initComputed (vm, computed) {
   }
 }
 
-function defineComputed (
-  target,
-  key,
-  userDef
-) {
-  var shouldCache = !isServerRendering();
+function defineComputed (target, key, userDef) {
   if (typeof userDef === 'function') {
-    sharedPropertyDefinition.get = shouldCache
-      ? createComputedGetter(key)
-      : userDef;
+    sharedPropertyDefinition.get = createComputedGetter(key);
     sharedPropertyDefinition.set = noop;
   } else {
     sharedPropertyDefinition.get = userDef.get
-      ? shouldCache && userDef.cache !== false
+      ? userDef.cache !== false
         ? createComputedGetter(key)
         : userDef.get
       : noop;
@@ -3448,28 +3416,22 @@ function initMethods (vm, methods) {
   "development" !== 'production' && checkOptionType(vm, 'methods');
   var props = vm.$options.props;
   for (var key in methods) {
+    vm[key] = methods[key] == null ? noop : bind(methods[key], vm);
     {
       if (methods[key] == null) {
         warn(
-          "Method \"" + key + "\" has an undefined value in the component 
definition. " +
+          "method \"" + key + "\" has an undefined value in the component 
definition. " +
           "Did you reference the function correctly?",
           vm
         );
       }
       if (props && hasOwn(props, key)) {
         warn(
-          ("Method \"" + key + "\" has already been defined as a prop."),
+          ("method \"" + key + "\" has already been defined as a prop."),
           vm
         );
       }
-      if ((key in vm) && isReserved(key)) {
-        warn(
-          "Method \"" + key + "\" conflicts with an existing Vue instance 
method. " +
-          "Avoid defining component methods that start with _ or $."
-        );
-      }
     }
-    vm[key] = methods[key] == null ? noop : bind(methods[key], vm);
   }
 }
 
@@ -3622,7 +3584,7 @@ function createFunctionalComponent (
   var propOptions = Ctor.options.props;
   if (isDef(propOptions)) {
     for (var key in propOptions) {
-      props[key] = validateProp(key, propOptions, propsData || emptyObject);
+      props[key] = validateProp(key, propOptions, propsData || {});
     }
   } else {
     if (isDef(data.attrs)) { mergeProps(props, data.attrs); }
@@ -3637,7 +3599,7 @@ function createFunctionalComponent (
     props: props,
     children: children,
     parent: context,
-    listeners: data.on || emptyObject,
+    listeners: data.on || {},
     injections: resolveInject(Ctor.options.inject, context),
     slots: function () { return resolveSlots(children, context); }
   });
@@ -3961,7 +3923,7 @@ function _createElement (
   var vnode, ns;
   if (typeof tag === 'string') {
     var Ctor;
-    ns = (context.$vnode && context.$vnode.ns) || config.getTagNamespace(tag);
+    ns = config.getTagNamespace(tag);
     if (config.isReservedTag(tag)) {
       // platform built-in elements
       vnode = new VNode(
@@ -4257,13 +4219,12 @@ function initRender (vm) {
   // $attrs & $listeners are exposed for easier HOC creation.
   // they need to be reactive so that HOCs using them are always updated
   var parentData = parentVnode && parentVnode.data;
-
   /* istanbul ignore else */
   {
-    defineReactive$$1(vm, '$attrs', parentData && parentData.attrs || 
emptyObject, function () {
+    defineReactive$$1(vm, '$attrs', parentData && parentData.attrs, function 
() {
       !isUpdatingChildComponent && warn("$attrs is readonly.", vm);
     }, true);
-    defineReactive$$1(vm, '$listeners', vm.$options._parentListeners || 
emptyObject, function () {
+    defineReactive$$1(vm, '$listeners', vm.$options._parentListeners, function 
() {
       !isUpdatingChildComponent && warn("$listeners is readonly.", vm);
     }, true);
   }
@@ -4282,13 +4243,9 @@ function renderMixin (Vue) {
     var _parentVnode = ref._parentVnode;
 
     if (vm._isMounted) {
-      // if the parent didn't update, the slot nodes will be the ones from
-      // last render. They need to be cloned to ensure "freshness" for this 
render.
+      // clone slot nodes on re-renders
       for (var key in vm.$slots) {
-        var slot = vm.$slots[key];
-        if (slot._rendered) {
-          vm.$slots[key] = cloneVNodes(slot, true /* deep */);
-        }
+        vm.$slots[key] = cloneVNodes(vm.$slots[key]);
       }
     }
 
@@ -4972,43 +4929,6 @@ function registerRef (vnode, isRemoval) {
   }
 }
 
-/*  */
-
-
-
-var isHTMLTag = makeMap(
-  'html,body,base,head,link,meta,style,title,' +
-  'address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,' +
-  'div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,' +
-  'a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,' +
-  
's,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,' +
-  'embed,object,param,source,canvas,script,noscript,del,ins,' +
-  'caption,col,colgroup,table,thead,tbody,td,th,tr,' +
-  'button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,' +
-  'output,progress,select,textarea,' +
-  'details,dialog,menu,menuitem,summary,' +
-  'content,element,shadow,template,blockquote,iframe,tfoot'
-);
-
-// this map is intentionally selective, only covering SVG elements that may
-// contain child elements.
-var isSVG = makeMap(
-  'svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font-face,' +
-  'foreignObject,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,' +
-  'polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view',
-  true
-);
-
-
-
-
-
-
-
-
-
-var isTextInputType = makeMap('text,number,password,search,email,tel,url');
-
 /**
  * Virtual DOM patching algorithm based on Snabbdom by
  * Simon Friis Vindum (@paldepind)
@@ -5017,6 +4937,8 @@ var isTextInputType = 
makeMap('text,number,password,search,email,tel,url');
  *
  * modified by Evan You (@yyx990803)
  *
+
+/*
  * Not type-checking this because this file is perf-critical and the cost
  * of making flow understand it is not worth it.
  */
@@ -5042,12 +4964,14 @@ function sameVnode (a, b) {
   )
 }
 
+// Some browsers do not support dynamically changing type for <input>
+// so they need to be treated as different nodes
 function sameInputType (a, b) {
   if (a.tag !== 'input') { return true }
   var i;
   var typeA = isDef(i = a.data) && isDef(i = i.attrs) && i.type;
   var typeB = isDef(i = b.data) && isDef(i = i.attrs) && i.type;
-  return typeA === typeB || isTextInputType(typeA) && isTextInputType(typeB)
+  return typeA === typeB
 }
 
 function createKeyToOldIdx (children, beginIdx, endIdx) {
@@ -5391,11 +5315,10 @@ function createPatchFunction (backend) {
         newStartVnode = newCh[++newStartIdx];
       } else {
         if (isUndef(oldKeyToIdx)) { oldKeyToIdx = createKeyToOldIdx(oldCh, 
oldStartIdx, oldEndIdx); }
-        idxInOld = isDef(newStartVnode.key)
-          ? oldKeyToIdx[newStartVnode.key]
-          : findIdxInOld(newStartVnode, oldCh, oldStartIdx, oldEndIdx);
+        idxInOld = isDef(newStartVnode.key) ? oldKeyToIdx[newStartVnode.key] : 
null;
         if (isUndef(idxInOld)) { // New element
           createElm(newStartVnode, insertedVnodeQueue, parentElm, 
oldStartVnode.elm);
+          newStartVnode = newCh[++newStartIdx];
         } else {
           elmToMove = oldCh[idxInOld];
           /* istanbul ignore if */
@@ -5409,12 +5332,13 @@ function createPatchFunction (backend) {
             patchVnode(elmToMove, newStartVnode, insertedVnodeQueue);
             oldCh[idxInOld] = undefined;
             canMove && nodeOps.insertBefore(parentElm, elmToMove.elm, 
oldStartVnode.elm);
+            newStartVnode = newCh[++newStartIdx];
           } else {
             // same key but different element. treat as new element
             createElm(newStartVnode, insertedVnodeQueue, parentElm, 
oldStartVnode.elm);
+            newStartVnode = newCh[++newStartIdx];
           }
         }
-        newStartVnode = newCh[++newStartIdx];
       }
     }
     if (oldStartIdx > oldEndIdx) {
@@ -5425,13 +5349,6 @@ function createPatchFunction (backend) {
     }
   }
 
-  function findIdxInOld (node, oldCh, start, end) {
-    for (var i = start; i < end; i++) {
-      var c = oldCh[i];
-      if (isDef(c) && sameVnode(node, c)) { return i }
-    }
-  }
-
   function patchVnode (oldVnode, vnode, insertedVnodeQueue, removeOnly) {
     if (oldVnode === vnode) {
       return
@@ -5650,29 +5567,15 @@ function createPatchFunction (backend) {
           // component root element replaced.
           // update parent placeholder node element, recursively
           var ancestor = vnode.parent;
-          var patchable = isPatchable(vnode);
           while (ancestor) {
-            for (var i = 0; i < cbs.destroy.length; ++i) {
-              cbs.destroy[i](ancestor);
-            }
             ancestor.elm = vnode.elm;
-            if (patchable) {
-              for (var i$1 = 0; i$1 < cbs.create.length; ++i$1) {
-                cbs.create[i$1](emptyNode, ancestor);
-              }
-              // #6513
-              // invoke insert hooks that may have been merged by create hooks.
-              // e.g. for directives that uses the "inserted" hook.
-              var insert = ancestor.data.hook.insert;
-              if (insert.merged) {
-                // start at index 1 to avoid re-invoking component mounted hook
-                for (var i$2 = 1; i$2 < insert.fns.length; i$2++) {
-                  insert.fns[i$2]();
-                }
-              }
-            }
             ancestor = ancestor.parent;
           }
+          if (isPatchable(vnode)) {
+            for (var i = 0; i < cbs.create.length; ++i) {
+              cbs.create[i](emptyNode, vnode.parent);
+            }
+          }
         }
 
         if (isDef(parentElm$1)) {
@@ -5914,9 +5817,7 @@ function add$1 (
   event,
   handler,
   once,
-  capture,
-  passive,
-  params
+  capture
 ) {
   if (capture) {
     console.log('Weex do not support event in bubble phase.');
@@ -5934,7 +5835,7 @@ function add$1 (
       }
     };
   }
-  target$1.addEvent(event, handler, params);
+  target$1.addEvent(event, handler);
 }
 
 function remove$2 (
@@ -6363,104 +6264,6 @@ var patch = createPatchFunction({
 var platformDirectives = {
 };
 
-function getVNodeType (vnode) {
-  if (!vnode.tag) {
-    return ''
-  }
-  return vnode.tag.replace(/vue\-component\-(\d+\-)?/, '')
-}
-
-function isSimpleSpan (vnode) {
-  return vnode.children && vnode.children.length === 1 && 
!vnode.children[0].tag
-}
-
-var cssLengthRE = /^([+-]?[0-9]+(\.[0-9]+)?)(px|em|ex|%|in|cm|mm|pt|pc)$/i;
-function trimCSSUnit (prop) {
-  var res = String(prop).match(cssLengthRE);
-  if (res) {
-    return Number(res[1])
-  }
-  return prop
-}
-
-function parseStyle (vnode) {
-  if (!vnode || !vnode.data) {
-    return
-  }
-
-  var ref = vnode.data;
-  var staticStyle = ref.staticStyle;
-  var staticClass = ref.staticClass;
-  if (vnode.data.style || vnode.data.class || staticStyle || staticClass) {
-    var styles = Object.assign({}, staticStyle, vnode.data.style);
-
-    var cssMap = vnode.context.$options.style || {};
-    var classList = [].concat(staticClass, vnode.data.class);
-    classList.forEach(function (name) {
-      if (name && cssMap[name]) {
-        Object.assign(styles, cssMap[name]);
-      }
-    });
-
-    for (var key in styles) {
-      styles[key] = trimCSSUnit(styles[key]);
-    }
-    return styles
-  }
-}
-
-function convertVNodeChildren (children) {
-  if (!children.length) {
-    return
-  }
-
-  return children.map(function (vnode) {
-    var type = getVNodeType(vnode);
-    var props = { type: type };
-
-    // convert raw text node
-    if (!type) {
-      props.type = 'span';
-      props.attr = {
-        value: (vnode.text || '').trim()
-      };
-    } else {
-      props.style = parseStyle(vnode);
-      if (vnode.data) {
-        props.attr = vnode.data.attrs;
-        if (vnode.data.on) {
-          props.events = vnode.data.on;
-        }
-      }
-
-      if (type === 'span' && isSimpleSpan(vnode)) {
-        props.attr = props.attr || {};
-        props.attr.value = vnode.children[0].text.trim();
-        return props
-      }
-    }
-
-    if (vnode.children && vnode.children.length) {
-      props.children = convertVNodeChildren(vnode.children);
-    }
-
-    return props
-  })
-}
-
-var Richtext = {
-  name: 'richtext',
-  // abstract: true,
-  render: function render (h) {
-    return h('weex:richtext', {
-      on: this._events,
-      attrs: {
-        value: convertVNodeChildren(this.$options._renderChildren || [])
-      }
-    })
-  }
-};
-
 /*  */
 
 // Provides transition support for a single element/component.
@@ -6531,6 +6334,10 @@ function isSameChild (child, oldChild) {
   return oldChild.key === child.key && oldChild.tag === child.tag
 }
 
+function isAsyncPlaceholder (node) {
+  return node.isComment && node.asyncFactory
+}
+
 var Transition$1 = {
   name: 'transition',
   props: transitionProps,
@@ -6797,17 +6604,16 @@ var TransitionGroup = {
 // }
 
 var platformComponents = {
-  Richtext: Richtext,
   Transition: Transition$1,
   TransitionGroup: TransitionGroup
 };
 
 /* globals renderer */
 
-var isReservedTag$1 = makeMap(
+var isReservedTag = makeMap(
   'template,script,style,element,content,slot,link,meta,svg,view,' +
-  'a,div,img,image,text,span,input,switch,textarea,spinner,select,' +
-  'slider,slider-neighbor,indicator,canvas,' +
+  'a,div,img,image,text,span,richtext,input,switch,textarea,spinner,select,' +
+  'slider,slider-neighbor,indicator,trisition,trisition-group,canvas,' +
   'list,cell,header,loading,loading-indicator,refresh,scrollable,scroller,' +
   'video,web,embed,tabbar,tabheader,datepicker,timepicker,marquee,countdown',
   true
@@ -6821,11 +6627,6 @@ var canBeLeftOpenTag = makeMap(
   true
 );
 
-var isRuntimeComponent = makeMap(
-  'richtext,trisition,trisition-group',
-  true
-);
-
 var isUnaryTag = makeMap(
   'embed,img,image,input,link,meta',
   true
@@ -6833,7 +6634,7 @@ var isUnaryTag = makeMap(
 
 function mustUseProp () { /* console.log('mustUseProp') */ }
 
-function isUnknownElement$1 () { /* console.log('isUnknownElement') */ }
+function isUnknownElement () { /* console.log('isUnknownElement') */ }
 
 function query (el, document) {
   // renderer is injected by weex factory wrapper
@@ -6847,9 +6648,8 @@ function query (el, document) {
 
 // install platform specific utils
 Vue$2.config.mustUseProp = mustUseProp;
-Vue$2.config.isReservedTag = isReservedTag$1;
-Vue$2.config.isRuntimeComponent = isRuntimeComponent;
-Vue$2.config.isUnknownElement = isUnknownElement$1;
+Vue$2.config.isReservedTag = isReservedTag;
+Vue$2.config.isUnknownElement = isUnknownElement;
 
 // install platform runtime directives and components
 Vue$2.options.directives = platformDirectives;
@@ -6988,11 +6788,11 @@ function createInstance (
   // It will declare some instance variables like `Vue`, HTML5 Timer APIs etc.
   var instanceVars = Object.assign({
     Vue: Vue,
-    weex: weexInstanceVar
+    weex: weexInstanceVar,
+    // deprecated
+    __weex_require_module__: weexInstanceVar.requireModule // 
eslint-disable-line
   }, timerAPIs, env.services);
 
-  appCode = "(function(global){ \n" + appCode + "\n })(Object.create(this))";
-
   if (!callFunctionNative(instanceVars, appCode)) {
     // If failed to compile functionBody on native side,
     // fallback to 'callFunction()'.
@@ -7001,8 +6801,6 @@ function createInstance (
 
   // Send `createFinish` signal to native.
   instance.document.taskCenter.send('dom', { action: 'createFinish' }, []);
-
-  return instance
 }
 
 /**
@@ -7069,16 +6867,17 @@ var jsHandlers = {
   }
 };
 
-function fireEvent (instance, nodeId, type, e, domChanges, params) {
+function fireEvent (instance, nodeId, type, e, domChanges) {
   var el = instance.document.getRef(nodeId);
   if (el) {
-    return instance.document.fireEvent(el, type, e, domChanges, params)
+    return instance.document.fireEvent(el, type, e, domChanges)
   }
   return new Error(("invalid element reference \"" + nodeId + "\""))
 }
 
 function callback (instance, callbackId, data, ifKeepAlive) {
   var result = instance.document.taskCenter.callback(callbackId, data, 
ifKeepAlive);
+  instance.document.taskCenter.send('dom', { action: 'updateFinish' }, []);
   return result
 }
 
@@ -7199,15 +6998,10 @@ function createVueModuleInstance (instanceId, 
moduleGetter) {
 
   // patch reserved tag detection to account for dynamically registered
   // components
-  var weexRegex = /^weex:/i;
   var isReservedTag = Vue.config.isReservedTag || (function () { return false; 
});
-  var isRuntimeComponent = Vue.config.isRuntimeComponent || (function () { 
return false; });
   Vue.config.isReservedTag = function (name) {
-    return (!isRuntimeComponent(name) && components[name]) ||
-      isReservedTag(name) ||
-      weexRegex.test(name)
+    return components[name] || isReservedTag(name)
   };
-  Vue.config.parsePlatformTagName = function (name) { return 
name.replace(weexRegex, ''); };
 
   // expose weex-specific info
   Vue.prototype.$instanceId = instanceId;
@@ -7332,41 +7126,6 @@ function getInstanceTimer (instanceId, moduleGetter) {
     },
     clearInterval: function (n) {
       timer.clearInterval(n);
-    },
-
-    // TODO: deprecated
-    deprecated_setTimeout: function deprecated_setTimeout (handler, delay) {
-      if (typeof commonjsGlobal.setIntervalWeex === 'function') {
-        var timerId = commonjsGlobal.setIntervalWeex(instanceId, function () {
-          handler.apply(null);
-          if (typeof commonjsGlobal.clearIntervalWeex === 'function') {
-            commonjsGlobal.clearIntervalWeex(instanceId, timerId);
-          }
-        }, delay);
-      }
-    },
-
-    // TODO: deprecated
-    deprecated_clearTimeout: function deprecated_clearTimeout (timerId) {
-      if (typeof commonjsGlobal.clearIntervalWeex === 'function') {
-        return commonjsGlobal.clearIntervalWeex(instanceId, timerId)
-      }
-    },
-
-    // TODO: deprecated
-    deprecated_setInterval: function deprecated_setInterval (handler, delay) {
-      if (typeof commonjsGlobal.setIntervalWeex === 'function') {
-        return commonjsGlobal.setIntervalWeex(instanceId, handler, delay)
-      }
-      console.warn("[JS Framework] can't find \"global.setIntervalWeex\"," +
-        " please use \"setInerval\" instead!!");
-    },
-
-    // TODO: deprecated
-    deprecated_clearInterval: function deprecated_clearInterval (timerId) {
-      if (typeof commonjsGlobal.clearIntervalWeex === 'function') {
-        return commonjsGlobal.clearIntervalWeex(instanceId, timerId)
-      }
     }
   };
   return timerAPIs
@@ -7458,7 +7217,7 @@ exports.supports = supports;
 });
 
 var index$1 = unwrapExports(index);
-var supports = index.supports;
+var supports$1 = index.supports;
 var isRegisteredComponent = index.isRegisteredComponent;
 var registerComponents = index.registerComponents;
 var isRegisteredModule = index.isRegisteredModule;
@@ -7474,7 +7233,7 @@ var init$2 = index.init;
 var Vue = Object.freeze({
        default: index$1,
        __moduleExports: index,
-       supports: supports,
+       supports: supports$1,
        isRegisteredComponent: isRegisteredComponent,
        registerComponents: registerComponents,
        isRegisteredModule: isRegisteredModule,
@@ -10445,7 +10204,7 @@ function initMethods$1 (Vm, apis) {
 /**
  * get a module of methods for an app instance
  */
-function requireModule (app, name) {
+function requireModule$1 (app, name) {
   var methods = nativeModules[name];
   var target = {};
   var loop = function ( methodName ) {
@@ -12875,7 +12634,7 @@ function App$1 (id, options) {
  * @deprecated
  */
 App$1.prototype.requireModule = function (name) {
-  return requireModule(this, name)
+  return requireModule$1(this, name)
 };
 
 /**
@@ -21852,7 +21611,7 @@ var frameworks = {
   Weex: Weex
 };
 
-var subversion = 
{"browser":"0.5.0","framework":"0.22.0","vue-render":"0.12.3","transformer":">=0.1.5
 <0.5"};
+var subversion = 
{"browser":"0.5.0","framework":"0.22.0-beta.2","vue-render":"0.12.3","transformer":">=0.1.5
 <0.5"};
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -23815,17 +23574,15 @@ function freezeProtoProperty (proto, propertyName, 
protoName) {
  * under the License.
  */
 
-/**
- * Get a unique id.
- */
-var nextNodeRef = 1;
-function uniqueId () {
-  return (nextNodeRef++).toString()
-}
+// Get a unique id.
+var uniqueId = (function () {
+  var nextNodeRef = 1;
+  return function () { return String(nextNodeRef++); }
+})();
 
 function typof$1 (v) {
-  var s = Object.prototype.toString.call(v);
-  return s.substring(8, s.length - 1)
+  var type = Object.prototype.toString.call(v);
+  return type.substring(8, type.length - 1)
 }
 
 function bufferToBase64 (buffer) {
@@ -24330,8 +24087,9 @@ Node.prototype.destroy = function destroy () {
  * specific language governing permissions and limitations
  * under the License.
  */
-var Element$2;
+var Element$2; // TODO: import Element
 
+// deprecated
 function setElement (El) {
   Element$2 = El;
 }
@@ -24418,74 +24176,6 @@ function getWeexElement (type) {
  * under the License.
  */
 
-// match the binding delimiter
-var delimiterRE = /\[\[((?:.|\n)+?)\]\]/g;
-
-function generateBinding (text) {
-  if (typof$1(text) === 'String') {
-    return { '@binding': text }
-  }
-  return text
-}
-
-function parseString (string) {
-  var tokens = [];
-  var lastIndex = delimiterRE.lastIndex = 0;
-  var match, index;
-  while ((match = delimiterRE.exec(string))) {
-    index = match.index;
-    if (index > lastIndex) {
-      tokens.push(string.slice(lastIndex, index));
-    }
-    var binding = generateBinding(match[1].trim());
-    tokens.push(binding);
-    lastIndex = index + match[0].length;
-  }
-  if (lastIndex < string.length) {
-    tokens.push(string.slice(lastIndex));
-  }
-  if (tokens.length === 1) {
-    return tokens[0]
-  }
-  return tokens
-}
-
-function filterDirective (value) {
-  if (typof$1(value) === 'String' && delimiterRE.test(value)) {
-    return parseString(value)
-  }
-  if (typof$1(value) === 'Object') {
-    var realData = {};
-    for (var key in value) {
-      realData[key] = filterDirective(value[key]);
-    }
-    return realData
-  }
-  if (typof$1(value) === 'Array') {
-    return value.map(filterDirective)
-  }
-  return 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.
- */
-
 var DEFAULT_TAG_NAME = 'div';
 var BUBBLE_EVENTS = [
   'click', 'longpress', 'touchstart', 'touchmove', 'touchend',
@@ -24499,20 +24189,19 @@ function registerNode (docId, node) {
 
 var Element = (function (Node$$1) {
   function Element (type, props, isExtended) {
-    if ( type === void 0 ) type = DEFAULT_TAG_NAME;
-
     Node$$1.call(this);
 
+    // TODO: deprecated
     var WeexElement = getWeexElement(type);
     if (WeexElement && !isExtended) {
-      return new WeexElement(props)
+      return new WeexElement(type, props, true)
     }
 
     props = props || {};
     this.nodeType = 1;
     this.nodeId = uniqueId();
     this.ref = this.nodeId;
-    this.type = type;
+    this.type = type || DEFAULT_TAG_NAME;
     this.attr = props.attr || {};
     this.style = props.style || {};
     this.classStyle = props.classStyle || {};
@@ -24749,7 +24438,7 @@ var Element = (function (Node$$1) {
     var taskCenter = getTaskCenter(this.docId);
     if (!silent && taskCenter) {
       var result = {};
-      result[key] = filterDirective(value);
+      result[key] = value;
       taskCenter.send(
         'dom',
         { action: 'updateAttrs' },
@@ -24806,13 +24495,11 @@ var Element = (function (Node$$1) {
 
   /**
    * Add an event handler.
-   * @param {string} event type
-   * @param {function} event handler
+   * @param {string} type event type
+   * @param {function} handler event handler
+   * @param {object} params event handler parameters
    */
   Element.prototype.addEvent = function addEvent (type, handler, params) {
-    if (!this.event) {
-      this.event = {};
-    }
     if (!this.event[type]) {
       this.event[type] = { handler: handler, params: params };
       var taskCenter = getTaskCenter(this.docId);
@@ -24831,7 +24518,7 @@ var Element = (function (Node$$1) {
    * @param {string} event type
    */
   Element.prototype.removeEvent = function removeEvent (type) {
-    if (this.event && this.event[type]) {
+    if (this.event[type]) {
       delete this.event[type];
       var taskCenter = getTaskCenter(this.docId);
       if (taskCenter) {
@@ -24847,35 +24534,36 @@ var Element = (function (Node$$1) {
   /**
    * Fire an event manually.
    * @param {string} type type
-   * @param {function} event handler
+   * @param {function} e handler
    * @param {boolean} isBubble whether or not event bubble
-   * @param {boolean} options
+   * @param {object} options additional options
    * @return {} anything returned by handler function
    */
-  Element.prototype.fireEvent = function fireEvent (type, event, isBubble, 
options) {
+  Element.prototype.fireEvent = function fireEvent (type, e, isBubble, 
options) {
     var result = null;
     var isStopPropagation = false;
     var eventDesc = this.event[type];
-    if (eventDesc && event) {
+    if (eventDesc && e) {
       var handler = eventDesc.handler;
-      event.stopPropagation = function () {
+      e.stopPropagation = function () {
         isStopPropagation = true;
       };
       if (options && options.params) {
-        result = handler.call.apply(handler, [ this ].concat( options.params, 
[event] ));
+        result = handler.call.apply(handler, [ this ].concat( options.params, 
[e] ));
       }
       else {
-        result = handler.call(this, event);
+        result = handler.call(this, e);
       }
     }
 
+    // TODO: bubble in next tick
     if (!isStopPropagation
       && isBubble
       && BUBBLE_EVENTS.includes(type)
       && this.parentNode
       && this.parentNode.fireEvent) {
-      event.currentTarget = this.parentNode;
-      this.parentNode.fireEvent(type, event, isBubble); // no options
+      e.currentTarget = this.parentNode;
+      this.parentNode.fireEvent(type, e, isBubble);
     }
 
     return result
@@ -24899,18 +24587,18 @@ var Element = (function (Node$$1) {
     var result = {
       ref: this.ref.toString(),
       type: this.type,
-      attr: filterDirective(this.attr),
+      attr: this.attr,
       style: this.toStyle()
     };
     var event = [];
-    for (var type in this.event) {
-      var ref = this$1.event[type];
+    for (var eventType in this.event) {
+      var ref = this$1.event[eventType];
       var params = ref.params;
       if (!params) {
-        event.push(type);
+        event.push(eventType);
       }
       else {
-        event.push({ type: type, params: params });
+        event.push({ type: eventType, params: params });
       }
     }
     if (event.length) {
@@ -25089,7 +24777,6 @@ function init$6 () {
  */
 
 // JS Services
-
 var services = [];
 
 /**
@@ -25106,8 +24793,8 @@ var services = [];
  *                         return an object of what variables or classes
  *                         would be injected into the Weex instance.
  */
-function register$2 (name, options) {
-  if (has$5(name)) {
+function registerService (name, options) {
+  if (hasService(name)) {
     console.warn(("Service \"" + name + "\" has been registered already!"));
   }
   else {
@@ -25120,7 +24807,7 @@ function register$2 (name, options) {
  * Unregister a JavaScript service by name
  * @param {string} name
  */
-function unregister (name) {
+function unregisterService (name) {
   services.some(function (service, index) {
     if (service.name === name) {
       services.splice(index, 1);
@@ -25134,17 +24821,52 @@ function unregister (name) {
  * @param  {string}  name
  * @return {Boolean}
  */
-function has$5 (name) {
-  return indexOf(name) >= 0
+function hasService (name) {
+  return services.map(function (service) { return service.name; 
}).indexOf(name) >= 0
 }
 
 /**
- * Find the index of a JavaScript service by name
- * @param  {string} name
- * @return {number}
+ * Generate service map
  */
-function indexOf (name) {
-  return services.map(function (service) { return service.name; 
}).indexOf(name)
+function createServices (id, env, config) {
+  // Init JavaScript services for this instance.
+  var serviceMap = Object.create(null);
+  serviceMap.service = Object.create(null);
+  services.forEach(function (ref) {
+    var name = ref.name;
+    var options = ref.options;
+
+    {
+      console.debug(("[JS Runtime] create service " + name + "."));
+    }
+    var create = options.create;
+    if (create) {
+      var result = create(id, env, config);
+      Object.assign(serviceMap.service, result);
+      Object.assign(serviceMap, result.instance);
+    }
+  });
+  delete serviceMap.service.instance;
+  Object.freeze(serviceMap.service);
+  return serviceMap
+}
+
+function refreshServices (id, env, config) {
+  services.forEach(function (service) {
+    var refresh = service.options.refresh;
+    if (typeof refresh === 'function') {
+      refresh(id, env, config);
+    }
+  });
+}
+
+function destroyServices (id, env, config) {
+  services.forEach(function (service) {
+    var destroy = service.options.destroy;
+    if (typeof destroy === 'function') {
+      destroy(id, env, config);
+    }
+  });
 }
 
 /*
@@ -25166,223 +24888,94 @@ function indexOf (name) {
  * under the License.
  */
 
-var frameworks$1;
-var runtimeConfig;
-
-var versionRegExp = /^\s*\/\/ *(\{[^}]*\}) *\r?\n/;
+var weexModules = {};
 
 /**
- * Detect a JS Bundle code and make sure which framework it's based to. Each JS
- * Bundle should make sure that it starts with a line of JSON comment and is
- * more that one line.
- * @param  {string} code
- * @return {object}
+ * Register native modules information.
+ * @param {object} newModules
  */
-function getBundleType (code) {
-  var result = versionRegExp.exec(code);
-  if (result) {
-    try {
-      var info = JSON.parse(result[1]);
-      return info.framework
+function registerModules$2 (newModules) {
+  var loop = function ( name ) {
+    if (!weexModules[name]) {
+      weexModules[name] = {};
     }
-    catch (e) {}
-  }
+    newModules[name].forEach(function (method) {
+      if (typeof method === 'string') {
+        weexModules[name][method] = true;
+      }
+      else {
+        weexModules[name][method.name] = method.args;
+      }
+    });
+  };
 
-  // default bundle type
-  return 'Weex'
+  for (var name in newModules) loop( name );
 }
 
-function createServices (id, env, config) {
-  // Init JavaScript services for this instance.
-  var serviceMap = Object.create(null);
-  serviceMap.service = Object.create(null);
-  services.forEach(function (ref) {
-    var name = ref.name;
-    var options = ref.options;
+/**
+ * Check whether the module or the method has been registered.
+ * @param {String} module name
+ * @param {String} method name (optional)
+ */
+function isRegisteredModule$1 (name, method) {
+  if (typeof method === 'string') {
+    return !!(weexModules[name] && weexModules[name][method])
+  }
+  return !!weexModules[name]
+}
 
-    {
-      console.debug(("[JS Runtime] create service " + name + "."));
-    }
-    var create = options.create;
-    if (create) {
-      var result = create(id, env, config);
-      Object.assign(serviceMap.service, result);
-      Object.assign(serviceMap, result.instance);
-    }
-  });
-  delete serviceMap.service.instance;
-  Object.freeze(serviceMap.service);
-  return serviceMap
+function getModuleDescription (name) {
+  return weexModules[name]
 }
 
-var instanceMap$2 = {};
-
-function getFrameworkType (id) {
-  if (instanceMap$2[id]) {
-    return instanceMap$2[id].framework
-  }
-}
-
-/**
- * Check which framework a certain JS Bundle code based to. And create instance
- * by this framework.
- * @param {string} id
- * @param {string} code
- * @param {object} config
- * @param {object} 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.
  */
-function createInstance$3 (id, code, config, data) {
-  if (instanceMap$2[id]) {
-    return new Error(("invalid instance id \"" + id + "\""))
-  }
-
-  // Init instance info.
-  var bundleType = getBundleType(code);
-
-  // Init instance config.
-  config = JSON.parse(JSON.stringify(config || {}));
-  config.env = JSON.parse(JSON.stringify(global.WXEnvironment || {}));
-
-  var context = {
-    config: config,
-    created: Date.now(),
-    framework: bundleType
-  };
-  context.services = createServices(id, context, runtimeConfig);
-  instanceMap$2[id] = context;
-
-  {
-    console.debug(("[JS Framework] create an " + bundleType + " instance"));
-  }
-
-  var fm = frameworks$1[bundleType];
-  if (!fm) {
-    return new Error(("invalid bundle type \"" + bundleType + "\"."))
-  }
 
-  return fm.createInstance(id, code, config, data, context)
-}
-
-var methods$1 = {
-  createInstance: createInstance$3,
-  registerService: register$2,
-  unregisterService: unregister
-};
+var weexComponents = {};
 
 /**
- * Register methods which init each frameworks.
- * @param {string} methodName
+ * Register native components information.
+ * @param {array} newComponents
  */
-function genInit (methodName) {
-  methods$1[methodName] = function () {
-    var args = [], len = arguments.length;
-    while ( len-- ) args[ len ] = arguments[ len ];
-
-    if (methodName === 'registerComponents') {
-      checkComponentMethods(args[0]);
-    }
-    for (var name in frameworks$1) {
-      var framework = frameworks$1[name];
-      if (framework && framework[methodName]) {
-        framework[methodName].apply(framework, args);
+function registerComponents$2 (newComponents) {
+  if (Array.isArray(newComponents)) {
+    newComponents.forEach(function (component) {
+      if (!component) {
+        return
       }
-    }
-  };
-}
-
-function checkComponentMethods (components) {
-  if (Array.isArray(components)) {
-    components.forEach(function (name) {
-      if (name && name.type && name.methods) {
-        registerElement(name.type, name.methods);
+      if (typeof component === 'string') {
+        weexComponents[component] = true;
+      }
+      else if (typeof component === 'object' && typeof component.type === 
'string') {
+        weexComponents[component.type] = component;
+        registerElement(component.type, component.methods);
       }
     });
   }
 }
 
 /**
- * Register methods which will be called for each instance.
- * @param {string} methodName
+ * Check whether the component has been registered.
+ * @param {String} component name
  */
-function genInstance (methodName) {
-  methods$1[methodName] = function () {
-    var args = [], len = arguments.length;
-    while ( len-- ) args[ len ] = arguments[ len ];
-
-    var id = args[0];
-    var type = getFrameworkType(id);
-    if (type && frameworks$1[type]) {
-      var result = (ref = frameworks$1[type])[methodName].apply(ref, args);
-      var info = { framework: type };
-
-      // Lifecycle methods
-      if (methodName === 'refreshInstance') {
-        services.forEach(function (service) {
-          var refresh = service.options.refresh;
-          if (refresh) {
-            refresh(id, { info: info, runtime: runtimeConfig });
-          }
-        });
-      }
-      else if (methodName === 'destroyInstance') {
-        services.forEach(function (service) {
-          var destroy = service.options.destroy;
-          if (destroy) {
-            destroy(id, { info: info, runtime: runtimeConfig });
-          }
-        });
-        delete instanceMap$2[id];
-      }
-
-      return result
-    }
-    return new Error(("invalid instance id \"" + id + "\""))
-    var ref;
-  };
-}
-
-/**
- * Adapt some legacy method(s) which will be called for each instance. These
- * methods should be deprecated and removed later.
- * @param {string} methodName
- * @param {string} nativeMethodName
- */
-function adaptInstance (methodName, nativeMethodName) {
-  methods$1[nativeMethodName] = function () {
-    var args = [], len = arguments.length;
-    while ( len-- ) args[ len ] = arguments[ len ];
-
-    var id = args[0];
-    var type = getFrameworkType(id);
-    if (type && frameworks$1[type]) {
-      return (ref = frameworks$1[type])[methodName].apply(ref, args)
-    }
-    return new Error(("invalid instance id \"" + id + "\""))
-    var ref;
-  };
-}
-
-function init$5 (config) {
-  runtimeConfig = config || {};
-  frameworks$1 = runtimeConfig.frameworks || {};
-  init$6();
-
-  // Init each framework by `init` method and `config` which contains three
-  // virtual-DOM Class: `Document`, `Element` & `Comment`, and a JS bridge 
method:
-  // `sendTasks(...args)`.
-  for (var name in frameworks$1) {
-    var framework = frameworks$1[name];
-    framework.init(config);
-  }
-
-  // @todo: The method `registerMethods` will be re-designed or removed later.
-   ['registerComponents', 'registerModules', 
'registerMethods'].forEach(genInit)
-
-  ; ['destroyInstance', 'refreshInstance', 'receiveTasks', 
'getRoot'].forEach(genInstance);
-
-  adaptInstance('receiveTasks', 'callJS');
-
-  return methods$1
+function isRegisteredComponent$1 (name) {
+  return !!weexComponents[name]
 }
 
 /*
@@ -25884,6 +25477,10 @@ Document.prototype.createBody = function createBody 
(type, props) {
 * @return {object} element
 */
 Document.prototype.createElement = function createElement (tagName, props) {
+  var WeexElement = getWeexElement(tagName);
+  if (WeexElement) {
+    return new WeexElement(tagName, props)
+  }
   return new Element(tagName, props)
 };
 
@@ -25899,10 +25496,10 @@ Document.prototype.createComment = function 
createComment (text) {
 /**
 * Fire an event on specified element manually.
 * @param {object} element
-* @param {string} event type
-* @param {object} event object
-* @param {object} dom changes
-* @param {object} options
+* @param {string} type event type
+* @param {object} eventevent object
+* @param {object} domChanges
+ * @param {object} options additional options
 * @return {} anything returned by handler function
 */
 Document.prototype.fireEvent = function fireEvent (el, type, event, 
domChanges, options) {
@@ -25954,6 +25551,386 @@ Document.handler = null;
  * under the License.
  */
 
+var moduleProxys = {};
+
+function setId$1 (weex, id) {
+  Object.defineProperty(weex, '[[CurrentInstanceId]]', { value: id });
+}
+
+function getId (weex) {
+  return weex['[[CurrentInstanceId]]']
+}
+
+function moduleGetter$1 (module, method, taskCenter) {
+  return function () {
+    var args = [], len = arguments.length;
+    while ( len-- ) args[ len ] = arguments[ len ];
+
+    return taskCenter.send('module', { module: module, method: method }, args);
+  }
+}
+
+var WeexInstance = function WeexInstance (id, config) {
+  setId$1(this, id);
+  this.config = config || {};
+  this.document = new Document(id, this.config.bundleUrl);
+  this.requireModule = this.requireModule.bind(this);
+  this.isRegisteredModule = isRegisteredModule$1;
+  this.isRegisteredComponent = isRegisteredComponent$1;
+};
+
+WeexInstance.prototype.requireModule = function requireModule (moduleName) {
+  var id = getId(this);
+  if (!(id && this.document && this.document.taskCenter)) {
+    console.error(("[JS Framework] invalid instance id \"" + id + "\""));
+    return
+  }
+
+  // warn for unknown module
+  if (!isRegisteredModule$1(moduleName)) {
+    console.warn(("[JS Framework] using unregistered weex module \"" + 
moduleName + "\""));
+    return
+  }
+
+  // create new module proxy
+  if (!moduleProxys[moduleName]) {
+    var moduleDefine = getModuleDescription(moduleName);
+    var taskCenter = this.document.taskCenter;
+
+    // create registered module apis
+    var moduleApis = {};
+    var loop = function ( methodName ) {
+      Object.defineProperty(moduleApis, methodName, {
+        enumerable: true,
+        configurable: true,
+        get: function () { return moduleGetter$1(moduleName, methodName, 
taskCenter); },
+        set: function set (fn) {
+          if (typeof fn === 'function') {
+            return taskCenter.send('module', {
+              module: moduleName,
+              method: methodName
+            }, [fn])
+          }
+        }
+      });
+    };
+
+      for (var methodName in moduleDefine) loop( methodName );
+
+    // create module Proxy
+    if (typeof Proxy === 'function') {
+      moduleProxys[moduleName] = new Proxy(moduleApis, {
+        get: function get (target, methodName) {
+          if (methodName in target) {
+            return target[methodName]
+          }
+          console.warn(("[JS Framework] using unregistered method \"" + 
moduleName + "." + methodName + "\""));
+          return moduleGetter$1(moduleName, methodName, taskCenter)
+        }
+      });
+    }
+    else {
+      moduleProxys[moduleName] = moduleApis;
+    }
+  }
+
+  return moduleProxys[moduleName]
+};
+
+WeexInstance.prototype.supports = function supports (condition) {
+  if (typeof condition !== 'string') { return null }
+
+  var res = condition.match(/^@(\w+)\/(\w+)(\.(\w+))?$/i);
+  if (res) {
+    var type = res[1];
+    var name = res[2];
+    var method = res[4];
+    switch (type) {
+      case 'module': return isRegisteredModule$1(name, method)
+      case 'component': return isRegisteredComponent$1(name)
+    }
+  }
+
+  return null
+};
+
+/*
+ * 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 versionRegExp = /^\s*\/\/ *(\{[^}]*\}) *\r?\n/;
+
+/**
+ * Detect a JS Bundle code and make sure which framework it's based to. Each JS
+ * Bundle should make sure that it starts with a line of JSON comment and is
+ * more that one line.
+ * @param  {string} code
+ * @return {object}
+ */
+function getBundleType (code) {
+  var result = versionRegExp.exec(code);
+  if (result) {
+    try {
+      var info = JSON.parse(result[1]);
+      return info.framework
+    }
+    catch (e) {}
+  }
+  return 'Weex' // default bundle type
+}
+
+var instanceMap$2 = {};
+
+function getFrameworkType (id) {
+  if (instanceMap$2[id]) {
+    return instanceMap$2[id].framework
+  }
+  return 'Weex'
+}
+
+/**
+ * Check which framework a certain JS Bundle code based to. And create instance
+ * by this framework.
+ * @param {string} id
+ * @param {string} code
+ * @param {object} config
+ * @param {object} data
+ */
+function createInstance$3 (id, code, config, data) {
+  if (instanceMap$2[id]) {
+    return new Error(("invalid instance id \"" + id + "\""))
+  }
+
+  // Init instance info.
+  var bundleType = getBundleType(code);
+  var runtimeConfig = getRuntimeConfig();
+
+  // Init instance config.
+  config = JSON.parse(JSON.stringify(config || {}));
+  config.env = JSON.parse(JSON.stringify(global.WXEnvironment || {}));
+
+  var weex = new WeexInstance(id, config);
+  Object.freeze(weex);
+
+  var runtimeEnv = {
+    weex: weex, // TODO: deprecated
+    config: config, // TODO: deprecated
+    created: Date.now(),
+    framework: bundleType
+  };
+
+  // TODO: deprecated, no need to pass services to runtime env
+  runtimeEnv.services = createServices(id, runtimeEnv, runtimeConfig);
+  instanceMap$2[id] = runtimeEnv;
+
+  var runtimeContext = Object.create(null);
+  Object.assign(runtimeContext, runtimeEnv.services, { weex: weex });
+
+  var framework = runtimeConfig.frameworks[bundleType];
+  if (!framework) {
+    return new Error(("invalid bundle type \"" + bundleType + "\"."))
+  }
+
+  {
+    console.debug(("[JS Framework] create an " + bundleType + " instance"));
+  }
+
+  // run create instance
+  if (typeof framework.prepareInstanceContext === 'function') {
+    var instanceContext = framework.prepareInstanceContext(runtimeContext);
+    return runInContext(code, instanceContext)
+  }
+  return framework.createInstance(id, code, config, data, runtimeEnv)
+}
+
+function runInContext (code, context) {
+  var keys = [];
+  var args = [];
+  for (var key in context) {
+    keys.push(key);
+    args.push(context[key]);
+  }
+
+  var bundle = "\n    (function (global) {\n      \"use strict\";\n      " + 
code + "\n    })(Object.create(this))\n  ";
+
+  return (new (Function.prototype.bind.apply( Function, [ null ].concat( keys, 
[bundle]) ))).apply(void 0, args)
+}
+
+function refreshInstance$2 (id) {
+  var args = [], len = arguments.length - 1;
+  while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
+
+  var type = getFrameworkType(id);
+  var runtimeConfig = getRuntimeConfig();
+  refreshServices(id, {
+    info: { framework: type },
+    runtime: runtimeConfig
+  });
+
+  var fm = runtimeConfig.frameworks[type];
+  if (!fm) {
+    return new Error(("refreshInstance: the instance id of \"" + type + "\" is 
not found."))
+  }
+  return fm.refreshInstance.apply(fm, [ id ].concat( args ))
+}
+
+function destroyInstance$3 (id) {
+  var args = [], len = arguments.length - 1;
+  while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
+
+  var type = getFrameworkType(id);
+  var runtimeConfig = getRuntimeConfig();
+  destroyServices(id, {
+    info: { framework: type },
+    runtime: runtimeConfig
+  });
+
+  var fm = runtimeConfig.frameworks[type];
+  if (!fm) {
+    return new Error(("destroyInstance: the instance id of \"" + type + "\" is 
not found."))
+  }
+  delete instanceMap$2[id];
+  return fm.destroyInstance.apply(fm, [ id ].concat( args ))
+}
+
+/*
+ * 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 runtimeConfig = {};
+
+function getRuntimeConfig () {
+  return runtimeConfig
+}
+
+var methods$1 = {
+  createInstance: createInstance$3,
+  refreshInstance: refreshInstance$2,
+  destroyInstance: destroyInstance$3,
+  registerService: registerService,
+  unregisterService: unregisterService
+};
+
+/**
+ * Register methods which init each frameworks.
+ * @param {string} methodName
+ * @param {function} sharedMethod
+ */
+function adaptMethod (methodName, sharedMethod) {
+  methods$1[methodName] = function () {
+    var args = [], len = arguments.length;
+    while ( len-- ) args[ len ] = arguments[ len ];
+
+    if (typeof sharedMethod === 'function') {
+      sharedMethod.apply(void 0, args);
+    }
+
+    // TODO: deprecated
+    for (var name in runtimeConfig.frameworks) {
+      var framework = runtimeConfig.frameworks[name];
+      if (framework && framework[methodName]) {
+        framework[methodName].apply(framework, args);
+      }
+    }
+  };
+}
+
+/**
+ * Register methods which will be called for each instance.
+ * @param {string} methodName
+ */
+// TODO: move to instance.js
+function genInstance (methodName) {
+  methods$1[methodName] = function () {
+    var args = [], len = arguments.length;
+    while ( len-- ) args[ len ] = arguments[ len ];
+
+    var id = args[0];
+    var type = getFrameworkType(id);
+    var framework = runtimeConfig.frameworks[type];
+    if (type && framework) {
+      return framework[methodName].apply(framework, args)
+    }
+    return new Error(("invalid instance id \"" + id + "\""))
+  };
+}
+
+function init$5 (config) {
+  Object.assign(runtimeConfig, config);
+
+  init$6();
+
+  // Init each framework by `init` method and `config` which contains three
+  // virtual-DOM Class: `Document`, `Element` & `Comment`, and a JS bridge 
method:
+  // `sendTasks(...args)`.
+  var frameworks = runtimeConfig.frameworks || {};
+  for (var name in frameworks) {
+    var framework = frameworks[name];
+    framework.init(config);
+  }
+
+  adaptMethod('registerComponents', registerComponents$2);
+  adaptMethod('registerModules', registerModules$2);
+  adaptMethod('registerMethods')
+
+  // TODO: deprecated
+  ; ['receiveTasks', 'getRoot'].forEach(genInstance);
+
+  // adapt instance
+  methods$1.callJS = methods$1.receiveTasks;
+
+  return methods$1
+}
+
+/*
+ * 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.
+ */
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -26019,11 +25996,11 @@ Document.handler = config$2.sendTasks;
 function freezePrototype$$1 () {
   freezePrototype$1();
 
-  Object.freeze(config$2.Element);
+  // Object.freeze(config.Element)
   Object.freeze(config$2.Comment);
   Object.freeze(config$2.Listener);
   Object.freeze(config$2.Document.prototype);
-  Object.freeze(config$2.Element.prototype);
+  // Object.freeze(config.Element.prototype)
   Object.freeze(config$2.Comment.prototype);
   Object.freeze(config$2.Listener.prototype);
 }
@@ -26033,7 +26010,7 @@ var runtime = {
   resetNativeConsole: resetNativeConsole,
   setNativeTimer: setNativeTimer,
   resetNativeTimer: resetNativeTimer,
-  service: { register: register$2, unregister: unregister, has: has$5 },
+  service: { registerService: registerService, unregisterService: 
unregisterService, hasService: hasService },
   freezePrototype: freezePrototype$$1,
   init: init$5,
   config: config$2
@@ -26059,15 +26036,13 @@ var runtime = {
  */
 
 /**
- * Mock MessageEvent type
- * @param {string} type
- * @param {object} dict { data, origin, source, ports }
+ * Implement the MessageEvent.
  *
  * This type has been simplified.
  * https://html.spec.whatwg.org/multipage/comms.html#messageevent
  * https://dom.spec.whatwg.org/#interface-event
  */
-function MessageEvent (type, dict) {
+var MessageEvent = function MessageEvent (type, dict) {
   if ( dict === void 0 ) dict = {};
 
   this.type = type || 'message';
@@ -26080,51 +26055,40 @@ function MessageEvent (type, dict) {
   // inherit properties
   this.target = null;
   this.timeStamp = Date.now();
-}
+};
 
-/*
- * 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 channels = {};
 
 /**
- * @fileOverview
- * The polyfill of BroadcastChannel API.
+ * Implement the BroadcastChannel API.
  * This api can be used to achieve inter-instance communications.
  *
  * 
https://html.spec.whatwg.org/multipage/comms.html#broadcasting-to-other-browsing-contexts
  */
+var BroadcastChannel$1 = function BroadcastChannel$1 (name) {
+  // the name property is readonly
+  Object.defineProperty(this, 'name', {
+    configurable: false,
+    enumerable: true,
+    writable: false,
+    value: String(name)
+  });
 
-var channels = {};
-var instances = {};
+  this._closed = false;
+  this.onmessage = null;
 
-/**
- * An empty constructor for BroadcastChannel polyfill.
- * The real constructor will be defined when a Weex instance created because
- * we need to track the channel by Weex instance id.
- */
-function BroadcastChannel () {}
+  if (!channels[this.name]) {
+    channels[this.name] = [];
+  }
+  channels[this.name].push(this);
+};
 
 /**
  * Sends the given message to other BroadcastChannel objects set up for this 
channel.
  * @param {any} message
  */
-BroadcastChannel.prototype.postMessage = function (message) {
-  var this$1 = this;
+BroadcastChannel$1.prototype.postMessage = function postMessage (message) {
+    var this$1 = this;
 
   if (this._closed) {
     throw new Error(("BroadcastChannel \"" + (this.name) + "\" is closed."))
@@ -26134,9 +26098,7 @@ BroadcastChannel.prototype.postMessage = function 
(message) {
   if (subscribers && subscribers.length) {
     for (var i = 0; i < subscribers.length; ++i) {
       var member = subscribers[i];
-
       if (member._closed || member === this$1) { continue }
-
       if (typeof member.onmessage === 'function') {
         member.onmessage(new MessageEvent('message', { data: message }));
       }
@@ -26147,15 +26109,13 @@ BroadcastChannel.prototype.postMessage = function 
(message) {
 /**
  * Closes the BroadcastChannel object, opening it up to garbage collection.
  */
-BroadcastChannel.prototype.close = function () {
-  var this$1 = this;
+BroadcastChannel$1.prototype.close = function close () {
+    var this$1 = this;
 
   if (this._closed) {
     return
   }
 
-  this._closed = true;
-
   // remove itself from channels.
   if (channels[this.name]) {
     var subscribers = channels[this.name].filter(function (x) { return x !== 
this$1; });
@@ -26166,47 +26126,65 @@ BroadcastChannel.prototype.close = function () {
       delete channels[this.name];
     }
   }
+
+  this._closed = true;
 };
 
-var BroadcastChannel$1 = {
-  create: function (id, env, config) {
-    instances[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.
+ */
+
+var listeners = {};
+
+var BroadcastChannel$$1 = {
+  create: function create (id) {
     if (typeof global.BroadcastChannel === 'function') {
       return {}
     }
-    var serviceObject = {
-      /**
-       * Returns a new BroadcastChannel object via which messages for the given
-       * channel name can be sent and received.
-       * @param {string} name
-       */
-      BroadcastChannel: function (name) {
-        // the name property is readonly
-        Object.defineProperty(this, 'name', {
-          configurable: false,
-          enumerable: true,
-          writable: false,
-          value: String(name)
-        });
 
-        this._closed = false;
-        this.onmessage = null;
+    listeners[id] = [];
+    var InstanceBroadcastChannel = (function (BroadcastChannel$$1) {
+      function InstanceBroadcastChannel () {
+        var args = [], len = arguments.length;
+        while ( len-- ) args[ len ] = arguments[ len ];
 
-        if (!channels[this.name]) {
-          channels[this.name] = [];
-        }
-        channels[this.name].push(this);
-        instances[id].push(this);
+        BroadcastChannel$$1.apply(this, args);
+        listeners[id].push(this);
       }
-    };
-    serviceObject.BroadcastChannel.prototype = BroadcastChannel.prototype;
+
+      if ( BroadcastChannel$$1 ) InstanceBroadcastChannel.__proto__ = 
BroadcastChannel$$1;
+      InstanceBroadcastChannel.prototype = Object.create( BroadcastChannel$$1 
&& BroadcastChannel$$1.prototype );
+      InstanceBroadcastChannel.prototype.constructor = 
InstanceBroadcastChannel;
+
+      return InstanceBroadcastChannel;
+    }(BroadcastChannel$1));
     return {
-      instance: serviceObject
+      instance: {
+        BroadcastChannel: InstanceBroadcastChannel
+      }
     }
   },
-  destroy: function (id, env) {
-    instances[id].forEach(function (channel) { return channel.close(); });
-    delete instances[id];
+
+  destroy: function destroy (id) {
+    if (id && listeners[id]) {
+      listeners[id].forEach(function (member) { return member.close(); });
+      delete listeners[id];
+    }
   }
 };
 
@@ -26229,7 +26207,7 @@ var BroadcastChannel$1 = {
  * under the License.
  */
 var services$1 = {
-  BroadcastChannel: BroadcastChannel$1
+  BroadcastChannel: BroadcastChannel$$1
 };
 
 /*
@@ -26264,7 +26242,7 @@ var setup = function (frameworks) {
   var transformer = subversion.transformer;
 
   for (var serviceName in services$1) {
-    runtime.service.register(serviceName, services$1[serviceName]);
+    runtime.service.registerService(serviceName, services$1[serviceName]);
   }
 
   runtime.freezePrototype();
@@ -26432,4 +26410,4 @@ setup(frameworks);
 global.registerMethods(methods$2);
 
 })));
-//# 
sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjpudWxsLCJzb3VyY2VzIjpbIi4uL3dlZXgvaHRtbDUvZnJhbWV3b3Jrcy92YW5pbGxhL2luZGV4LmpzIiwiLi4vLi4vdnVlL3BhY2thZ2VzL3dlZXgtdnVlLWZyYW1ld29yay9mYWN0b3J5LmpzIiwiLi4vLi4vdnVlL3BhY2thZ2VzL3dlZXgtdnVlLWZyYW1ld29yay9pbmRleC5qcyIsIi4uL3dlZXgvaHRtbDUvZnJhbWV3b3Jrcy9sZWdhY3kvYXBpL21ldGhvZHMuanMiLCIuLi93ZWV4L2h0bWw1L2ZyYW1ld29ya3MvbGVnYWN5L3V0aWwvc2hhcmVkLmpzIiwiLi4vd2VleC9odG1sNS9mcmFtZXdvcmtzL2xlZ2FjeS91dGlsL2luZGV4LmpzIiwiLi4vd2VleC9odG1sNS9mcmFtZXdvcmtzL2xlZ2FjeS9jb3JlL2RlcC5qcyIsIi4uL3dlZXgvaHRtbDUvZnJhbWV3b3Jrcy9sZWdhY3kvY29yZS93YXRjaGVyLmpzIiwiLi4vd2VleC9odG1sNS9mcmFtZXdvcmtzL2xlZ2FjeS9jb3JlL2FycmF5LmpzIiwiLi4vd2VleC9odG1sNS9mcmFtZXdvcmtzL2xlZ2FjeS9jb3JlL29ic2VydmVyLmpzIiwiLi4vd2VleC9odG1sNS9mcmFtZXdvcmtzL2xlZ2FjeS9jb3JlL3N0YXRlLmpzIiwiLi4vd2VleC9odG1sNS9mcmFtZXdvcmtzL2xlZ2FjeS9jb25maWcuanMiLCIuLi93ZWV4L2h0bWw1L2ZyYW1ld29ya3MvbGVnYWN5L3ZtL2RpcmVjdGl2ZS5qcyIsIi4uL3dlZXgvaHRtbDUvZnJhbWV3b3Jrcy9sZWdhY3kvdm0vZ
 
G9tLWhlbHBlci5qcyIsIi4uL3dlZXgvaHRtbDUvZnJhbWV3b3Jrcy9sZWdhY3kvdm0vY29tcGlsZXIuanMiLCIuLi93ZWV4L2h0bWw1L2ZyYW1ld29ya3MvbGVnYWN5L3ZtL2V2ZW50cy5qcyIsIi4uL3dlZXgvaHRtbDUvZnJhbWV3b3Jrcy9sZWdhY3kvdm0vaW5kZXguanMiLCIuLi93ZWV4L2h0bWw1L2ZyYW1ld29ya3MvbGVnYWN5L2FwcC9yZWdpc3Rlci5qcyIsIi4uL3dlZXgvbm9kZV9tb2R1bGVzL3NlbXZlci9zZW12ZXIuanMiLCIuLi93ZWV4L2h0bWw1L2ZyYW1ld29ya3MvbGVnYWN5L2FwcC9kb3duZ3JhZGUuanMiLCIuLi93ZWV4L2h0bWw1L2ZyYW1ld29ya3MvbGVnYWN5L2FwcC92aWV3cG9ydC5qcyIsIi4uL3dlZXgvaHRtbDUvZnJhbWV3b3Jrcy9sZWdhY3kvYXBwL2J1bmRsZS9ib290c3RyYXAuanMiLCIuLi93ZWV4L2h0bWw1L2ZyYW1ld29ya3MvbGVnYWN5L2FwcC9idW5kbGUvZGVmaW5lLmpzIiwiLi4vd2VleC9odG1sNS9mcmFtZXdvcmtzL2xlZ2FjeS9hcHAvYnVuZGxlL2luZGV4LmpzIiwiLi4vd2VleC9odG1sNS9mcmFtZXdvcmtzL2xlZ2FjeS9hcHAvY3RybC9taXNjLmpzIiwiLi4vd2VleC9odG1sNS9mcmFtZXdvcmtzL2xlZ2FjeS9hcHAvY3RybC9pbml0LmpzIiwiLi4vd2VleC9odG1sNS9mcmFtZXdvcmtzL2xlZ2FjeS9hcHAvY3RybC9pbmRleC5qcyIsIi4uL3dlZXgvaHRtbDUvZnJhbWV3b3Jrcy9sZWdhY3kvYXBwL2RpZmZlci5qcyIsIi4uL3dlZXgvaHRtbDUvZnJhbWV3b3Jrcy9sZWdhY3
 
kvYXBwL2luc3RhbmNlLmpzIiwiLi4vd2VleC9odG1sNS9mcmFtZXdvcmtzL2xlZ2FjeS9hcHAvaW5kZXguanMiLCIuLi93ZWV4L2h0bWw1L2ZyYW1ld29ya3MvbGVnYWN5L3N0YXRpYy9tYXAuanMiLCIuLi93ZWV4L2h0bWw1L2ZyYW1ld29ya3MvbGVnYWN5L3N0YXRpYy9jcmVhdGUuanMiLCIuLi93ZWV4L2h0bWw1L2ZyYW1ld29ya3MvbGVnYWN5L3N0YXRpYy9saWZlLmpzIiwiLi4vd2VleC9odG1sNS9mcmFtZXdvcmtzL2xlZ2FjeS9zdGF0aWMvcmVnaXN0ZXIuanMiLCIuLi93ZWV4L2h0bWw1L2ZyYW1ld29ya3MvbGVnYWN5L3N0YXRpYy9icmlkZ2UuanMiLCIuLi93ZWV4L2h0bWw1L2ZyYW1ld29ya3MvbGVnYWN5L3N0YXRpYy9taXNjLmpzIiwiLi4vd2VleC9odG1sNS9mcmFtZXdvcmtzL2xlZ2FjeS9pbmRleC5qcyIsIi4uLy4uL3dlZXgtcmF4LWZyYW1ld29yay9kaXN0L2ZyYW1ld29yay53ZWV4LmV2ZW50LmpzIiwiLi4vZnJhbWV3b3Jrcy5qcyIsIi4uL3dlZXgvaHRtbDUvc2hhcmVkL2FycmF5RnJvbS5qcyIsIi4uL3dlZXgvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZ2xvYmFsLmpzIiwiLi4vd2VleC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb3JlLmpzIiwiLi4vd2VleC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pcy1vYmplY3QuanMiLCIuLi93ZWV4L25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FuLW9iamVjdC5qcyIsIi4uL3dlZXgvbm9kZV9tb2R1bGVzL2N
 
vcmUtanMvbW9kdWxlcy9fZmFpbHMuanMiLCIuLi93ZWV4L25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2Rlc2NyaXB0b3JzLmpzIiwiLi4vd2VleC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19kb20tY3JlYXRlLmpzIiwiLi4vd2VleC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pZTgtZG9tLWRlZmluZS5qcyIsIi4uL3dlZXgvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8tcHJpbWl0aXZlLmpzIiwiLi4vd2VleC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZHAuanMiLCIuLi93ZWV4L25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3Byb3BlcnR5LWRlc2MuanMiLCIuLi93ZWV4L25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2hpZGUuanMiLCIuLi93ZWV4L25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2hhcy5qcyIsIi4uL3dlZXgvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdWlkLmpzIiwiLi4vd2VleC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19yZWRlZmluZS5qcyIsIi4uL3dlZXgvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYS1mdW5jdGlvbi5qcyIsIi4uL3dlZXgvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY3R4LmpzIiwiLi4vd2VleC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanMiLCIuLi93ZWV4L25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NvZi5q
 
cyIsIi4uL3dlZXgvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faW9iamVjdC5qcyIsIi4uL3dlZXgvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZGVmaW5lZC5qcyIsIi4uL3dlZXgvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8taW9iamVjdC5qcyIsIi4uL3dlZXgvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8taW50ZWdlci5qcyIsIi4uL3dlZXgvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8tbGVuZ3RoLmpzIiwiLi4vd2VleC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1hYnNvbHV0ZS1pbmRleC5qcyIsIi4uL3dlZXgvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktaW5jbHVkZXMuanMiLCIuLi93ZWV4L25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3NoYXJlZC5qcyIsIi4uL3dlZXgvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2hhcmVkLWtleS5qcyIsIi4uL3dlZXgvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWtleXMtaW50ZXJuYWwuanMiLCIuLi93ZWV4L25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2VudW0tYnVnLWtleXMuanMiLCIuLi93ZWV4L25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1rZXlzLmpzIiwiLi4vd2VleC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ29wcy5qcyIsIi4uL3dlZXgvbm9kZV9tb2R1bGVzL2NvcmUta
 
nMvbW9kdWxlcy9fb2JqZWN0LXBpZS5qcyIsIi4uL3dlZXgvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8tb2JqZWN0LmpzIiwiLi4vd2VleC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtYXNzaWduLmpzIiwiLi4vd2VleC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuYXNzaWduLmpzIiwiLi4vd2VleC9odG1sNS9zaGFyZWQvb2JqZWN0QXNzaWduLmpzIiwiLi4vd2VleC9odG1sNS9zaGFyZWQvb2JqZWN0U2V0UHJvdG90eXBlT2YuanMiLCIuLi93ZWV4L2h0bWw1L3NoYXJlZC9wcm9taXNlLmpzIiwiLi4vd2VleC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL193a3MuanMiLCIuLi93ZWV4L25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NsYXNzb2YuanMiLCIuLi93ZWV4L25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC50by1zdHJpbmcuanMiLCIuLi93ZWV4L25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy1hdC5qcyIsIi4uL3dlZXgvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbGlicmFyeS5qcyIsIi4uL3dlZXgvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXRlcmF0b3JzLmpzIiwiLi4vd2VleC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZHBzLmpzIiwiLi4vd2VleC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19odG1sLmpzIiwiLi4vd2VleC9ub2
 
RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtY3JlYXRlLmpzIiwiLi4vd2VleC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zZXQtdG8tc3RyaW5nLXRhZy5qcyIsIi4uL3dlZXgvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXRlci1jcmVhdGUuanMiLCIuLi93ZWV4L25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1ncG8uanMiLCIuLi93ZWV4L25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2l0ZXItZGVmaW5lLmpzIiwiLi4vd2VleC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuaXRlcmF0b3IuanMiLCIuLi93ZWV4L25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FkZC10by11bnNjb3BhYmxlcy5qcyIsIi4uL3dlZXgvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXRlci1zdGVwLmpzIiwiLi4vd2VleC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5pdGVyYXRvci5qcyIsIi4uL3dlZXgvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy93ZWIuZG9tLml0ZXJhYmxlLmpzIiwiLi4vd2VleC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hbi1pbnN0YW5jZS5qcyIsIi4uL3dlZXgvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXRlci1jYWxsLmpzIiwiLi4vd2VleC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pcy1hcnJheS1pdGVyLmpzIiwiLi4vd2VleC9ub2RlX21
 
vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2NvcmUuZ2V0LWl0ZXJhdG9yLW1ldGhvZC5qcyIsIi4uL3dlZXgvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZm9yLW9mLmpzIiwiLi4vd2VleC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zcGVjaWVzLWNvbnN0cnVjdG9yLmpzIiwiLi4vd2VleC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pbnZva2UuanMiLCIuLi93ZWV4L25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3Rhc2suanMiLCIuLi93ZWV4L25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX21pY3JvdGFzay5qcyIsIi4uL3dlZXgvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbmV3LXByb21pc2UtY2FwYWJpbGl0eS5qcyIsIi4uL3dlZXgvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcGVyZm9ybS5qcyIsIi4uL3dlZXgvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcHJvbWlzZS1yZXNvbHZlLmpzIiwiLi4vd2VleC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19yZWRlZmluZS1hbGwuanMiLCIuLi93ZWV4L25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3NldC1zcGVjaWVzLmpzIiwiLi4vd2VleC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyLWRldGVjdC5qcyIsIi4uL3dlZXgvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucHJvbWlzZS5qcyIsIi4uL3dlZXgvaHRtbDUvc2hhcmVkL2NvbnNvbGUuanMiLCIu
 
Li93ZWV4L2h0bWw1L3NoYXJlZC9zZXRUaW1lb3V0LmpzIiwiLi4vd2VleC9odG1sNS9zaGFyZWQvZnJlZXplLmpzIiwiLi4vd2VleC9odG1sNS9zaGFyZWQvaW5kZXguanMiLCIuLi93ZWV4L2h0bWw1L3J1bnRpbWUvdXRpbHMuanMiLCIuLi93ZWV4L2h0bWw1L3J1bnRpbWUvYnJpZGdlL25vcm1hbGl6ZS5qcyIsIi4uL3dlZXgvaHRtbDUvcnVudGltZS9icmlkZ2UvQ2FsbGJhY2tNYW5hZ2VyLmpzIiwiLi4vd2VleC9odG1sNS9ydW50aW1lL3Zkb20vb3BlcmF0aW9uLmpzIiwiLi4vd2VleC9odG1sNS9ydW50aW1lL3Zkb20vTm9kZS5qcyIsIi4uL3dlZXgvaHRtbDUvcnVudGltZS92ZG9tL1dlZXhFbGVtZW50LmpzIiwiLi4vd2VleC9odG1sNS9ydW50aW1lL3Zkb20vZGlyZWN0aXZlLmpzIiwiLi4vd2VleC9odG1sNS9ydW50aW1lL3Zkb20vRWxlbWVudC5qcyIsIi4uL3dlZXgvaHRtbDUvcnVudGltZS9icmlkZ2UvVGFza0NlbnRlci5qcyIsIi4uL3dlZXgvaHRtbDUvcnVudGltZS9hcGkvc2VydmljZS5qcyIsIi4uL3dlZXgvaHRtbDUvcnVudGltZS9hcGkvaW5pdC5qcyIsIi4uL3dlZXgvaHRtbDUvcnVudGltZS92ZG9tL0NvbW1lbnQuanMiLCIuLi93ZWV4L2h0bWw1L3J1bnRpbWUvYnJpZGdlL0xpc3RlbmVyLmpzIiwiLi4vd2VleC9odG1sNS9ydW50aW1lL2JyaWRnZS9IYW5kbGVyLmpzIiwiLi4vd2VleC9odG1sNS9ydW50aW1lL3Zkb20vRG9jdW1lbnQuanMiLCIuLi93ZWV4L2h0bWw1L3J1bnRpbWUvdmRvbS9pb
 
mRleC5qcyIsIi4uL3dlZXgvaHRtbDUvcnVudGltZS9hcGkvY29uZmlnLmpzIiwiLi4vd2VleC9odG1sNS9ydW50aW1lL2luZGV4LmpzIiwiLi4vd2VleC9odG1sNS9zZXJ2aWNlcy9icm9hZGNhc3QtY2hhbm5lbC9tZXNzYWdlLWV2ZW50LmpzIiwiLi4vd2VleC9odG1sNS9zZXJ2aWNlcy9icm9hZGNhc3QtY2hhbm5lbC9pbmRleC5qcyIsIi4uL3dlZXgvaHRtbDUvc2VydmljZXMvaW5kZXguanMiLCIuLi93ZWV4L2h0bWw1L3JlbmRlci9uYXRpdmUvc2V0dXAuanMiLCIuLi9saWIvYXBpL21ldGhvZHMuanMiLCIuLi9pbmRleC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZVxuICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlXG4gKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvblxuICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZVxuICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZVxuICogXCJMaWNlbnNlXCIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlXG4gKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaW
 
NlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsXG4gKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhblxuICogXCJBUyBJU1wiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTllcbiAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZVxuICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9uc1xuICogdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbmNvbnN0IGNvbmZpZyA9IHt9XG5cbmNvbnN0IGluc3RhbmNlTWFwID0ge31cblxuZXhwb3J0IGZ1bmN0aW9uIGluaXQgKGNmZykge1xuICBjb25maWcuRG9jdW1lbnQgPSBjZmcuRG9jdW1lbnRcbiAgY29uZmlnLkVsZW1lbnQgPSBjZmcuRWxlbWVudFxuICBjb25maWcuQ29tbWVudCA9IGNmZy5Db21tZW50XG4gIGNvbmZpZy5zZW5kVGFza3MgPSBjZmcuc2VuZFRhc2tzXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVJbnN0YW5jZSAoaWQsIGNvZGUsIG9wdGlvbnMgPSB7fSwgZGF0YSA9IHt9LCBzZXJ2aWNlT2JqZWN0cyA9IHt9KSB7XG4gIGNvbnN0IGRvY3VtZW50ID0gbmV3IGNvbmZpZy5Eb2N1bWV
 
udChpZCwgb3B0aW9ucy5idW5kbGVVcmwpXG4gIGNvbnN0IGNhbGxiYWNrcyA9IHt9XG4gIGNvbnN0IGluc3RhbmNlID0geyBpZCwgZGF0YSwgZG9jdW1lbnQsIGNhbGxiYWNrcyB9XG5cbiAgbGV0IGxhc3RDYWxsYmFja0lkID0gMFxuICBkb2N1bWVudC5hZGRDYWxsYmFjayA9IGZ1bmMgPT4ge1xuICAgIGxhc3RDYWxsYmFja0lkKytcbiAgICBjYWxsYmFja3NbbGFzdENhbGxiYWNrSWRdID0gZnVuY1xuICAgIHJldHVybiBsYXN0Q2FsbGJhY2tJZFxuICB9XG4gIGRvY3VtZW50LmhhbmRsZUNhbGxiYWNrID0gKGZ1bmNJZCwgZGF0YSwgaWZMYXN0KSA9PiB7XG4gICAgY29uc3QgY2FsbGJhY2sgPSBjYWxsYmFja3NbZnVuY0lkXVxuICAgIGlmIChpZkxhc3QpIHtcbiAgICAgIGRlbGV0ZSBjYWxsYmFja3NbZnVuY0lkXVxuICAgIH1cbiAgICByZXR1cm4gY2FsbGJhY2soZGF0YSlcbiAgfVxuICBpbnN0YW5jZU1hcFtpZF0gPSBpbnN0YW5jZVxuXG4gIGNvbnN0IGdsb2JhbE9iamVjdHMgPSBPYmplY3QuYXNzaWduKHtcbiAgICBEb2N1bWVudDogY29uZmlnLkRvY3VtZW50LFxuICAgIEVsZW1lbnQ6IGNvbmZpZy5FbGVtZW50LFxuICAgIENvbW1lbnQ6IGNvbmZpZy5Db21tZW50LFxuICAgIHNlbmRUYXNrczogdGFza3MgPT4gY29uZmlnLnNlbmRUYXNrcyhpZCwgdGFza3MsIC0xKSxcbiAgICBvcHRpb25zLFxuICAgIGRvY3VtZW50XG4gIH0sIHNlcnZpY2VPYmplY3RzKVxuXG4gIGNvbnN0IGdsb2JhbEtleXMgPSBbXVxu
 
ICBjb25zdCBnbG9iYWxWYWx1ZXMgPSBbXVxuICBmb3IgKGNvbnN0IGtleSBpbiBnbG9iYWxPYmplY3RzKSB7XG4gICAgZ2xvYmFsS2V5cy5wdXNoKGtleSlcbiAgICBnbG9iYWxWYWx1ZXMucHVzaChnbG9iYWxPYmplY3RzW2tleV0pXG4gIH1cbiAgZ2xvYmFsS2V5cy5wdXNoKGNvZGUpXG5cbiAgY29uc3QgcmVzdWx0ID0gbmV3IEZ1bmN0aW9uKC4uLmdsb2JhbEtleXMpXG4gIHJlc3VsdCguLi5nbG9iYWxWYWx1ZXMpXG5cbiAgY29uZmlnLnNlbmRUYXNrcyhpZCwgW3sgbW9kdWxlOiAnZG9tJywgbWV0aG9kOiAnY3JlYXRlRmluaXNoJywgYXJnczogW10gfV0sIC0xKVxuXG4gIHJldHVybiBpbnN0YW5jZVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZGVzdHJveUluc3RhbmNlIChpZCkge1xuICBkZWxldGUgaW5zdGFuY2VNYXBbaWRdXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRSb290IChpZCkge1xuICByZXR1cm4gaW5zdGFuY2VNYXBbaWRdLmRvY3VtZW50LmJvZHkudG9KU09OKClcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlY2VpdmVUYXNrcyAoaWQsIHRhc2tzKSB7XG4gIGNvbnN0IGpzSGFuZGxlcnMgPSB7XG4gICAgZmlyZUV2ZW50OiAoaWQsIHJlZiwgdHlwZSwgZGF0YSwgZG9tQ2hhbmdlcykgPT4ge1xuICAgICAgY29uc3QgeyBkb2N1bWVudCB9ID0gaW5zdGFuY2VNYXBbaWRdXG4gICAgICBjb25zdCBlbCA9IGRvY3VtZW50LmdldFJlZihyZWYpXG4gICAgICByZXR1cm4gZG9jdW1lbnQuZmlyZUV2ZW50KGVsL
 
CB0eXBlLCBkYXRhLCBkb21DaGFuZ2VzKVxuICAgIH0sXG5cbiAgICBjYWxsYmFjazogKGlkLCBmdW5jSWQsIGRhdGEsIGlmTGFzdCkgPT4ge1xuICAgICAgY29uc3QgeyBkb2N1bWVudCB9ID0gaW5zdGFuY2VNYXBbaWRdXG4gICAgICByZXR1cm4gZG9jdW1lbnQuaGFuZGxlQ2FsbGJhY2soZnVuY0lkLCBkYXRhLCBpZkxhc3QpXG4gICAgfVxuICB9XG5cbiAgY29uc3QgeyBkb2N1bWVudCB9ID0gaW5zdGFuY2VNYXBbaWRdIHx8IHt9XG4gIGlmIChkb2N1bWVudCAmJiBBcnJheS5pc0FycmF5KHRhc2tzKSkge1xuICAgIGNvbnN0IHJlc3VsdHMgPSBbXVxuICAgIHRhc2tzLmZvckVhY2goKHRhc2spID0+IHtcbiAgICAgIGNvbnN0IGhhbmRsZXIgPSBqc0hhbmRsZXJzW3Rhc2subWV0aG9kXVxuICAgICAgY29uc3QgYXJncyA9IFsuLi50YXNrLmFyZ3NdXG4gICAgICBpZiAodHlwZW9mIGhhbmRsZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgYXJncy51bnNoaWZ0KGlkKVxuICAgICAgICByZXN1bHRzLnB1c2goaGFuZGxlciguLi5hcmdzKSlcbiAgICAgIH1cbiAgICB9KVxuICAgIHJldHVybiByZXN1bHRzXG4gIH1cbn1cbiIsIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiB3ZWV4RmFjdG9yeSAoZXhwb3J0cywgcmVuZGVyZXIpIHtcblxuLyogICovXG5cbi8vIHRoZXNlIGhlbHBlcnMgcHJvZHVjZXMgYmV0dGVyIHZtIGNvZGUgaW4gSlMgZW5naW5lcyBkdWUgdG8gdGhlaXJcbi8vIG
 
V4cGxpY2l0bmVzcyBhbmQgZnVuY3Rpb24gaW5saW5pbmdcbmZ1bmN0aW9uIGlzVW5kZWYgKHYpIHtcbiAgcmV0dXJuIHYgPT09IHVuZGVmaW5lZCB8fCB2ID09PSBudWxsXG59XG5cbmZ1bmN0aW9uIGlzRGVmICh2KSB7XG4gIHJldHVybiB2ICE9PSB1bmRlZmluZWQgJiYgdiAhPT0gbnVsbFxufVxuXG5mdW5jdGlvbiBpc1RydWUgKHYpIHtcbiAgcmV0dXJuIHYgPT09IHRydWVcbn1cblxuZnVuY3Rpb24gaXNGYWxzZSAodikge1xuICByZXR1cm4gdiA9PT0gZmFsc2Vcbn1cblxuLyoqXG4gKiBDaGVjayBpZiB2YWx1ZSBpcyBwcmltaXRpdmVcbiAqL1xuZnVuY3Rpb24gaXNQcmltaXRpdmUgKHZhbHVlKSB7XG4gIHJldHVybiAoXG4gICAgdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyB8fFxuICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgfHxcbiAgICB0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJ1xuICApXG59XG5cbi8qKlxuICogUXVpY2sgb2JqZWN0IGNoZWNrIC0gdGhpcyBpcyBwcmltYXJpbHkgdXNlZCB0byB0ZWxsXG4gKiBPYmplY3RzIGZyb20gcHJpbWl0aXZlIHZhbHVlcyB3aGVuIHdlIGtub3cgdGhlIHZhbHVlXG4gKiBpcyBhIEpTT04tY29tcGxpYW50IHR5cGUuXG4gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0IChvYmopIHtcbiAgcmV0dXJuIG9iaiAhPT0gbnVsbCAmJiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0J1xufVxuXG52YXIgX3RvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcblx
 
uLyoqXG4gKiBTdHJpY3Qgb2JqZWN0IHR5cGUgY2hlY2suIE9ubHkgcmV0dXJucyB0cnVlXG4gKiBmb3IgcGxhaW4gSmF2YVNjcmlwdCBvYmplY3RzLlxuICovXG5mdW5jdGlvbiBpc1BsYWluT2JqZWN0IChvYmopIHtcbiAgcmV0dXJuIF90b1N0cmluZy5jYWxsKG9iaikgPT09ICdbb2JqZWN0IE9iamVjdF0nXG59XG5cbmZ1bmN0aW9uIGlzUmVnRXhwICh2KSB7XG4gIHJldHVybiBfdG9TdHJpbmcuY2FsbCh2KSA9PT0gJ1tvYmplY3QgUmVnRXhwXSdcbn1cblxuLyoqXG4gKiBDaGVjayBpZiB2YWwgaXMgYSB2YWxpZCBhcnJheSBpbmRleC5cbiAqL1xuZnVuY3Rpb24gaXNWYWxpZEFycmF5SW5kZXggKHZhbCkge1xuICB2YXIgbiA9IHBhcnNlRmxvYXQodmFsKTtcbiAgcmV0dXJuIG4gPj0gMCAmJiBNYXRoLmZsb29yKG4pID09PSBuICYmIGlzRmluaXRlKHZhbClcbn1cblxuLyoqXG4gKiBDb252ZXJ0IGEgdmFsdWUgdG8gYSBzdHJpbmcgdGhhdCBpcyBhY3R1YWxseSByZW5kZXJlZC5cbiAqL1xuZnVuY3Rpb24gdG9TdHJpbmcgKHZhbCkge1xuICByZXR1cm4gdmFsID09IG51bGxcbiAgICA/ICcnXG4gICAgOiB0eXBlb2YgdmFsID09PSAnb2JqZWN0J1xuICAgICAgPyBKU09OLnN0cmluZ2lmeSh2YWwsIG51bGwsIDIpXG4gICAgICA6IFN0cmluZyh2YWwpXG59XG5cbi8qKlxuICogQ29udmVydCBhIGlucHV0IHZhbHVlIHRvIGEgbnVtYmVyIGZvciBwZXJzaXN0ZW5jZS5cbiAqIElmIHRoZSBjb252ZXJzaW9uIGZhaWxz
 
LCByZXR1cm4gb3JpZ2luYWwgc3RyaW5nLlxuICovXG5mdW5jdGlvbiB0b051bWJlciAodmFsKSB7XG4gIHZhciBuID0gcGFyc2VGbG9hdCh2YWwpO1xuICByZXR1cm4gaXNOYU4obikgPyB2YWwgOiBuXG59XG5cbi8qKlxuICogTWFrZSBhIG1hcCBhbmQgcmV0dXJuIGEgZnVuY3Rpb24gZm9yIGNoZWNraW5nIGlmIGEga2V5XG4gKiBpcyBpbiB0aGF0IG1hcC5cbiAqL1xuZnVuY3Rpb24gbWFrZU1hcCAoXG4gIHN0cixcbiAgZXhwZWN0c0xvd2VyQ2FzZVxuKSB7XG4gIHZhciBtYXAgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICB2YXIgbGlzdCA9IHN0ci5zcGxpdCgnLCcpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICBtYXBbbGlzdFtpXV0gPSB0cnVlO1xuICB9XG4gIHJldHVybiBleHBlY3RzTG93ZXJDYXNlXG4gICAgPyBmdW5jdGlvbiAodmFsKSB7IHJldHVybiBtYXBbdmFsLnRvTG93ZXJDYXNlKCldOyB9XG4gICAgOiBmdW5jdGlvbiAodmFsKSB7IHJldHVybiBtYXBbdmFsXTsgfVxufVxuXG4vKipcbiAqIENoZWNrIGlmIGEgdGFnIGlzIGEgYnVpbHQtaW4gdGFnLlxuICovXG52YXIgaXNCdWlsdEluVGFnID0gbWFrZU1hcCgnc2xvdCxjb21wb25lbnQnLCB0cnVlKTtcblxuLyoqXG4gKiBDaGVjayBpZiBhIGF0dHJpYnV0ZSBpcyBhIHJlc2VydmVkIGF0dHJpYnV0ZS5cbiAqL1xudmFyIGlzUmVzZXJ2ZWRBdHRyaWJ1dGUgPSBtYWtlTWFwKCdrZXkscmVmLHNsb3QsaXMnK
 
TtcblxuLyoqXG4gKiBSZW1vdmUgYW4gaXRlbSBmcm9tIGFuIGFycmF5XG4gKi9cbmZ1bmN0aW9uIHJlbW92ZSAoYXJyLCBpdGVtKSB7XG4gIGlmIChhcnIubGVuZ3RoKSB7XG4gICAgdmFyIGluZGV4ID0gYXJyLmluZGV4T2YoaXRlbSk7XG4gICAgaWYgKGluZGV4ID4gLTEpIHtcbiAgICAgIHJldHVybiBhcnIuc3BsaWNlKGluZGV4LCAxKVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIENoZWNrIHdoZXRoZXIgdGhlIG9iamVjdCBoYXMgdGhlIHByb3BlcnR5LlxuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuZnVuY3Rpb24gaGFzT3duIChvYmosIGtleSkge1xuICByZXR1cm4gaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSlcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBjYWNoZWQgdmVyc2lvbiBvZiBhIHB1cmUgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNhY2hlZCAoZm4pIHtcbiAgdmFyIGNhY2hlID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgcmV0dXJuIChmdW5jdGlvbiBjYWNoZWRGbiAoc3RyKSB7XG4gICAgdmFyIGhpdCA9IGNhY2hlW3N0cl07XG4gICAgcmV0dXJuIGhpdCB8fCAoY2FjaGVbc3RyXSA9IGZuKHN0cikpXG4gIH0pXG59XG5cbi8qKlxuICogQ2FtZWxpemUgYSBoeXBoZW4tZGVsaW1pdGVkIHN0cmluZy5cbiAqL1xudmFyIGNhbWVsaXplUkUgPSAvLShcXHcpL2c7XG52YXIgY2FtZWxpemUgPSBjYWNoZWQoZnVuY3Rpb24gKHN0ci
 
kge1xuICByZXR1cm4gc3RyLnJlcGxhY2UoY2FtZWxpemVSRSwgZnVuY3Rpb24gKF8sIGMpIHsgcmV0dXJuIGMgPyBjLnRvVXBwZXJDYXNlKCkgOiAnJzsgfSlcbn0pO1xuXG4vKipcbiAqIENhcGl0YWxpemUgYSBzdHJpbmcuXG4gKi9cbnZhciBjYXBpdGFsaXplID0gY2FjaGVkKGZ1bmN0aW9uIChzdHIpIHtcbiAgcmV0dXJuIHN0ci5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHN0ci5zbGljZSgxKVxufSk7XG5cbi8qKlxuICogSHlwaGVuYXRlIGEgY2FtZWxDYXNlIHN0cmluZy5cbiAqL1xudmFyIGh5cGhlbmF0ZVJFID0gL1xcQihbQS1aXSkvZztcbnZhciBoeXBoZW5hdGUgPSBjYWNoZWQoZnVuY3Rpb24gKHN0cikge1xuICByZXR1cm4gc3RyLnJlcGxhY2UoaHlwaGVuYXRlUkUsICctJDEnKS50b0xvd2VyQ2FzZSgpXG59KTtcblxuLyoqXG4gKiBTaW1wbGUgYmluZCwgZmFzdGVyIHRoYW4gbmF0aXZlXG4gKi9cbmZ1bmN0aW9uIGJpbmQgKGZuLCBjdHgpIHtcbiAgZnVuY3Rpb24gYm91bmRGbiAoYSkge1xuICAgIHZhciBsID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICByZXR1cm4gbFxuICAgICAgPyBsID4gMVxuICAgICAgICA/IGZuLmFwcGx5KGN0eCwgYXJndW1lbnRzKVxuICAgICAgICA6IGZuLmNhbGwoY3R4LCBhKVxuICAgICAgOiBmbi5jYWxsKGN0eClcbiAgfVxuICAvLyByZWNvcmQgb3JpZ2luYWwgZm4gbGVuZ3RoXG4gIGJvdW5kRm4uX2xlbmd0aCA9IGZuLmxlbmd0aDtcbiAgcmV0dXJuIGJvdW5kRm5
 
cbn1cblxuLyoqXG4gKiBDb252ZXJ0IGFuIEFycmF5LWxpa2Ugb2JqZWN0IHRvIGEgcmVhbCBBcnJheS5cbiAqL1xuZnVuY3Rpb24gdG9BcnJheSAobGlzdCwgc3RhcnQpIHtcbiAgc3RhcnQgPSBzdGFydCB8fCAwO1xuICB2YXIgaSA9IGxpc3QubGVuZ3RoIC0gc3RhcnQ7XG4gIHZhciByZXQgPSBuZXcgQXJyYXkoaSk7XG4gIHdoaWxlIChpLS0pIHtcbiAgICByZXRbaV0gPSBsaXN0W2kgKyBzdGFydF07XG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG4vKipcbiAqIE1peCBwcm9wZXJ0aWVzIGludG8gdGFyZ2V0IG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gZXh0ZW5kICh0bywgX2Zyb20pIHtcbiAgZm9yICh2YXIga2V5IGluIF9mcm9tKSB7XG4gICAgdG9ba2V5XSA9IF9mcm9tW2tleV07XG4gIH1cbiAgcmV0dXJuIHRvXG59XG5cbi8qKlxuICogTWVyZ2UgYW4gQXJyYXkgb2YgT2JqZWN0cyBpbnRvIGEgc2luZ2xlIE9iamVjdC5cbiAqL1xuZnVuY3Rpb24gdG9PYmplY3QgKGFycikge1xuICB2YXIgcmVzID0ge307XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGFycltpXSkge1xuICAgICAgZXh0ZW5kKHJlcywgYXJyW2ldKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG4vKipcbiAqIFBlcmZvcm0gbm8gb3BlcmF0aW9uLlxuICogU3R1YmJpbmcgYXJncyB0byBtYWtlIEZsb3cgaGFwcHkgd2l0aG91dCBsZWF2aW5nIHVzZWxlc3MgdHJhbnNwaWxlZCBjb2RlXG4g
 
KiB3aXRoIC4uLnJlc3QgKGh0dHBzOi8vZmxvdy5vcmcvYmxvZy8yMDE3LzA1LzA3L1N0cmljdC1GdW5jdGlvbi1DYWxsLUFyaXR5LylcbiAqL1xuZnVuY3Rpb24gbm9vcCAoYSwgYiwgYykge31cblxuLyoqXG4gKiBBbHdheXMgcmV0dXJuIGZhbHNlLlxuICovXG52YXIgbm8gPSBmdW5jdGlvbiAoYSwgYiwgYykgeyByZXR1cm4gZmFsc2U7IH07XG5cbi8qKlxuICogUmV0dXJuIHNhbWUgdmFsdWVcbiAqL1xudmFyIGlkZW50aXR5ID0gZnVuY3Rpb24gKF8pIHsgcmV0dXJuIF87IH07XG5cbi8qKlxuICogR2VuZXJhdGUgYSBzdGF0aWMga2V5cyBzdHJpbmcgZnJvbSBjb21waWxlciBtb2R1bGVzLlxuICovXG5cblxuLyoqXG4gKiBDaGVjayBpZiB0d28gdmFsdWVzIGFyZSBsb29zZWx5IGVxdWFsIC0gdGhhdCBpcyxcbiAqIGlmIHRoZXkgYXJlIHBsYWluIG9iamVjdHMsIGRvIHRoZXkgaGF2ZSB0aGUgc2FtZSBzaGFwZT9cbiAqL1xuZnVuY3Rpb24gbG9vc2VFcXVhbCAoYSwgYikge1xuICBpZiAoYSA9PT0gYikgeyByZXR1cm4gdHJ1ZSB9XG4gIHZhciBpc09iamVjdEEgPSBpc09iamVjdChhKTtcbiAgdmFyIGlzT2JqZWN0QiA9IGlzT2JqZWN0KGIpO1xuICBpZiAoaXNPYmplY3RBICYmIGlzT2JqZWN0Qikge1xuICAgIHRyeSB7XG4gICAgICB2YXIgaXNBcnJheUEgPSBBcnJheS5pc0FycmF5KGEpO1xuICAgICAgdmFyIGlzQXJyYXlCID0gQXJyYXkuaXNBcnJheShiKTtcbiAgICAgIGlmIChpc0FycmF5QSAmJiBpc0Fyc
 
mF5Qikge1xuICAgICAgICByZXR1cm4gYS5sZW5ndGggPT09IGIubGVuZ3RoICYmIGEuZXZlcnkoZnVuY3Rpb24gKGUsIGkpIHtcbiAgICAgICAgICByZXR1cm4gbG9vc2VFcXVhbChlLCBiW2ldKVxuICAgICAgICB9KVxuICAgICAgfSBlbHNlIGlmICghaXNBcnJheUEgJiYgIWlzQXJyYXlCKSB7XG4gICAgICAgIHZhciBrZXlzQSA9IE9iamVjdC5rZXlzKGEpO1xuICAgICAgICB2YXIga2V5c0IgPSBPYmplY3Qua2V5cyhiKTtcbiAgICAgICAgcmV0dXJuIGtleXNBLmxlbmd0aCA9PT0ga2V5c0IubGVuZ3RoICYmIGtleXNBLmV2ZXJ5KGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgICByZXR1cm4gbG9vc2VFcXVhbChhW2tleV0sIGJba2V5XSlcbiAgICAgICAgfSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gIH0gZWxzZSBpZiAoIWlzT2JqZWN0QSAmJiAhaXNPYmplY3RCKSB7XG4gICAgcmV0dXJuIFN0cmluZyhhKSA9PT0gU3RyaW5nKGIpXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuZnVuY3Rpb24gbG9vc2VJbmRleE9mIChhcnIsIHZhbCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgIGlmIChsb2
 
9zZUVxdWFsKGFycltpXSwgdmFsKSkgeyByZXR1cm4gaSB9XG4gIH1cbiAgcmV0dXJuIC0xXG59XG5cbi8qKlxuICogRW5zdXJlIGEgZnVuY3Rpb24gaXMgY2FsbGVkIG9ubHkgb25jZS5cbiAqL1xuZnVuY3Rpb24gb25jZSAoZm4pIHtcbiAgdmFyIGNhbGxlZCA9IGZhbHNlO1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIGlmICghY2FsbGVkKSB7XG4gICAgICBjYWxsZWQgPSB0cnVlO1xuICAgICAgZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG4gIH1cbn1cblxudmFyIFNTUl9BVFRSID0gJ2RhdGEtc2VydmVyLXJlbmRlcmVkJztcblxudmFyIEFTU0VUX1RZUEVTID0gW1xuICAnY29tcG9uZW50JyxcbiAgJ2RpcmVjdGl2ZScsXG4gICdmaWx0ZXInXG5dO1xuXG52YXIgT

<TRUNCATED>

Reply via email to