";throw c}}y.exec=y,S.options=S.setOptions=function(e){return w(S.defaults,e),S},S.getDefaults=function(){return{baseUrl:null,breaks:!1,gfm:!0,headerIds:!0,headerPrefix:"",highlight:null,langPrefix:"language-",mangle:!0,pedantic:!1,renderer:new u,sanitize:!1,sanitizer:null,silent:!1,smartLists:!1,smartypants:!1,tables:!0,xhtml:!1}},S.defaults=S.getDefaults(),S.Parser=h,S.parser=h.parse,S.Renderer=u,S.TextRenderer=p,S.Lexer=a,S.lexer=a.lex,S.InlineLexer=c,S.inlineLexer=c.output,S.Slugger=g,S.parse=S,"object"===o(t)?e.exports=S:void 0===(i=function(){return S}.call(t,n,t,e))||(e.exports=i)}(this||"undefined"!=typeof window&&window)}).call(this,n(125))},125:function(e,t){function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var r;r=function(){return this}();try{r=r||new Function("return this")()}catch(i){"object"===("undefined"==typeof window?"undefined":n(window))&&(r=window)}e.exports=r},126:function(e,t,n){var r=n(103),i=n(106),o=n(129);function s(e,t){return new o(t).process(e)}for(var a in(t=e.exports=s).filterXSS=s,t.FilterXSS=o,r)t[a]=r[a];for(var a in i)t[a]=i[a];"undefined"!=typeof window&&(window.filterXSS=e.exports),"undefined"!=typeof self&&"undefined"!=typeof DedicatedWorkerGlobalScope&&self instanceof DedicatedWorkerGlobalScope&&(self.filterXSS=e.exports)},127:function(e,t,n){var r=n(104),i=n(128);n(105);function o(e){return null==e}function s(e){(e=function(e){var t={};for(var n in e)t[n]=e[n];return t}(e||{})).whiteList=e.whiteList||r.whiteList,e.onAttr=e.onAttr||r.onAttr,e.onIgnoreAttr=e.onIgnoreAttr||r.onIgnoreAttr,e.safeAttrValue=e.safeAttrValue||r.safeAttrValue,this.options=e}s.prototype.process=function(e){if(!(e=(e=e||"").toString()))return"";var t=this.options,n=t.whiteList,r=t.onAttr,s=t.onIgnoreAttr,a=t.safeAttrValue;return i(e,function(e,t,i,l,c){var u=n[i],p=!1;if(!0===u?p=u:"function"==typeof u?p=u(l):u instanceof RegExp&&(p=u.test(l)),!0!==p&&(p=!1),l=a(i,l)){var h,g={position:t,sourcePosition:e,source:c,isWhite:p};return p?o(h=r(i,l,g))?i+":"+l:h:o(h=s(i,l,g))?void 0:h}})},e.exports=s},128:function(e,t,n){var r=n(105);e.exports=function(e,t){";"!==(e=r.trimRight(e))[e.length-1]&&(e+=";");var n=e.length,i=!1,o=0,s=0,a="";function l(){if(!i){var n=r.trim(e.slice(o,s)),l=n.indexOf(":");if(-1!==l){var c=r.trim(n.slice(0,l)),u=r.trim(n.slice(l+1));if(c){var p=t(o,a.length,c,u,n);p&&(a+=p+"; ")}}}o=s+1}for(;s";var x=function(e){var t=l.spaceIndex(e);if(-1===t)return{html:"",closing:"/"===e[e.length-2]};var n="/"===(e=l.trim(e.slice(t+1,-1)))[e.length-1];return n&&(e=l.trim(e.slice(0,-1))),{html:e,closing:n}}(s),k=n[i],y=a(x.html,function(e,t){var n,r=-1!==l.indexOf(k,e);return c(n=u(i,e,t,r))?r?(t=h(i,e,t,f))?e+'="'+t+'"':e:c(n=p(i,e,t,r))?void 0:n:n});s="<"+i;return y&&(s+=" "+y),x.closing&&(s+=" /"),s+=">"}return c(m=o(i,s,b))?g(s):m},g);return d&&(m=d.remove(m)),m},e.exports=u},73:function(e,t,n){var r=n(104),i=n(127);for(var o in(t=e.exports=function(e,t){return new i(t).process(e)}).FilterCSS=i,r)t[o]=r[o];"undefined"!=typeof window&&(window.filterCSS=e.exports)},74:function(e,t){e.exports={indexOf:function(e,t){var n,r;if(Array.prototype.indexOf)return e.indexOf(t);for(n=0,r=e.length;n\n \n \n "]);return l=function(){return e},e}function u(){var e=f(["\n \n "]);return u=function(){return e},e}function f(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function d(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function p(e,t){return(p=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function h(e){var t,r=w(e.key);"method"===e.kind?t={value:e.value,writable:!0,configurable:!0,enumerable:!1}:"get"===e.kind?t={get:e.value,configurable:!0,enumerable:!1}:"set"===e.kind?t={set:e.value,configurable:!0,enumerable:!1}:"field"===e.kind&&(t={configurable:!0,writable:!0,enumerable:!0});var n={kind:"field"===e.kind?"field":"method",key:r,placement:e.static?"static":"field"===e.kind?"own":"prototype",descriptor:t};return e.decorators&&(n.decorators=e.decorators),"field"===e.kind&&(n.initializer=e.value),n}function m(e,t){void 0!==e.descriptor.get?t.descriptor.get=e.descriptor.get:t.descriptor.set=e.descriptor.set}function y(e){return e.decorators&&e.decorators.length}function v(e){return void 0!==e&&!(void 0===e.value&&void 0===e.writable)}function b(e,t){var r=e[t];if(void 0!==r&&"function"!=typeof r)throw new TypeError("Expected '"+t+"' to be a function");return r}function w(e){var t=function(e,t){if("object"!==o(e)||null===e)return e;var r=e[Symbol.toPrimitive];if(void 0!==r){var n=r.call(e,t||"default");if("object"!==o(n))return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===o(t)?t:String(t)}function k(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}function g(e){if(Array.isArray(e))return e}function E(e,t,r){return(E="undefined"!=typeof Reflect&&Reflect.get?Reflect.get:function(e,t,r){var n=function(e,t){for(;!Object.prototype.hasOwnProperty.call(e,t)&&null!==(e=O(e)););return e}(e,t);if(n){var i=Object.getOwnPropertyDescriptor(n,t);return i.get?i.get.call(r):i.value}})(e,t,r||e)}function O(e){return(O=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}!function(e,t,r,n){var i=function(){var e={elementsDefinitionOrder:[["method"],["field"]],initializeInstanceElements:function(e,t){["method","field"].forEach(function(r){t.forEach(function(t){t.kind===r&&"own"===t.placement&&this.defineClassElement(e,t)},this)},this)},initializeClassElements:function(e,t){var r=e.prototype;["method","field"].forEach(function(n){t.forEach(function(t){var i=t.placement;if(t.kind===n&&("static"===i||"prototype"===i)){var o="static"===i?e:r;this.defineClassElement(o,t)}},this)},this)},defineClassElement:function(e,t){var r=t.descriptor;if("field"===t.kind){var n=t.initializer;r={enumerable:r.enumerable,writable:r.writable,configurable:r.configurable,value:void 0===n?void 0:n.call(e)}}Object.defineProperty(e,t.key,r)},decorateClass:function(e,t){var r=[],n=[],i={static:[],prototype:[],own:[]};if(e.forEach(function(e){this.addElementPlacement(e,i)},this),e.forEach(function(e){if(!y(e))return r.push(e);var t=this.decorateElement(e,i);r.push(t.element),r.push.apply(r,t.extras),n.push.apply(n,t.finishers)},this),!t)return{elements:r,finishers:n};var o=this.decorateConstructor(r,t);return n.push.apply(n,o.finishers),o.finishers=n,o},addElementPlacement:function(e,t,r){var n=t[e.placement];if(!r&&-1!==n.indexOf(e.key))throw new TypeError("Duplicated element ("+e.key+")");n.push(e.key)},decorateElement:function(e,t){for(var r=[],n=[],i=e.decorators,o=i.length-1;o>=0;o--){var s=t[e.placement];s.splice(s.indexOf(e.key),1);var a=this.fromElementDescriptor(e),c=this.toElementFinisherExtras((0,i[o])(a)||a);e=c.element,this.addElementPlacement(e,t),c.finisher&&n.push(c.finisher);var l=c.extras;if(l){for(var u=0;u=0;n--){var i=this.fromClassDescriptor(e),o=this.toClassDescriptor((0,t[n])(i)||i);if(void 0!==o.finisher&&r.push(o.finisher),void 0!==o.elements){e=o.elements;for(var s=0;s can only be templatized once");t.__templatizeOwner=e;var r=(e?e.constructor:N)._parseTemplate(t),o=r.templatizeInstanceClass;o||(o=M(t,r,n),r.templatizeInstanceClass=o),L(t,r,n);var i=function(t){function e(){return C(this,e),g(this,P(e).apply(this,arguments))}return k(e,o),e}();return i.prototype._methodHost=I(t),i.prototype.__dataHost=t,i.prototype.__templatizeOwner=e,i.prototype.__hostProps=r.hostProps,i=i}function z(t,e){for(var n;e;)if(n=e.__templatizeInstance){if(n.__dataHost==t)return n;e=n.__dataHost}else e=e.parentNode;return null}var B=n(84);function q(t){return(q="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function Y(t,e){return!e||"object"!==q(e)&&"function"!=typeof e?function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t):e}function V(t){return(V=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function U(t,e){for(var n=0;n child");n.disconnect(),e.render()});return void n.observe(this,{childList:!0})}this.root=this._stampTemplate(t),this.$=this.root.$,this.__children=[];for(var r=this.root.firstChild;r;r=r.nextSibling)this.__children[this.__children.length]=r;this._enableProperties()}this.__insertChildren(),this.dispatchEvent(new CustomEvent("dom-change",{bubbles:!0,composed:!0}))}}]),e}();customElements.define("dom-bind",G);var W=n(9),K=n(27),Z=n(32),Q=n(45),tt=n(23);function et(t){return(et="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function nt(t,e){return!e||"object"!==et(e)&&"function"!=typeof e?function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t):e}function rt(t,e,n){return(rt="undefined"!=typeof Reflect&&Reflect.get?Reflect.get:function(t,e,n){var r=function(t,e){for(;!Object.prototype.hasOwnProperty.call(t,e)&&null!==(t=ot(t)););return t}(t,e);if(r){var o=Object.getOwnPropertyDescriptor(r,e);return o.get?o.get.call(n):o.value}})(t,e,n||t)}function ot(t){return(ot=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function it(t,e){for(var n=0;n child");n.disconnect(),t.__render()});return n.observe(this,{childList:!0}),!1}var r={};r[this.as]=!0,r[this.indexAs]=!0,r[this.itemsIndexAs]=!0,this.__ctor=H(e,this,{mutableData:this.mutableData,parentModel:!0,instanceProps:r,forwardHostProp:function(t,e){for(var n,r=this.__instances,o=0;o1&&void 0!==arguments[1]?arguments[1]:0;this.__renderDebouncer=K.a.debounce(this.__renderDebouncer,e>0?tt.c.after(e):tt.b,t.bind(this)),Object(Z.a)(this.__renderDebouncer)}},{key:"render",value:function(){this.__debounceRender(this.__render),Object(Z.b)()}},{key:"__render",value:function(){this.__ensureTemplatized()&&(this.__applyFullRefresh(),this.__pool.length=0,this._setRenderedItemCount(this.__instances.length),this.dispatchEvent(new CustomEvent("dom-change",{bubbles:!0,composed:!0})),this.__tryRenderChunk())}},{key:"__applyFullRefresh",value:function(){for(var t=this,e=this.items||[],n=new Array(e.length),r=0;r=i;l--)this.__detachAndRemoveInstance(l)}},{key:"__detachInstance",value:function(t){for(var e=this.__instances[t],n=0;n child");r.disconnect(),t.__render()});return r.observe(this,{childList:!0}),!1}this.__ctor=H(n,this,{mutableData:!0,forwardHostProp:function(t,e){this.__instance&&(this.if?this.__instance.forwardHostProp(t,e):(this.__invalidProps=this.__invalidProps||Object.create(null),this.__invalidProps[Object(Q.g)(t)]=!0))}})}if(this.__instance){this.__syncHostProperties();var o=this.__instance.children;if(o&&o.length)if(this.previousSibling!==o[o.length-1])for(var i,a=0;a=o.index+o.removed.length?n.set(e,t+o.addedCount-o.removed.length):n.set(e,-1))});for(var i=0;i=0&&t.linkPaths("items."+n,"selected."+e++)})}else this.__selectedMap.forEach(function(e){t.linkPaths("selected","items."+e),t.linkPaths("selectedItem","items."+e)})}},{key:"clearSelection",value:function(){this.__dataLinkedPaths={},this.__selectedMap=new Map,this.selected=this.multi?[]:null,this.selectedItem=null}},{key:"isSelected",value:function(t){return this.__selectedMap.has(t)}},{key:"isIndexSelected",value:function(t){return this.isSelected(this.items[t])}},{key:"__deselectChangedIdx",value:function(t){var e=this,n=this.__selectedIndexForItemIndex(t);if(n>=0){var r=0;this.__selectedMap.forEach(function(t,o){n==r++&&e.deselect(o)})}}},{key:"__selectedIndexForItemIndex",value:function(t){var e=this.__dataLinkedPaths["items."+t];if(e)return parseInt(e.slice("selected.".length),10)}},{key:"deselect",value:function(t){var e,n=this.__selectedMap.get(t);n>=0&&(this.__selectedMap.delete(t),this.multi&&(e=this.__selectedIndexForItemIndex(n)),this.__updateLinks(),this.multi?this.splice("selected",e,1):this.selected=this.selectedItem=null)}},{key:"deselectIndex",value:function(t){this.deselect(this.items[t])}},{key:"select",value:function(t){this.selectIndex(this.items.indexOf(t))}},{key:"selectIndex",value:function(t){var e=this.items[t];this.isSelected(e)?this.toggle&&this.deselectIndex(t):(this.multi||this.__selectedMap.clear(),this.__selectedMap.set(e,t),this.__updateLinks(),this.multi?this.push("selected",e):this.selected=this.selectedItem=e)}}]),n}()})(W.a),jt=function(t){function e(){return Ot(this,e),wt(this,Pt(e).apply(this,arguments))}return Ct(e,Tt),St(e,null,[{key:"is",get:function(){return"array-selector"}}]),e}();customElements.define(jt.is,jt);n(108);y._mutablePropertyChange;Boolean,n(4);n.d(e,"a",function(){return At});var At=Object(r.a)(HTMLElement).prototype},function(t,e,n){"use strict";n.d(e,"a",function(){return a});n(8);function r(t,e){for(var n=0;n1?n-1:0),a=1;a=0){if(!i[e])throw new Error("invalid async handle: "+t);i[e]=null}}}},,,,function(t,e,n){"use strict";n.d(e,"a",function(){return o});n(8),n(12),n(23);function r(t,e){for(var n=0;n-1}var v=!1;function m(t){if(!_(t)&&"touchend"!==t)return a&&v&&i.b?{passive:!0}:void 0}!function(){try{var t=Object.defineProperty({},"passive",{get:function(){v=!0}});window.addEventListener("test",null,t),window.removeEventListener("test",null,t)}catch(e){}}();var b=navigator.userAgent.match(/iP(?:[oa]d|hone)|Android/),g=[],O={button:!0,input:!0,keygen:!0,meter:!0,output:!0,textarea:!0,progress:!0,select:!0},w={button:!0,command:!0,fieldset:!0,input:!0,keygen:!0,optgroup:!0,option:!0,select:!0,textarea:!0};function P(t){var e=Array.prototype.slice.call(t.labels||[]);if(!e.length){e=[];var n=t.getRootNode();if(t.id)for(var r=n.querySelectorAll("label[for = ".concat(t.id,"]")),o=0;o-1;if(o[i]===E.mouse.target)return}if(r)return;t.preventDefault(),t.stopPropagation()}};function S(t){for(var e,n=b?["click"]:p,r=0;r0?e[0]:t.target}return t.target}function R(t){var e,n=t.type,r=t.currentTarget[s];if(r){var o=r[n];if(o){if(!t[u]&&(t[u]={},"touch"===n.slice(0,5))){var i=(t=t).changedTouches[0];if("touchstart"===n&&1===t.touches.length&&(E.touch.id=i.identifier),E.touch.id!==i.identifier)return;a||"touchstart"!==n&&"touchmove"!==n||function(t){var e=t.changedTouches[0],n=t.type;if("touchstart"===n)E.touch.x=e.clientX,E.touch.y=e.clientY,E.touch.scrollDecided=!1;else if("touchmove"===n){if(E.touch.scrollDecided)return;E.touch.scrollDecided=!0;var r=function(t){var e="auto",n=t.composedPath&&t.composedPath();if(n)for(var r,o=0;oi:"pan-y"===r&&(o=i>a)),o?t.preventDefault():H("track")}}(t)}if(!(e=t[u]).skip){for(var l,f=0;f-1&&l.reset&&l.reset();for(var h,p=0;p=f||o>=f}function q(t,e,n){if(e){var r,o=t.moves[t.moves.length-2],i=t.moves[t.moves.length-1],a=i.x-t.x,s=i.y-t.y,u=0;o&&(r=i.x-o.x,u=i.y-o.y),F(e,"track",{state:t.state,x:n.clientX,y:n.clientY,dx:a,dy:s,ddx:r,ddy:u,sourceEvent:n,hover:function(){return function(t,e){for(var n=document.elementFromPoint(t,e),r=n;r&&r.shadowRoot&&!window.ShadyDOM&&r!==(r=r.shadowRoot.elementFromPoint(t,e));)r&&(n=r);return n}(n.clientX,n.clientY)}})}}function Y(t,e,n){var r=Math.abs(e.clientX-t.x),o=Math.abs(e.clientY-t.y),i=N(n||e);!i||w[i.localName]&&i.hasAttribute("disabled")||(isNaN(r)||isNaN(o)||r<=l&&o<=l||function(t){if("click"===t.type){if(0===t.detail)return!0;var e=N(t);if(!e.nodeType||e.nodeType!==Node.ELEMENT_NODE)return!0;var n=e.getBoundingClientRect(),r=t.pageX,o=t.pageY;return!(r>=n.left&&r<=n.right&&o>=n.top&&o<=n.bottom)}return!1}(e))&&(t.prevent||F(i,"tap",{x:e.clientX,y:e.clientY,sourceEvent:e,preventer:n}))}L({name:"downup",deps:["mousedown","touchstart","touchend"],flow:{start:["mousedown","touchstart"],end:["mouseup","touchend"]},emits:["down","up"],info:{movefn:null,upfn:null},reset:function(){j(this.info)},mousedown:function(t){if(C(t)){var e=N(t),n=this;T(this.info,function(t){C(t)||(z("up",e,t),j(n.info))},function(t){C(t)&&z("up",e,t),j(n.info)}),z("down",e,t)}},touchstart:function(t){z("down",N(t),t.changedTouches[0],t)},touchend:function(t){z("up",N(t),t.changedTouches[0],t)}}),L({name:"track",touchAction:"none",deps:["mousedown","touchstart","touchmove","touchend"],flow:{start:["mousedown","touchstart"],end:["mouseup","touchend"]},emits:["track"],info:{x:0,y:0,state:"start",started:!1,moves:[],addMove:function(t){this.moves.length>2&&this.moves.shift(),this.moves.push(t)},movefn:null,upfn:null,prevent:!1},reset:function(){this.info.state="start",this.info.started=!1,this.info.moves=[],this.info.x=0,this.info.y=0,this.info.prevent=!1,j(this.info)},mousedown:function(t){if(C(t)){var e=N(t),n=this,r=function(t){var r=t.clientX,o=t.clientY;B(n.info,r,o)&&(n.info.state=n.info.started?"mouseup"===t.type?"end":"track":"start","start"===n.info.state&&H("tap"),n.info.addMove({x:r,y:o}),C(t)||(n.info.state="end",j(n.info)),e&&q(n.info,e,t),n.info.started=!0)};T(this.info,r,function(t){n.info.started&&r(t),j(n.info)}),this.info.x=t.clientX,this.info.y=t.clientY}},touchstart:function(t){var e=t.changedTouches[0];this.info.x=e.clientX,this.info.y=e.clientY},touchmove:function(t){var e=N(t),n=t.changedTouches[0],r=n.clientX,o=n.clientY;B(this.info,r,o)&&("start"===this.info.state&&H("tap"),this.info.addMove({x:r,y:o}),q(this.info,e,n),this.info.state="track",this.info.started=!0)},touchend:function(t){var e=N(t),n=t.changedTouches[0];this.info.started&&(this.info.state="end",this.info.addMove({x:n.clientX,y:n.clientY}),q(this.info,e,n))}}),L({name:"tap",deps:["mousedown","click","touchstart","touchend"],flow:{start:["mousedown","touchstart"],end:["click","touchend"]},emits:["tap"],info:{x:NaN,y:NaN,prevent:!1},reset:function(){this.info.x=NaN,this.info.y=NaN,this.info.prevent=!1},mousedown:function(t){C(t)&&(this.info.x=t.clientX,this.info.y=t.clientY)},click:function(t){C(t)&&Y(this.info,t)},touchstart:function(t){var e=t.changedTouches[0];this.info.x=e.clientX,this.info.y=e.clientY},touchend:function(t){Y(this.info,t.changedTouches[0],t)}});var V=N,U=I},,,,,,,,function(t,e,n){"use strict";n.d(e,"d",function(){return r}),n.d(e,"g",function(){return o}),n.d(e,"b",function(){return i}),n.d(e,"c",function(){return a}),n.d(e,"i",function(){return s}),n.d(e,"e",function(){return u}),n.d(e,"f",function(){return c}),n.d(e,"a",function(){return f}),n.d(e,"h",function(){return h});n(8);function r(t){return t.indexOf(".")>=0}function o(t){var e=t.indexOf(".");return-1===e?t:t.slice(0,e)}function i(t,e){return 0===t.indexOf(e+".")}function a(t,e){return 0===e.indexOf(t+".")}function s(t,e,n){return e+n.slice(t.length)}function u(t,e){return t===e||i(t,e)||a(t,e)}function c(t){if(Array.isArray(t)){for(var e=[],n=0;n1){for(var a=0;a=0;o--){var i=e[o];i?Array.isArray(i)?t(i,n):n.indexOf(i)<0&&(!r||r.indexOf(i)<0)&&n.unshift(i):console.warn("behavior is null, check for missing or 404 import")}return n}(t,null,n),e),n&&(t=n.concat(t)),e.prototype.behaviors=t,e}function h(t,e){var n=function(n){function r(){return function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,r),a(this,u(r).apply(this,arguments))}var o,l,f;return function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&c(t,e)}(r,e),o=r,f=[{key:"properties",get:function(){return t.properties}},{key:"observers",get:function(){return t.observers}}],(l=[{key:"created",value:function(){s(u(r.prototype),"created",this).call(this),t.created&&t.created.call(this)}},{key:"_registered",value:function(){s(u(r.prototype),"_registered",this).call(this),t.beforeRegister&&t.beforeRegister.call(Object.getPrototypeOf(this)),t.registered&&t.registered.call(Object.getPrototypeOf(this))}},{key:"_applyListeners",value:function(){if(s(u(r.prototype),"_applyListeners",this).call(this),t.listeners)for(var e in t.listeners)this._addMethodEventListenerToNode(this,e,t.listeners[e])}},{key:"_ensureAttributes",value:function(){if(t.hostAttributes)for(var e in t.hostAttributes)this._ensureAttribute(e,t.hostAttributes[e]);s(u(r.prototype),"_ensureAttributes",this).call(this)}},{key:"ready",value:function(){s(u(r.prototype),"ready",this).call(this),t.ready&&t.ready.call(this)}},{key:"attached",value:function(){s(u(r.prototype),"attached",this).call(this),t.attached&&t.attached.call(this)}},{key:"detached",value:function(){s(u(r.prototype),"detached",this).call(this),t.detached&&t.detached.call(this)}},{key:"attributeChanged",value:function(e,n,o){s(u(r.prototype),"attributeChanged",this).call(this,e,n,o),t.attributeChanged&&t.attributeChanged.call(this,e,n,o)}}])&&i(o.prototype,l),f&&i(o,f),r}();for(var r in n.generatedFrom=t,t)if(!(r in l)){var o=Object.getOwnPropertyDescriptor(t,r);o&&Object.defineProperty(n.prototype,r,o)}return n}var p=function(t,e){t||console.warn("Polymer's Class function requires `info` argument");var n=t.behaviors?f(t.behaviors,HTMLElement):Object(r.a)(HTMLElement),o=h(t,e?e(n):n);return o.is=t.is,o}},function(t,e,n){"use strict";n.d(e,"a",function(){return i});n(3);var r=n(5);function o(t,e){for(var n=0;nl.source.length&&"property"==c.kind&&!c.isCompound&&u.__isPropertyEffectsClient&&u.__dataHasAccessor&&u.__dataHasAccessor[c.target]){var f=n[e];e=Object(o.i)(l.source,c.target,e),u._setPendingPropertyOrPath(e,f,!1,!0)&&t._enqueueClient(u)}else{!function(t,e,n,r,o){o=function(t,e,n,r){if(n.isCompound){var o=t.__dataCompoundStorage[n.target];o[r.compoundIndex]=e,e=o.join("")}return"attribute"!==n.kind&&("textContent"!==n.target&&("value"!==n.target||"input"!==t.localName&&"textarea"!==t.localName)||(e=null==e?"":e)),e}(e,o,n,r),b.d&&(o=Object(b.d)(o,n.target,n.kind,e));if("attribute"==n.kind)t._valueToNodeAttribute(e,o,n.target);else{var i=n.target;e.__isPropertyEffectsClient&&e.__dataHasAccessor&&e.__dataHasAccessor[i]?e[j.READ_ONLY]&&e[j.READ_ONLY][i]||e._setPendingProperty(i,o)&&t._enqueueClient(e):t._setUnmanagedPropertyToNode(e,i,o)}}(t,u,c,l,i.evaluator._evaluateBinding(t,l,e,n,r,a))}}function V(t,e){if(e.isCompound){for(var n=t.__dataCompoundStorage||(t.__dataCompoundStorage={}),r=e.parts,o=new Array(r.length),i=0;i="0"&&r<="9"&&(r="#"),r){case"'":case'"':n.value=e.slice(1,-1),n.literal=!0;break;case"#":n.value=Number(e),n.literal=!0}return n.literal||(n.rootProperty=Object(o.g)(e),n.structured=Object(o.d)(e),n.structured&&(n.wildcard=".*"==e.slice(-2),n.wildcard&&(n.name=e.slice(0,-2)))),n}function Q(t,e,n,r){var o=n+".splices";t.notifyPath(o,{indexSplices:r}),t.notifyPath(n+".length",e.length),t.__data[o]={indexSplices:null}}function tt(t,e,n,r,o,i){Q(t,e,n,[{index:r,addedCount:o,removed:i,object:e,type:"splice"}])}var et=Object(r.a)(function(t){var e=m(Object(a.a)(t)),n=function(t){function n(){var t;return g(this,n),(t=P(this,S(n).call(this))).__isPropertyEffectsClient=!0,t.__dataCounter=0,t.__dataClientsReady,t.__dataPendingClients,t.__dataToNotify,t.__dataLinkedPaths,t.__dataHasPaths,t.__dataCompoundStorage,t.__dataHost,t.__dataTemp,t.__dataClientsInitialized,t.__data,t.__dataPending,t.__dataOld,t.__computeEffects,t.__reflectEffects,t.__notifyEffects,t.__propagateEffects,t.__observeEffects,t.__readOnly,t.__templateInfo,t}return function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&C(t,e)}(n,e),w(n,[{key:"_initializeProperties",value:function(){k(S(n.prototype),"_initializeProperties",this).call(this),nt.registerHost(this),this.__dataClientsReady=!1,this.__dataPendingClients=null,this.__dataToNotify=null,this.__dataLinkedPaths=null,this.__dataHasPaths=!1,this.__dataCompoundStorage=this.__dataCompoundStorage||null,this.__dataHost=this.__dataHost||null,this.__dataTemp={},this.__dataClientsInitialized=!1}},{key:"_initializeProtoProperties",value:function(t){this.__data=Object.create(t),this.__dataPending=Object.create(t),this.__dataOld={}}},{key:"_initializeInstanceProperties",value:function(t){var e=this[j.READ_ONLY];for(var n in t)e&&e[n]||(this.__dataPending=this.__dataPending||{},this.__dataOld=this.__dataOld||{},this.__data[n]=this.__dataPending[n]=t[n])}},{key:"_addPropertyEffect",value:function(t,e,n){this._createPropertyAccessor(t,e==j.READ_ONLY);var r=x(this,e)[t];r||(r=this[e][t]=[]),r.push(n)}},{key:"_removePropertyEffect",value:function(t,e,n){var r=x(this,e)[t],o=r.indexOf(n);o>=0&&r.splice(o,1)}},{key:"_hasPropertyEffect",value:function(t,e){var n=this[e];return Boolean(n&&n[t])}},{key:"_hasReadOnlyEffect",value:function(t){return this._hasPropertyEffect(t,j.READ_ONLY)}},{key:"_hasNotifyEffect",value:function(t){return this._hasPropertyEffect(t,j.NOTIFY)}},{key:"_hasReflectEffect",value:function(t){return this._hasPropertyEffect(t,j.REFLECT)}},{key:"_hasComputedEffect",value:function(t){return this._hasPropertyEffect(t,j.COMPUTE)}},{key:"_setPendingPropertyOrPath",value:function(t,e,r,i){if(i||Object(o.g)(Array.isArray(t)?t[0]:t)!==t){if(!i){var a=Object(o.a)(this,t);if(!(t=Object(o.h)(this,t,e))||!k(S(n.prototype),"_shouldPropertyChange",this).call(this,t,e,a))return!1}if(this.__dataHasPaths=!0,this._setPendingProperty(t,e,r))return function(t,e,n){var r,i=t.__dataLinkedPaths;if(i)for(var a in i){var s=i[a];Object(o.c)(a,e)?(r=Object(o.i)(a,s,e),t._setPendingPropertyOrPath(r,n,!0,!0)):Object(o.c)(s,e)&&(r=Object(o.i)(s,a,e),t._setPendingPropertyOrPath(r,n,!0,!0))}}(this,t,e),!0}else{if(this.__dataHasAccessor&&this.__dataHasAccessor[t])return this._setPendingProperty(t,e,r);this[t]=e}return!1}},{key:"_setUnmanagedPropertyToNode",value:function(t,e,n){n===t[e]&&"object"!=E(n)||(t[e]=n)}},{key:"_setPendingProperty",value:function(t,e,n){var r=this.__dataHasPaths&&Object(o.d)(t),i=r?this.__dataTemp:this.__data;return!!this._shouldPropertyChange(t,e,i[t])&&(this.__dataPending||(this.__dataPending={},this.__dataOld={}),t in this.__dataOld||(this.__dataOld[t]=this.__data[t]),r?this.__dataTemp[t]=e:this.__data[t]=e,this.__dataPending[t]=e,(r||this[j.NOTIFY]&&this[j.NOTIFY][t])&&(this.__dataToNotify=this.__dataToNotify||{},this.__dataToNotify[t]=n),!0)}},{key:"_setProperty",value:function(t,e){this._setPendingProperty(t,e,!0)&&this._invalidateProperties()}},{key:"_invalidateProperties",value:function(){this.__dataReady&&this._flushProperties()}},{key:"_enqueueClient",value:function(t){this.__dataPendingClients=this.__dataPendingClients||[],t!==this&&this.__dataPendingClients.push(t)}},{key:"_flushProperties",value:function(){this.__dataCounter++,k(S(n.prototype),"_flushProperties",this).call(this),this.__dataCounter--}},{key:"_flushClients",value:function(){this.__dataClientsReady?this.__enableOrFlushClients():(this.__dataClientsReady=!0,this._readyClients(),this.__dataReady=!0)}},{key:"__enableOrFlushClients",value:function(){var t=this.__dataPendingClients;if(t){this.__dataPendingClients=null;for(var e=0;e1?i-1:0),s=1;s3?r-3:0),a=3;a1?r-1:0),a=1;ao&&r.push({literal:t.slice(o,n.index)});var i=n[1][0],a=Boolean(n[2]),s=n[3].trim(),u=!1,c="",l=-1;"{"==i&&(l=s.indexOf("::"))>0&&(c=s.substring(l+2),s=s.substring(0,l),u=!0);var f=K(s),h=[];if(f){for(var p=f.args,d=f.methodName,y=0;y0||n>0;)if(0!=e)if(0!=n){var c=t[e-1][n-1],l=t[e-1][n],f=t[e][n-1],h=void 0;(h=l2&&void 0!==arguments[2]?arguments[2]:"",r="";if(t.cssText||t.rules){var o=t.rules;if(o&&!function(t){var e=t[0];return Boolean(e)&&Boolean(e.selector)&&0===e.selector.indexOf(f)}(o))for(var i,s=0,h=o.length;s1&&void 0!==arguments[1]?arguments[1]:"",n=g(t);return this.transformRules(n,e),t.textContent=b(n),n}},{key:"transformCustomStyle",value:function(t){var e=this,n=g(t);return O(n,function(t){":root"===t.selector&&(t.selector="html"),e.transformRule(t)}),t.textContent=b(n),n}},{key:"transformRules",value:function(t,e){var n=this;this._currentElement=e,O(t,function(t){n.transformRule(t)}),this._currentElement=null}},{key:"transformRule",value:function(t){t.cssText=this.transformCssText(t.parsedCssText,t),":root"===t.selector&&(t.selector=":host > *")}},{key:"transformCssText",value:function(t,e){var n=this;return t=t.replace(d.c,function(t,r,o,i){return n._produceCssProperties(t,r,o,i,e)}),this._consumeCssProperties(t,e)}},{key:"_getInitialValueForProperty",value:function(t){return this._measureElement||(this._measureElement=document.createElement("meta"),this._measureElement.setAttribute("apply-shim-measure",""),this._measureElement.style.all="initial",document.head.appendChild(this._measureElement)),window.getComputedStyle(this._measureElement).getPropertyValue(t)}},{key:"_fallbacksFromPreviousRules",value:function(t){for(var e=this,n=t;n.parent;)n=n.parent;var r={},o=!1;return O(n,function(n){(o=o||n===t)||n.selector===t.selector&&Object.assign(r,e._cssTextToMap(n.parsedCssText))}),r}},{key:"_consumeCssProperties",value:function(t,e){for(var n=null;n=d.b.exec(t);){var r=n[0],o=n[1],i=n.index,a=i+r.indexOf("@apply"),s=i+r.length,u=t.slice(0,a),c=t.slice(s),l=e?this._fallbacksFromPreviousRules(e):{};Object.assign(l,this._cssTextToMap(u));var f=this._atApplyToCssProperties(o,l);t="".concat(u).concat(f).concat(c),d.b.lastIndex=i+f.length}return t}},{key:"_atApplyToCssProperties",value:function(t,e){t=t.replace(A,"");var n=[],r=this._map.get(t);if(r||(this._map.set(t,{}),r=this._map.get(t)),r){var o,i,a;this._currentElement&&(r.dependants[this._currentElement]=!0);var s=r.properties;for(o in s)i=[o,": var(",t,"_-_",o],(a=e&&e[o])&&i.push(",",a.replace(N,"")),i.push(")"),N.test(s[o])&&i.push(" !important"),n.push(i.join(""))}return n.join("; ")}},{key:"_replaceInitialOrInherit",value:function(t,e){var n=x.exec(e);return n&&(e=n[1]?this._getInitialValueForProperty(t):"apply-shim-inherit"),e}},{key:"_cssTextToMap",value:function(t){for(var e,n,r,o,i=arguments.length>1&&void 0!==arguments[1]&&arguments[1],a=t.split(";"),s={},u=0;u1&&(e=o[0].trim(),n=o.slice(1).join(":"),i&&(n=this._replaceInitialOrInherit(e,n)),s[e]=n);return s}},{key:"_invalidateMixinEntry",value:function(t){if(I)for(var e in t.dependants)e!==this._currentElement&&I(e)}},{key:"_produceCssProperties",value:function(t,e,n,r,o){var i=this;if(n&&function t(e,n){var r=e.indexOf("var(");if(-1===r)return n(e,"","","");var o=w(e,r+3),i=e.substring(r+4,o),a=e.substring(0,r),s=t(e.substring(o+1),n),u=i.indexOf(",");return-1===u?n(a,i.trim(),"",s):n(a,i.substring(0,u).trim(),i.substring(u+1).trim(),s)}(n,function(t,e){e&&i._map.get(e)&&(r="@apply ".concat(e,";"))}),!r)return t;var a=this._consumeCssProperties(""+r,o),s=t.slice(0,t.indexOf("--")),u=this._cssTextToMap(a,!0),c=u,l=this._map.get(e),f=l&&l.properties;f?c=Object.assign(Object.create(f),u):this._map.set(e,c);var h,p,d=[],y=!1;for(h in c)void 0===(p=u[h])&&(p="initial"),!f||h in f||(y=!0),d.push("".concat(e).concat("_-_").concat(h,": ").concat(p));return y&&this._invalidateMixinEntry(l),l&&(l.properties=c),n&&(s="".concat(t,";").concat(s)),"".concat(s).concat(d.join("; "),";")}}]),t}();M.prototype.detectMixin=M.prototype.detectMixin,M.prototype.transformStyle=M.prototype.transformStyle,M.prototype.transformCustomStyle=M.prototype.transformCustomStyle,M.prototype.transformRules=M.prototype.transformRules,M.prototype.transformRule=M.prototype.transformRule,M.prototype.transformTemplate=M.prototype.transformTemplate,M.prototype._separator="_-_",Object.defineProperty(M.prototype,"invalidCallback",{get:function(){return I},set:function(t){I=t}});var L=M,D={},F="_applyShimCurrentVersion",H="_applyShimNextVersion",z="_applyShimValidatingVersion",B=Promise.resolve();function q(t){var e=D[t];e&&function(t){t[F]=t[F]||0,t[z]=t[z]||0,t[H]=(t[H]||0)+1}(e)}function Y(t){return t[F]===t[H]}function V(t){return!Y(t)&&t[z]===t[H]}function U(t){t[z]=t[H],t._validating||(t._validating=!0,B.then(function(){t[F]=t[H],t._validating=!1}))}n(109);function $(t,e){for(var n=0;n-1?n=e:(r=e,n=t.getAttribute&&t.getAttribute("is")||""):(n=t.is,r=t.extends),{is:n,typeExtension:r}}(t).is,n=D[e];if((!n||!S(n))&&n&&!Y(n)){V(n)||(this.prepareTemplate(n,e),U(n));var r=t.shadowRoot;if(r){var o=r.querySelector("style");o&&(o.__cssRules=n._styleAst,o.textContent=b(n._styleAst))}}}},{key:"styleDocument",value:function(t){this.ensure(),this.styleSubtree(document.body,t)}}])&&$(e.prototype,n),r&&$(e,r),t}();if(!window.ShadyCSS||!window.ShadyCSS.ScopingShim){var G=new X,W=window.ShadyCSS&&window.ShadyCSS.CustomStyleInterface;window.ShadyCSS={prepareTemplate:function(t,e,n){G.flushCustomStyles(),G.prepareTemplate(t,e)},prepareTemplateStyles:function(t,e,n){window.ShadyCSS.prepareTemplate(t,e,n)},prepareTemplateDom:function(t,e){},styleSubtree:function(t,e){G.flushCustomStyles(),G.styleSubtree(t,e)},styleElement:function(t){G.flushCustomStyles(),G.styleElement(t)},styleDocument:function(t){G.flushCustomStyles(),G.styleDocument(t)},getComputedStyleValue:function(t,e){return Object(C.b)(t,e)},flushCustomStyles:function(){G.flushCustomStyles()},nativeCss:r.c,nativeShadow:r.d,cssBuild:r.a,disableRuntime:r.b},W&&(window.ShadyCSS.CustomStyleInterface=W)}window.ShadyCSS.ApplyShim=J;var K=n(54),Z=n(84),Q=n(82),tt=n(12);function et(t){return(et="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function nt(t,e){return!e||"object"!==et(e)&&"function"!=typeof e?function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t):e}function rt(t,e){for(var n=0;n-1&<.splice(t,1)}}}]),n}();return n.__activateDir=!1,n});n(47);function vt(){document.body.removeAttribute("unresolved")}"interactive"===document.readyState||"complete"===document.readyState?vt():window.addEventListener("DOMContentLoaded",vt);var mt=n(6),bt=n(37),gt=n(27),Ot=n(23),wt=n(45);function Pt(t){return(Pt="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function kt(t){return function(t){if(Array.isArray(t)){for(var e=0,n=new Array(t.length);e0?Ot.c.after(n):Ot.b,e.bind(this))}},{key:"isDebouncerActive",value:function(t){this._debouncers=this._debouncers||{};var e=this._debouncers[t];return!(!e||!e.isActive())}},{key:"flushDebouncer",value:function(t){this._debouncers=this._debouncers||{};var e=this._debouncers[t];e&&e.flush()}},{key:"cancelDebouncer",value:function(t){this._debouncers=this._debouncers||{};var e=this._debouncers[t];e&&e.cancel()}},{key:"async",value:function(t,e){return e>0?Ot.c.run(t.bind(this),e):~Ot.b.run(t.bind(this))}},{key:"cancelAsync",value:function(t){t<0?Ot.b.cancel(~t):Ot.c.cancel(t)}},{key:"create",value:function(t,e){var n=document.createElement(t);if(e)if(n.setProperties)n.setProperties(e);else for(var r in e)n[r]=e[r];return n}},{key:"elementMatches",value:function(t,e){return Object(mt.b)(e||this,t)}},{key:"toggleAttribute",value:function(t,e){var n=this;return 3===arguments.length&&(n=arguments[2]),1==arguments.length&&(e=!n.hasAttribute(t)),e?(n.setAttribute(t,""),!0):(n.removeAttribute(t),!1)}},{key:"toggleClass",value:function(t,e,n){n=n||this,1==arguments.length&&(e=!n.classList.contains(t)),e?n.classList.add(t):n.classList.remove(t)}},{key:"transform",value:function(t,e){(e=e||this).style.webkitTransform=t,e.style.transform=t}},{key:"translate3d",value:function(t,e,n,r){r=r||this,this.transform("translate3d("+t+","+e+","+n+")",r)}},{key:"arrayDelete",value:function(t,e){var n;if(Array.isArray(t)){if((n=t.indexOf(e))>=0)return t.splice(n,1)}else if((n=Object(wt.a)(this,t).indexOf(e))>=0)return this.splice(t,n,1);return null}},{key:"_logger",value:function(t,e){var n;switch(Array.isArray(e)&&1===e.length&&Array.isArray(e[0])&&(e=e[0]),t){case"log":case"warn":case"error":(n=console)[t].apply(n,kt(e))}}},{key:"_log",value:function(){for(var t=arguments.length,e=new Array(t),n=0;n1?e-1:0),r=1;r {\n\n /**\n * @polymer\n * @mixinClass\n * @implements {Polymer_MutableData}\n */\n class MutableData extends superClass {\n /**\n * Overrides `PropertyEffects` to provide option for skipping\n * strict equality checking for Objects and Arrays.\n *\n * This method pulls the value to dirty check against from the `__dataTemp`\n * cache (rather than the normal `__data` cache) for Objects. Since the temp\n * cache is cleared at the end of a turn, this implementation allows\n * side-effects of deep object changes to be processed by re-setting the\n * same object (using the temp cache as an in-turn backstop to prevent\n * cycles due to 2-way notification).\n *\n * @param {string} property Property name\n * @param {*} value New property value\n * @param {*} old Previous property value\n * @return {boolean} Whether the property should be considered a change\n * @protected\n */\n _shouldPropertyChange(property, value, old) {\n return mutablePropertyChange(this, property, value, old, true);\n }\n\n }\n\n return MutableData;\n\n});\n\n/**\n * Element class mixin to add the optional ability to skip strict\n * dirty-checking for objects and arrays (always consider them to be\n * \"dirty\") by setting a `mutable-data` attribute on an element instance.\n *\n * By default, `PropertyEffects` performs strict dirty checking on\n * objects, which means that any deep modifications to an object or array will\n * not be propagated unless \"immutable\" data patterns are used (i.e. all object\n * references from the root to the mutation were changed).\n *\n * Polymer also provides a proprietary data mutation and path notification API\n * (e.g. `notifyPath`, `set`, and array mutation API's) that allow efficient\n * mutation and notification of deep changes in an object graph to all elements\n * bound to the same object graph.\n *\n * In cases where neither immutable patterns nor the data mutation API can be\n * used, applying this mixin will allow Polymer to skip dirty checking for\n * objects and arrays (always consider them to be \"dirty\"). This allows a\n * user to make a deep modification to a bound object graph, and then either\n * simply re-set the object (e.g. `this.items = this.items`) or call `notifyPath`\n * (e.g. `this.notifyPath('items')`) to update the tree. Note that all\n * elements that wish to be updated based on deep mutations must apply this\n * mixin or otherwise skip strict dirty checking for objects/arrays.\n * Specifically, any elements in the binding tree between the source of a\n * mutation and the consumption of it must enable this mixin or apply the\n * `MutableData` mixin.\n *\n * While this mixin adds the ability to forgo Object/Array dirty checking,\n * the `mutableData` flag defaults to false and must be set on the instance.\n *\n * Note, the performance characteristics of propagating large object graphs\n * will be worse by relying on `mutableData: true` as opposed to using\n * strict dirty checking with immutable patterns or Polymer's path notification\n * API.\n *\n * @mixinFunction\n * @polymer\n * @summary Element class mixin to optionally skip strict dirty-checking\n * for objects and arrays\n */\nexport const OptionalMutableData = dedupingMixin(superClass => {\n\n /**\n * @mixinClass\n * @polymer\n * @implements {Polymer_OptionalMutableData}\n */\n class OptionalMutableData extends superClass {\n\n static get properties() {\n return {\n /**\n * Instance-level flag for configuring the dirty-checking strategy\n * for this element. When true, Objects and Arrays will skip dirty\n * checking, otherwise strict equality checking will be used.\n */\n mutableData: Boolean\n };\n }\n\n /**\n * Overrides `PropertyEffects` to provide option for skipping\n * strict equality checking for Objects and Arrays.\n *\n * When `this.mutableData` is true on this instance, this method\n * pulls the value to dirty check against from the `__dataTemp` cache\n * (rather than the normal `__data` cache) for Objects. Since the temp\n * cache is cleared at the end of a turn, this implementation allows\n * side-effects of deep object changes to be processed by re-setting the\n * same object (using the temp cache as an in-turn backstop to prevent\n * cycles due to 2-way notification).\n *\n * @param {string} property Property name\n * @param {*} value New property value\n * @param {*} old Previous property value\n * @return {boolean} Whether the property should be considered a change\n * @protected\n */\n _shouldPropertyChange(property, value, old) {\n return mutablePropertyChange(this, property, value, old, this.mutableData);\n }\n }\n\n return OptionalMutableData;\n\n});\n\n// Export for use by legacy behavior\nMutableData._mutablePropertyChange = mutablePropertyChange;\n","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\n/**\n * Module for preparing and stamping instances of templates that utilize\n * Polymer's data-binding and declarative event listener features.\n *\n * Example:\n *\n * // Get a template from somewhere, e.g. light DOM\n * let template = this.querySelector('template');\n * // Prepare the template\n * let TemplateClass = Templatize.templatize(template);\n * // Instance the template with an initial data model\n * let instance = new TemplateClass({myProp: 'initial'});\n * // Insert the instance's DOM somewhere, e.g. element's shadow DOM\n * this.shadowRoot.appendChild(instance.root);\n * // Changing a property on the instance will propagate to bindings\n * // in the template\n * instance.myProp = 'new value';\n *\n * The `options` dictionary passed to `templatize` allows for customizing\n * features of the generated template class, including how outer-scope host\n * properties should be forwarded into template instances, how any instance\n * properties added into the template's scope should be notified out to\n * the host, and whether the instance should be decorated as a \"parent model\"\n * of any event handlers.\n *\n * // Customize property forwarding and event model decoration\n * let TemplateClass = Templatize.templatize(template, this, {\n * parentModel: true,\n * forwardHostProp(property, value) {...},\n * instanceProps: {...},\n * notifyInstanceProp(instance, property, value) {...},\n * });\n *\n * @summary Module for preparing and stamping instances of templates\n * utilizing Polymer templating features.\n */\n\nimport './boot.js';\n\nimport { PropertyEffects } from '../mixins/property-effects.js';\nimport { MutableData } from '../mixins/mutable-data.js';\nimport { strictTemplatePolicy } from '../utils/settings.js';\n\n// Base class for HTMLTemplateElement extension that has property effects\n// machinery for propagating host properties to children. This is an ES5\n// class only because Babel (incorrectly) requires super() in the class\n// constructor even though no `this` is used and it returns an instance.\nlet newInstance = null;\n\n/**\n * @constructor\n * @extends {HTMLTemplateElement}\n * @private\n */\nfunction HTMLTemplateElementExtension() { return newInstance; }\nHTMLTemplateElementExtension.prototype = Object.create(HTMLTemplateElement.prototype, {\n constructor: {\n value: HTMLTemplateElementExtension,\n writable: true\n }\n});\n\n/**\n * @constructor\n * @implements {Polymer_PropertyEffects}\n * @extends {HTMLTemplateElementExtension}\n * @private\n */\nconst DataTemplate = PropertyEffects(HTMLTemplateElementExtension);\n\n/**\n * @constructor\n * @implements {Polymer_MutableData}\n * @extends {DataTemplate}\n * @private\n */\nconst MutableDataTemplate = MutableData(DataTemplate);\n\n// Applies a DataTemplate subclass to a instance\nfunction upgradeTemplate(template, constructor) {\n newInstance = template;\n Object.setPrototypeOf(template, constructor.prototype);\n new constructor();\n newInstance = null;\n}\n\n/**\n * Base class for TemplateInstance.\n * @constructor\n * @implements {Polymer_PropertyEffects}\n * @private\n */\nconst base = PropertyEffects(class {});\n\n/**\n * @polymer\n * @customElement\n * @appliesMixin PropertyEffects\n * @unrestricted\n */\nclass TemplateInstanceBase extends base {\n constructor(props) {\n super();\n this._configureProperties(props);\n this.root = this._stampTemplate(this.__dataHost);\n // Save list of stamped children\n let children = this.children = [];\n for (let n = this.root.firstChild; n; n=n.nextSibling) {\n children.push(n);\n n.__templatizeInstance = this;\n }\n if (this.__templatizeOwner &&\n this.__templatizeOwner.__hideTemplateChildren__) {\n this._showHideChildren(true);\n }\n // Flush props only when props are passed if instance props exist\n // or when there isn't instance props.\n let options = this.__templatizeOptions;\n if ((props && options.instanceProps) || !options.instanceProps) {\n this._enableProperties();\n }\n }\n /**\n * Configure the given `props` by calling `_setPendingProperty`. Also\n * sets any properties stored in `__hostProps`.\n * @private\n * @param {Object} props Object of property name-value pairs to set.\n * @return {void}\n */\n _configureProperties(props) {\n let options = this.__templatizeOptions;\n if (options.forwardHostProp) {\n for (let hprop in this.__hostProps) {\n this._setPendingProperty(hprop, this.__dataHost['_host_' + hprop]);\n }\n }\n // Any instance props passed in the constructor will overwrite host props;\n // normally this would be a user error but we don't specifically filter them\n for (let iprop in props) {\n this._setPendingProperty(iprop, props[iprop]);\n }\n }\n /**\n * Forwards a host property to this instance. This method should be\n * called on instances from the `options.forwardHostProp` callback\n * to propagate changes of host properties to each instance.\n *\n * Note this method enqueues the change, which are flushed as a batch.\n *\n * @param {string} prop Property or path name\n * @param {*} value Value of the property to forward\n * @return {void}\n */\n forwardHostProp(prop, value) {\n if (this._setPendingPropertyOrPath(prop, value, false, true)) {\n this.__dataHost._enqueueClient(this);\n }\n }\n\n /**\n * Override point for adding custom or simulated event handling.\n *\n * @override\n * @param {!Node} node Node to add event listener to\n * @param {string} eventName Name of event\n * @param {function(!Event):void} handler Listener function to add\n * @return {void}\n */\n _addEventListenerToNode(node, eventName, handler) {\n if (this._methodHost && this.__templatizeOptions.parentModel) {\n // If this instance should be considered a parent model, decorate\n // events this template instance as `model`\n this._methodHost._addEventListenerToNode(node, eventName, (e) => {\n e.model = this;\n handler(e);\n });\n } else {\n // Otherwise delegate to the template's host (which could be)\n // another template instance\n let templateHost = this.__dataHost.__dataHost;\n if (templateHost) {\n templateHost._addEventListenerToNode(node, eventName, handler);\n }\n }\n }\n /**\n * Shows or hides the template instance top level child elements. For\n * text nodes, `textContent` is removed while \"hidden\" and replaced when\n * \"shown.\"\n * @param {boolean} hide Set to true to hide the children;\n * set to false to show them.\n * @return {void}\n * @protected\n */\n _showHideChildren(hide) {\n let c = this.children;\n for (let i=0; i\n // `model.__dataHost.__dataHost` is the template's host\n model = model.__dataHost.__dataHost;\n } while ((options = model.__templatizeOptions) && !options.parentModel);\n this.__parentModel = model;\n }\n return model;\n }\n\n /**\n * Stub of HTMLElement's `dispatchEvent`, so that effects that may\n * dispatch events safely no-op.\n *\n * @param {Event} event Event to dispatch\n * @return {boolean} Always true.\n */\n dispatchEvent(event) { // eslint-disable-line no-unused-vars\n return true;\n }\n}\n\n/** @type {!DataTemplate} */\nTemplateInstanceBase.prototype.__dataHost;\n/** @type {!TemplatizeOptions} */\nTemplateInstanceBase.prototype.__templatizeOptions;\n/** @type {!Polymer_PropertyEffects} */\nTemplateInstanceBase.prototype._methodHost;\n/** @type {!Object} */\nTemplateInstanceBase.prototype.__templatizeOwner;\n/** @type {!Object} */\nTemplateInstanceBase.prototype.__hostProps;\n\n/**\n * @constructor\n * @extends {TemplateInstanceBase}\n * @implements {Polymer_MutableData}\n * @private\n */\nconst MutableTemplateInstanceBase = MutableData(TemplateInstanceBase);\n\nfunction findMethodHost(template) {\n // Technically this should be the owner of the outermost template.\n // In shadow dom, this is always getRootNode().host, but we can\n // approximate this via cooperation with our dataHost always setting\n // `_methodHost` as long as there were bindings (or id's) on this\n // instance causing it to get a dataHost.\n let templateHost = template.__dataHost;\n return templateHost && templateHost._methodHost || templateHost;\n}\n\n/* eslint-disable valid-jsdoc */\n/**\n * @suppress {missingProperties} class.prototype is not defined for some reason\n */\nfunction createTemplatizerClass(template, templateInfo, options) {\n // Anonymous class created by the templatize\n let base = options.mutableData ?\n MutableTemplateInstanceBase : TemplateInstanceBase;\n /**\n * @constructor\n * @extends {base}\n * @private\n */\n let klass = class extends base { };\n klass.prototype.__templatizeOptions = options;\n klass.prototype._bindTemplate(template);\n addNotifyEffects(klass, template, templateInfo, options);\n return klass;\n}\n\n/**\n * @suppress {missingProperties} class.prototype is not defined for some reason\n */\nfunction addPropagateEffects(template, templateInfo, options) {\n let userForwardHostProp = options.forwardHostProp;\n if (userForwardHostProp) {\n // Provide data API and property effects on memoized template class\n let klass = templateInfo.templatizeTemplateClass;\n if (!klass) {\n let base = options.mutableData ? MutableDataTemplate : DataTemplate;\n /** @private */\n klass = templateInfo.templatizeTemplateClass =\n class TemplatizedTemplate extends base {};\n // Add template - >instances effects\n // and host <- template effects\n let hostProps = templateInfo.hostProps;\n for (let prop in hostProps) {\n klass.prototype._addPropertyEffect('_host_' + prop,\n klass.prototype.PROPERTY_EFFECT_TYPES.PROPAGATE,\n {fn: createForwardHostPropEffect(prop, userForwardHostProp)});\n klass.prototype._createNotifyingProperty('_host_' + prop);\n }\n }\n upgradeTemplate(template, klass);\n // Mix any pre-bound data into __data; no need to flush this to\n // instances since they pull from the template at instance-time\n if (template.__dataProto) {\n // Note, generally `__dataProto` could be chained, but it's guaranteed\n // to not be since this is a vanilla template we just added effects to\n Object.assign(template.__data, template.__dataProto);\n }\n // Clear any pending data for performance\n template.__dataTemp = {};\n template.__dataPending = null;\n template.__dataOld = null;\n template._enableProperties();\n }\n}\n/* eslint-enable valid-jsdoc */\n\nfunction createForwardHostPropEffect(hostProp, userForwardHostProp) {\n return function forwardHostProp(template, prop, props) {\n userForwardHostProp.call(template.__templatizeOwner,\n prop.substring('_host_'.length), props[prop]);\n };\n}\n\nfunction addNotifyEffects(klass, template, templateInfo, options) {\n let hostProps = templateInfo.hostProps || {};\n for (let iprop in options.instanceProps) {\n delete hostProps[iprop];\n let userNotifyInstanceProp = options.notifyInstanceProp;\n if (userNotifyInstanceProp) {\n klass.prototype._addPropertyEffect(iprop,\n klass.prototype.PROPERTY_EFFECT_TYPES.NOTIFY,\n {fn: createNotifyInstancePropEffect(iprop, userNotifyInstanceProp)});\n }\n }\n if (options.forwardHostProp && template.__dataHost) {\n for (let hprop in hostProps) {\n klass.prototype._addPropertyEffect(hprop,\n klass.prototype.PROPERTY_EFFECT_TYPES.NOTIFY,\n {fn: createNotifyHostPropEffect()});\n }\n }\n}\n\nfunction createNotifyInstancePropEffect(instProp, userNotifyInstanceProp) {\n return function notifyInstanceProp(inst, prop, props) {\n userNotifyInstanceProp.call(inst.__templatizeOwner,\n inst, prop, props[prop]);\n };\n}\n\nfunction createNotifyHostPropEffect() {\n return function notifyHostProp(inst, prop, props) {\n inst.__dataHost._setPendingPropertyOrPath('_host_' + prop, props[prop], true, true);\n };\n}\n\n\n/**\n * Returns an anonymous `PropertyEffects` class bound to the\n * `` provided. Instancing the class will result in the\n * template being stamped into a document fragment stored as the instance's\n * `root` property, after which it can be appended to the DOM.\n *\n * Templates may utilize all Polymer data-binding features as well as\n * declarative event listeners. Event listeners and inline computing\n * functions in the template will be called on the host of the template.\n *\n * The constructor returned takes a single argument dictionary of initial\n * property values to propagate into template bindings. Additionally\n * host properties can be forwarded in, and instance properties can be\n * notified out by providing optional callbacks in the `options` dictionary.\n *\n * Valid configuration in `options` are as follows:\n *\n * - `forwardHostProp(property, value)`: Called when a property referenced\n * in the template changed on the template's host. As this library does\n * not retain references to templates instanced by the user, it is the\n * templatize owner's responsibility to forward host property changes into\n * user-stamped instances. The `instance.forwardHostProp(property, value)`\n * method on the generated class should be called to forward host\n * properties into the template to prevent unnecessary property-changed\n * notifications. Any properties referenced in the template that are not\n * defined in `instanceProps` will be notified up to the template's host\n * automatically.\n * - `instanceProps`: Dictionary of property names that will be added\n * to the instance by the templatize owner. These properties shadow any\n * host properties, and changes within the template to these properties\n * will result in `notifyInstanceProp` being called.\n * - `mutableData`: When `true`, the generated class will skip strict\n * dirty-checking for objects and arrays (always consider them to be\n * \"dirty\").\n * - `notifyInstanceProp(instance, property, value)`: Called when\n * an instance property changes. Users may choose to call `notifyPath`\n * on e.g. the owner to notify the change.\n * - `parentModel`: When `true`, events handled by declarative event listeners\n * (`on-event=\"handler\"`) will be decorated with a `model` property pointing\n * to the template instance that stamped it. It will also be returned\n * from `instance.parentModel` in cases where template instance nesting\n * causes an inner model to shadow an outer model.\n *\n * All callbacks are called bound to the `owner`. Any context\n * needed for the callbacks (such as references to `instances` stamped)\n * should be stored on the `owner` such that they can be retrieved via\n * `this`.\n *\n * When `options.forwardHostProp` is declared as an option, any properties\n * referenced in the template will be automatically forwarded from the host of\n * the `` to instances, with the exception of any properties listed in\n * the `options.instanceProps` object. `instanceProps` are assumed to be\n * managed by the owner of the instances, either passed into the constructor\n * or set after the fact. Note, any properties passed into the constructor will\n * always be set to the instance (regardless of whether they would normally\n * be forwarded from the host).\n *\n * Note that `templatize()` can be run only once for a given ``.\n * Further calls will result in an error. Also, there is a special\n * behavior if the template was duplicated through a mechanism such as\n * `` or ``. In this case, all calls to\n * `templatize()` return the same class for all duplicates of a template.\n * The class returned from `templatize()` is generated only once using\n * the `options` from the first call. This means that any `options`\n * provided to subsequent calls will be ignored. Therefore, it is very\n * important not to close over any variables inside the callbacks. Also,\n * arrow functions must be avoided because they bind the outer `this`.\n * Inside the callbacks, any contextual information can be accessed\n * through `this`, which points to the `owner`.\n *\n * @param {!HTMLTemplateElement} template Template to templatize\n * @param {Polymer_PropertyEffects=} owner Owner of the template instances;\n * any optional callbacks will be bound to this owner.\n * @param {Object=} options Options dictionary (see summary for details)\n * @return {function(new:TemplateInstanceBase)} Generated class bound to the template\n * provided\n * @suppress {invalidCasts}\n */\nexport function templatize(template, owner, options) {\n // Under strictTemplatePolicy, the templatized element must be owned\n // by a (trusted) Polymer element, indicated by existence of _methodHost;\n // e.g. for dom-if & dom-repeat in main document, _methodHost is null\n if (strictTemplatePolicy && !findMethodHost(template)) {\n throw new Error('strictTemplatePolicy: template owner not trusted');\n }\n options = /** @type {!TemplatizeOptions} */(options || {});\n if (template.__templatizeOwner) {\n throw new Error('A can only be templatized once');\n }\n template.__templatizeOwner = owner;\n const ctor = owner ? owner.constructor : TemplateInstanceBase;\n let templateInfo = ctor._parseTemplate(template);\n // Get memoized base class for the prototypical template, which\n // includes property effects for binding template & forwarding\n let baseClass = templateInfo.templatizeInstanceClass;\n if (!baseClass) {\n baseClass = createTemplatizerClass(template, templateInfo, options);\n templateInfo.templatizeInstanceClass = baseClass;\n }\n // Host property forwarding must be installed onto template instance\n addPropagateEffects(template, templateInfo, options);\n // Subclass base class and add reference for this specific template\n /** @private */\n let klass = class TemplateInstance extends baseClass {};\n klass.prototype._methodHost = findMethodHost(template);\n klass.prototype.__dataHost = template;\n klass.prototype.__templatizeOwner = owner;\n klass.prototype.__hostProps = templateInfo.hostProps;\n klass = /** @type {function(new:TemplateInstanceBase)} */(klass); //eslint-disable-line no-self-assign\n return klass;\n}\n\n/**\n * Returns the template \"model\" associated with a given element, which\n * serves as the binding scope for the template instance the element is\n * contained in. A template model is an instance of\n * `TemplateInstanceBase`, and should be used to manipulate data\n * associated with this template instance.\n *\n * Example:\n *\n * let model = modelForElement(el);\n * if (model.index < 10) {\n * model.set('item.checked', true);\n * }\n *\n * @param {HTMLTemplateElement} template The model will be returned for\n * elements stamped from this template\n * @param {Node=} node Node for which to return a template model.\n * @return {TemplateInstanceBase} Template instance representing the\n * binding scope for the element\n */\nexport function modelForElement(template, node) {\n let model;\n while (node) {\n // An element with a __templatizeInstance marks the top boundary\n // of a scope; walk up until we find one, and then ensure that\n // its __dataHost matches `this`, meaning this dom-repeat stamped it\n if ((model = node.__templatizeInstance)) {\n // Found an element stamped by another template; keep walking up\n // from its __dataHost\n if (model.__dataHost != template) {\n node = model.__dataHost;\n } else {\n return model;\n }\n } else {\n // Still in a template scope, keep going up until\n // a __templatizeInstance is found\n node = node.parentNode;\n }\n }\n return null;\n}\n\nexport { TemplateInstanceBase };\n","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\nimport { TemplateInstanceBase, templatize, modelForElement } from '../utils/templatize.js'; // eslint-disable-line no-unused-vars\n\n/**\n * @typedef {{\n * _templatizerTemplate: HTMLTemplateElement,\n * _parentModel: boolean,\n * _instanceProps: Object,\n * _forwardHostPropV2: Function,\n * _notifyInstancePropV2: Function,\n * ctor: TemplateInstanceBase\n * }}\n */\nlet TemplatizerUser; // eslint-disable-line\n\n/**\n * The `Templatizer` behavior adds methods to generate instances of\n * templates that are each managed by an anonymous `PropertyEffects`\n * instance where data-bindings in the stamped template content are bound to\n * accessors on itself.\n *\n * This behavior is provided in Polymer 2.x-3.x as a hybrid-element convenience\n * only. For non-hybrid usage, the `Templatize` library\n * should be used instead.\n *\n * Example:\n *\n * import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';\n * // Get a template from somewhere, e.g. light DOM\n * let template = this.querySelector('template');\n * // Prepare the template\n * this.templatize(template);\n * // Instance the template with an initial data model\n * let instance = this.stamp({myProp: 'initial'});\n * // Insert the instance's DOM somewhere, e.g. light DOM\n * dom(this).appendChild(instance.root);\n * // Changing a property on the instance will propagate to bindings\n * // in the template\n * instance.myProp = 'new value';\n *\n * Users of `Templatizer` may need to implement the following abstract\n * API's to determine how properties and paths from the host should be\n * forwarded into to instances:\n *\n * _forwardHostPropV2: function(prop, value)\n *\n * Likewise, users may implement these additional abstract API's to determine\n * how instance-specific properties that change on the instance should be\n * forwarded out to the host, if necessary.\n *\n * _notifyInstancePropV2: function(inst, prop, value)\n *\n * In order to determine which properties are instance-specific and require\n * custom notification via `_notifyInstanceProp`, define an `_instanceProps`\n * object containing keys for each instance prop, for example:\n *\n * _instanceProps: {\n * item: true,\n * index: true\n * }\n *\n * Any properties used in the template that are not defined in _instanceProp\n * will be forwarded out to the Templatize `owner` automatically.\n *\n * Users may also implement the following abstract function to show or\n * hide any DOM generated using `stamp`:\n *\n * _showHideChildren: function(shouldHide)\n *\n * Note that some callbacks are suffixed with `V2` in the Polymer 2.x behavior\n * as the implementations will need to differ from the callbacks required\n * by the 1.x Templatizer API due to changes in the `TemplateInstance` API\n * between versions 1.x and 2.x.\n *\n * @polymerBehavior\n */\nexport const Templatizer = {\n\n /**\n * Generates an anonymous `TemplateInstance` class (stored as `this.ctor`)\n * for the provided template. This method should be called once per\n * template to prepare an element for stamping the template, followed\n * by `stamp` to create new instances of the template.\n *\n * @param {!HTMLTemplateElement} template Template to prepare\n * @param {boolean=} mutableData When `true`, the generated class will skip\n * strict dirty-checking for objects and arrays (always consider them to\n * be \"dirty\"). Defaults to false.\n * @return {void}\n * @this {TemplatizerUser}\n */\n templatize(template, mutableData) {\n this._templatizerTemplate = template;\n this.ctor = templatize(template, this, {\n mutableData: Boolean(mutableData),\n parentModel: this._parentModel,\n instanceProps: this._instanceProps,\n forwardHostProp: this._forwardHostPropV2,\n notifyInstanceProp: this._notifyInstancePropV2\n });\n },\n\n /**\n * Creates an instance of the template prepared by `templatize`. The object\n * returned is an instance of the anonymous class generated by `templatize`\n * whose `root` property is a document fragment containing newly cloned\n * template content, and which has property accessors corresponding to\n * properties referenced in template bindings.\n *\n * @param {Object=} model Object containing initial property values to\n * populate into the template bindings.\n * @return {TemplateInstanceBase} Returns the created instance of\n * the template prepared by `templatize`.\n * @this {TemplatizerUser}\n */\n stamp(model) {\n return new this.ctor(model);\n },\n\n /**\n * Returns the template \"model\" (`TemplateInstance`) associated with\n * a given element, which serves as the binding scope for the template\n * instance the element is contained in. A template model should be used\n * to manipulate data associated with this template instance.\n *\n * @param {HTMLElement} el Element for which to return a template model.\n * @return {TemplateInstanceBase} Model representing the binding scope for\n * the element.\n * @this {TemplatizerUser}\n */\n modelForElement(el) {\n return modelForElement(this._templatizerTemplate, el);\n }\n};\n","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\nimport '../utils/boot.js';\n\nimport { PropertyEffects } from '../mixins/property-effects.js';\nimport { OptionalMutableData } from '../mixins/mutable-data.js';\nimport { GestureEventListeners } from '../mixins/gesture-event-listeners.js';\nimport { strictTemplatePolicy } from '../utils/settings.js';\n\n/**\n * @constructor\n * @extends {HTMLElement}\n * @implements {Polymer_PropertyEffects}\n * @implements {Polymer_OptionalMutableData}\n * @implements {Polymer_GestureEventListeners}\n * @private\n */\nconst domBindBase =\n GestureEventListeners(\n OptionalMutableData(\n PropertyEffects(HTMLElement)));\n\n/**\n * Custom element to allow using Polymer's template features (data binding,\n * declarative event listeners, etc.) in the main document without defining\n * a new custom element.\n *\n * `` tags utilizing bindings may be wrapped with the ``\n * element, which will immediately stamp the wrapped template into the main\n * document and bind elements to the `dom-bind` element itself as the\n * binding scope.\n *\n * @polymer\n * @customElement\n * @appliesMixin PropertyEffects\n * @appliesMixin OptionalMutableData\n * @appliesMixin GestureEventListeners\n * @extends {domBindBase}\n * @summary Custom element to allow using Polymer's template features (data\n * binding, declarative event listeners, etc.) in the main document.\n */\nexport class DomBind extends domBindBase {\n\n static get observedAttributes() { return ['mutable-data']; }\n\n constructor() {\n super();\n if (strictTemplatePolicy) {\n throw new Error(`strictTemplatePolicy: dom-bind not allowed`);\n }\n this.root = null;\n this.$ = null;\n this.__children = null;\n }\n\n /**\n * @override\n * @return {void}\n */\n attributeChangedCallback() {\n // assumes only one observed attribute\n this.mutableData = true;\n }\n\n /**\n * @override\n * @return {void}\n */\n connectedCallback() {\n this.style.display = 'none';\n this.render();\n }\n\n /**\n * @override\n * @return {void}\n */\n disconnectedCallback() {\n this.__removeChildren();\n }\n\n __insertChildren() {\n this.parentNode.insertBefore(this.root, this);\n }\n\n __removeChildren() {\n if (this.__children) {\n for (let i=0; i {\n template = /** @type {HTMLTemplateElement} */(this.querySelector('template'));\n if (template) {\n observer.disconnect();\n this.render();\n } else {\n throw new Error('dom-bind requires a child');\n }\n });\n observer.observe(this, {childList: true});\n return;\n }\n this.root = this._stampTemplate(\n /** @type {!HTMLTemplateElement} */(template));\n this.$ = this.root.$;\n this.__children = [];\n for (let n=this.root.firstChild; n; n=n.nextSibling) {\n this.__children[this.__children.length] = n;\n }\n this._enableProperties();\n }\n this.__insertChildren();\n this.dispatchEvent(new CustomEvent('dom-change', {\n bubbles: true,\n composed: true\n }));\n }\n\n}\n\ncustomElements.define('dom-bind', DomBind);\n","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\nimport { PolymerElement } from '../../polymer-element.js';\n\nimport { TemplateInstanceBase, templatize, modelForElement } from '../utils/templatize.js'; // eslint-disable-line no-unused-vars\nimport { Debouncer } from '../utils/debounce.js';\nimport { enqueueDebouncer, flush } from '../utils/flush.js';\nimport { OptionalMutableData } from '../mixins/mutable-data.js';\nimport { matches, translate } from '../utils/path.js';\nimport { timeOut, microTask } from '../utils/async.js';\n\n/**\n * @constructor\n * @implements {Polymer_OptionalMutableData}\n * @extends {PolymerElement}\n * @private\n */\nconst domRepeatBase = OptionalMutableData(PolymerElement);\n\n/**\n * The `` element will automatically stamp and binds one instance\n * of template content to each object in a user-provided array.\n * `dom-repeat` accepts an `items` property, and one instance of the template\n * is stamped for each item into the DOM at the location of the `dom-repeat`\n * element. The `item` property will be set on each instance's binding\n * scope, thus templates should bind to sub-properties of `item`.\n *\n * Example:\n *\n * ```html\n * \n *\n * \n *\n *
Employee list:
\n * \n * \n *
First name: {{item.first}}
\n *
Last name: {{item.last}}
\n * \n * \n *\n * \n *\n * \n * ```\n *\n * With the following custom element definition:\n *\n * ```js\n * class EmployeeList extends PolymerElement {\n * static get is() { return 'employee-list'; }\n * static get properties() {\n * return {\n * employees: {\n * value() {\n * return [\n * {first: 'Bob', last: 'Smith'},\n * {first: 'Sally', last: 'Johnson'},\n * ...\n * ];\n * }\n * }\n * };\n * }\n * }\n * ```\n *\n * Notifications for changes to items sub-properties will be forwarded to template\n * instances, which will update via the normal structured data notification system.\n *\n * Mutations to the `items` array itself should be made using the Array\n * mutation API's on the PropertyEffects mixin (`push`, `pop`, `splice`,\n * `shift`, `unshift`), and template instances will be kept in sync with the\n * data in the array.\n *\n * Events caught by event handlers within the `dom-repeat` template will be\n * decorated with a `model` property, which represents the binding scope for\n * each template instance. The model should be used to manipulate data on the\n * instance, for example `event.model.set('item.checked', true);`.\n *\n * Alternatively, the model for a template instance for an element stamped by\n * a `dom-repeat` can be obtained using the `modelForElement` API on the\n * `dom-repeat` that stamped it, for example\n * `this.$.domRepeat.modelForElement(event.target).set('item.checked', true);`.\n * This may be useful for manipulating instance data of event targets obtained\n * by event handlers on parents of the `dom-repeat` (event delegation).\n *\n * A view-specific filter/sort may be applied to each `dom-repeat` by supplying a\n * `filter` and/or `sort` property. This may be a string that names a function on\n * the host, or a function may be assigned to the property directly. The functions\n * should implemented following the standard `Array` filter/sort API.\n *\n * In order to re-run the filter or sort functions based on changes to sub-fields\n * of `items`, the `observe` property may be set as a space-separated list of\n * `item` sub-fields that should cause a re-filter/sort when modified. If\n * the filter or sort function depends on properties not contained in `items`,\n * the user should observe changes to those properties and call `render` to update\n * the view based on the dependency change.\n *\n * For example, for an `dom-repeat` with a filter of the following:\n *\n * ```js\n * isEngineer(item) {\n * return item.type == 'engineer' || item.manager.type == 'engineer';\n * }\n * ```\n *\n * Then the `observe` property should be configured as follows:\n *\n * ```html\n * \n * ```\n *\n * @customElement\n * @polymer\n * @extends {domRepeatBase}\n * @appliesMixin OptionalMutableData\n * @summary Custom element for stamping instance of a template bound to\n * items in an array.\n */\nexport class DomRepeat extends domRepeatBase {\n\n // Not needed to find template; can be removed once the analyzer\n // can find the tag name from customElements.define call\n static get is() { return 'dom-repeat'; }\n\n static get template() { return null; }\n\n static get properties() {\n\n /**\n * Fired whenever DOM is added or removed by this template (by\n * default, rendering occurs lazily). To force immediate rendering, call\n * `render`.\n *\n * @event dom-change\n */\n return {\n\n /**\n * An array containing items determining how many instances of the template\n * to stamp and that that each template instance should bind to.\n */\n items: {\n type: Array\n },\n\n /**\n * The name of the variable to add to the binding scope for the array\n * element associated with a given template instance.\n */\n as: {\n type: String,\n value: 'item'\n },\n\n /**\n * The name of the variable to add to the binding scope with the index\n * of the instance in the sorted and filtered list of rendered items.\n * Note, for the index in the `this.items` array, use the value of the\n * `itemsIndexAs` property.\n */\n indexAs: {\n type: String,\n value: 'index'\n },\n\n /**\n * The name of the variable to add to the binding scope with the index\n * of the instance in the `this.items` array. Note, for the index of\n * this instance in the sorted and filtered list of rendered items,\n * use the value of the `indexAs` property.\n */\n itemsIndexAs: {\n type: String,\n value: 'itemsIndex'\n },\n\n /**\n * A function that should determine the sort order of the items. This\n * property should either be provided as a string, indicating a method\n * name on the element's host, or else be an actual function. The\n * function should match the sort function passed to `Array.sort`.\n * Using a sort function has no effect on the underlying `items` array.\n */\n sort: {\n type: Function,\n observer: '__sortChanged'\n },\n\n /**\n * A function that can be used to filter items out of the view. This\n * property should either be provided as a string, indicating a method\n * name on the element's host, or else be an actual function. The\n * function should match the sort function passed to `Array.filter`.\n * Using a filter function has no effect on the underlying `items` array.\n */\n filter: {\n type: Function,\n observer: '__filterChanged'\n },\n\n /**\n * When using a `filter` or `sort` function, the `observe` property\n * should be set to a space-separated list of the names of item\n * sub-fields that should trigger a re-sort or re-filter when changed.\n * These should generally be fields of `item` that the sort or filter\n * function depends on.\n */\n observe: {\n type: String,\n observer: '__observeChanged'\n },\n\n /**\n * When using a `filter` or `sort` function, the `delay` property\n * determines a debounce time in ms after a change to observed item\n * properties that must pass before the filter or sort is re-run.\n * This is useful in rate-limiting shuffling of the view when\n * item changes may be frequent.\n */\n delay: Number,\n\n /**\n * Count of currently rendered items after `filter` (if any) has been applied.\n * If \"chunking mode\" is enabled, `renderedItemCount` is updated each time a\n * set of template instances is rendered.\n *\n */\n renderedItemCount: {\n type: Number,\n notify: true,\n readOnly: true\n },\n\n /**\n * Defines an initial count of template instances to render after setting\n * the `items` array, before the next paint, and puts the `dom-repeat`\n * into \"chunking mode\". The remaining items will be created and rendered\n * incrementally at each animation frame therof until all instances have\n * been rendered.\n */\n initialCount: {\n type: Number,\n observer: '__initializeChunking'\n },\n\n /**\n * When `initialCount` is used, this property defines a frame rate (in\n * fps) to target by throttling the number of instances rendered each\n * frame to not exceed the budget for the target frame rate. The\n * framerate is effectively the number of `requestAnimationFrame`s that\n * it tries to allow to actually fire in a given second. It does this\n * by measuring the time between `rAF`s and continuously adjusting the\n * number of items created each `rAF` to maintain the target framerate.\n * Setting this to a higher number allows lower latency and higher\n * throughput for event handlers and other tasks, but results in a\n * longer time for the remaining items to complete rendering.\n */\n targetFramerate: {\n type: Number,\n value: 20\n },\n\n _targetFrameTime: {\n type: Number,\n computed: '__computeFrameTime(targetFramerate)'\n }\n\n };\n\n }\n\n static get observers() {\n return [ '__itemsChanged(items.*)' ];\n }\n\n constructor() {\n super();\n this.__instances = [];\n this.__limit = Infinity;\n this.__pool = [];\n this.__renderDebouncer = null;\n this.__itemsIdxToInstIdx = {};\n this.__chunkCount = null;\n this.__lastChunkTime = null;\n this.__sortFn = null;\n this.__filterFn = null;\n this.__observePaths = null;\n /** @type {?function(new:Polymer.TemplateInstanceBase, *)} */\n this.__ctor = null;\n this.__isDetached = true;\n this.template = null;\n }\n\n /**\n * @override\n * @return {void}\n */\n disconnectedCallback() {\n super.disconnectedCallback();\n this.__isDetached = true;\n for (let i=0; i {\n if (this.querySelector('template')) {\n observer.disconnect();\n this.__render();\n } else {\n throw new Error('dom-repeat requires a child');\n }\n });\n observer.observe(this, {childList: true});\n return false;\n }\n // Template instance props that should be excluded from forwarding\n let instanceProps = {};\n instanceProps[this.as] = true;\n instanceProps[this.indexAs] = true;\n instanceProps[this.itemsIndexAs] = true;\n this.__ctor = templatize(template, this, {\n mutableData: this.mutableData,\n parentModel: true,\n instanceProps: instanceProps,\n /**\n * @this {DomRepeat}\n * @param {string} prop Property to set\n * @param {*} value Value to set property to\n */\n forwardHostProp: function(prop, value) {\n let i$ = this.__instances;\n for (let i=0, inst; (ithis.__renderChunk());\n }\n\n __renderChunk() {\n // Simple auto chunkSize throttling algorithm based on feedback loop:\n // measure actual time between frames and scale chunk count by ratio\n // of target/actual frame time\n let currChunkTime = performance.now();\n let ratio = this._targetFrameTime / (currChunkTime - this.__lastChunkTime);\n this.__chunkCount = Math.round(this.__chunkCount * ratio) || 1;\n this.__limit += this.__chunkCount;\n this.__lastChunkTime = currChunkTime;\n this.__debounceRender(this.__render);\n }\n\n __observeChanged() {\n this.__observePaths = this.observe &&\n this.observe.replace('.*', '.').split(' ');\n }\n\n __itemsChanged(change) {\n if (this.items && !Array.isArray(this.items)) {\n console.warn('dom-repeat expected array for `items`, found', this.items);\n }\n // If path was to an item (e.g. 'items.3' or 'items.3.foo'), forward the\n // path to that instance synchronously (returns false for non-item paths)\n if (!this.__handleItemPath(change.path, change.value)) {\n // Otherwise, the array was reset ('items') or spliced ('items.splices'),\n // so queue a full refresh\n this.__initializeChunking();\n this.__debounceRender(this.__render);\n }\n }\n\n __handleObservedPaths(path) {\n // Handle cases where path changes should cause a re-sort/filter\n if (this.__sortFn || this.__filterFn) {\n if (!path) {\n // Always re-render if the item itself changed\n this.__debounceRender(this.__render, this.delay);\n } else if (this.__observePaths) {\n // Otherwise, re-render if the path changed matches an observed path\n let paths = this.__observePaths;\n for (let i=0; i 0 ? timeOut.after(delay) : microTask\n , fn.bind(this));\n enqueueDebouncer(this.__renderDebouncer);\n }\n\n /**\n * Forces the element to render its content. Normally rendering is\n * asynchronous to a provoking change. This is done for efficiency so\n * that multiple changes trigger only a single render. The render method\n * should be called if, for example, template rendering is required to\n * validate application state.\n * @return {void}\n */\n render() {\n // Queue this repeater, then flush all in order\n this.__debounceRender(this.__render);\n flush();\n }\n\n __render() {\n if (!this.__ensureTemplatized()) {\n // No template found yet\n return;\n }\n this.__applyFullRefresh();\n // Reset the pool\n // TODO(kschaaf): Reuse pool across turns and nested templates\n // Now that objects/arrays are re-evaluated when set, we can safely\n // reuse pooled instances across turns, however we still need to decide\n // semantics regarding how long to hold, how many to hold, etc.\n this.__pool.length = 0;\n // Set rendered item count\n this._setRenderedItemCount(this.__instances.length);\n // Notify users\n this.dispatchEvent(new CustomEvent('dom-change', {\n bubbles: true,\n composed: true\n }));\n // Check to see if we need to render more items\n this.__tryRenderChunk();\n }\n\n __applyFullRefresh() {\n let items = this.items || [];\n let isntIdxToItemsIdx = new Array(items.length);\n for (let i=0; i\n this.__filterFn(items[i], idx, array));\n }\n // Apply user sort\n if (this.__sortFn) {\n isntIdxToItemsIdx.sort((a, b) => this.__sortFn(items[a], items[b]));\n }\n // items->inst map kept for item path forwarding\n const itemsIdxToInstIdx = this.__itemsIdxToInstIdx = {};\n let instIdx = 0;\n // Generate instances and assign items\n const limit = Math.min(isntIdxToItemsIdx.length, this.__limit);\n for (; instIdx=instIdx; i--) {\n this.__detachAndRemoveInstance(i);\n }\n }\n\n __detachInstance(idx) {\n let inst = this.__instances[idx];\n for (let i=0; i. path change,\n // responsible for notifying item. changes to inst for key\n __handleItemPath(path, value) {\n let itemsPath = path.slice(6); // 'items.'.length == 6\n let dot = itemsPath.indexOf('.');\n let itemsIdx = dot < 0 ? itemsPath : itemsPath.substring(0, dot);\n // If path was index into array...\n if (itemsIdx == parseInt(itemsIdx, 10)) {\n let itemSubPath = dot < 0 ? '' : itemsPath.substring(dot+1);\n // If the path is observed, it will trigger a full refresh\n this.__handleObservedPaths(itemSubPath);\n // Note, even if a rull refresh is triggered, always do the path\n // notification because unless mutableData is used for dom-repeat\n // and all elements in the instance subtree, a full refresh may\n // not trigger the proper update.\n let instIdx = this.__itemsIdxToInstIdx[itemsIdx];\n let inst = this.__instances[instIdx];\n if (inst) {\n let itemPath = this.as + (itemSubPath ? '.' + itemSubPath : '');\n // This is effectively `notifyPath`, but avoids some of the overhead\n // of the public API\n inst._setPendingPropertyOrPath(itemPath, value, false, true);\n inst._flushProperties();\n }\n return true;\n }\n }\n\n /**\n * Returns the item associated with a given element stamped by\n * this `dom-repeat`.\n *\n * Note, to modify sub-properties of the item,\n * `modelForElement(el).set('item.', value)`\n * should be used.\n *\n * @param {!HTMLElement} el Element for which to return the item.\n * @return {*} Item associated with the element.\n */\n itemForElement(el) {\n let instance = this.modelForElement(el);\n return instance && instance[this.as];\n }\n\n /**\n * Returns the inst index for a given element stamped by this `dom-repeat`.\n * If `sort` is provided, the index will reflect the sorted order (rather\n * than the original array order).\n *\n * @param {!HTMLElement} el Element for which to return the index.\n * @return {?number} Row index associated with the element (note this may\n * not correspond to the array index if a user `sort` is applied).\n */\n indexForElement(el) {\n let instance = this.modelForElement(el);\n return instance && instance[this.indexAs];\n }\n\n /**\n * Returns the template \"model\" associated with a given element, which\n * serves as the binding scope for the template instance the element is\n * contained in. A template model\n * should be used to manipulate data associated with this template instance.\n *\n * Example:\n *\n * let model = modelForElement(el);\n * if (model.index < 10) {\n * model.set('item.checked', true);\n * }\n *\n * @param {!HTMLElement} el Element for which to return a template model.\n * @return {TemplateInstanceBase} Model representing the binding scope for\n * the element.\n */\n modelForElement(el) {\n return modelForElement(this.template, el);\n }\n\n}\n\ncustomElements.define(DomRepeat.is, DomRepeat);\n","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\nimport { PolymerElement } from '../../polymer-element.js';\n\nimport { templatize } from '../utils/templatize.js';\nimport { Debouncer } from '../utils/debounce.js';\nimport { enqueueDebouncer, flush } from '../utils/flush.js';\nimport { microTask } from '../utils/async.js';\nimport { root } from '../utils/path.js';\n\n/**\n * The `` element will stamp a light-dom `` child when\n * the `if` property becomes truthy, and the template can use Polymer\n * data-binding and declarative event features when used in the context of\n * a Polymer element's template.\n *\n * When `if` becomes falsy, the stamped content is hidden but not\n * removed from dom. When `if` subsequently becomes truthy again, the content\n * is simply re-shown. This approach is used due to its favorable performance\n * characteristics: the expense of creating template content is paid only\n * once and lazily.\n *\n * Set the `restamp` property to true to force the stamped content to be\n * created / destroyed when the `if` condition changes.\n *\n * @customElement\n * @polymer\n * @extends PolymerElement\n * @summary Custom element that conditionally stamps and hides or removes\n * template content based on a boolean flag.\n */\nexport class DomIf extends PolymerElement {\n\n // Not needed to find template; can be removed once the analyzer\n // can find the tag name from customElements.define call\n static get is() { return 'dom-if'; }\n\n static get template() { return null; }\n\n static get properties() {\n\n return {\n\n /**\n * Fired whenever DOM is added or removed/hidden by this template (by\n * default, rendering occurs lazily). To force immediate rendering, call\n * `render`.\n *\n * @event dom-change\n */\n\n /**\n * A boolean indicating whether this template should stamp.\n */\n if: {\n type: Boolean,\n observer: '__debounceRender'\n },\n\n /**\n * When true, elements will be removed from DOM and discarded when `if`\n * becomes false and re-created and added back to the DOM when `if`\n * becomes true. By default, stamped elements will be hidden but left\n * in the DOM when `if` becomes false, which is generally results\n * in better performance.\n */\n restamp: {\n type: Boolean,\n observer: '__debounceRender'\n }\n\n };\n\n }\n\n constructor() {\n super();\n this.__renderDebouncer = null;\n this.__invalidProps = null;\n this.__instance = null;\n this._lastIf = false;\n this.__ctor = null;\n this.__hideTemplateChildren__ = false;\n }\n\n __debounceRender() {\n // Render is async for 2 reasons:\n // 1. To eliminate dom creation trashing if user code thrashes `if` in the\n // same turn. This was more common in 1.x where a compound computed\n // property could result in the result changing multiple times, but is\n // mitigated to a large extent by batched property processing in 2.x.\n // 2. To avoid double object propagation when a bag including values bound\n // to the `if` property as well as one or more hostProps could enqueue\n // the to flush before the 's host property\n // forwarding. In that scenario creating an instance would result in\n // the host props being set once, and then the enqueued changes on the\n // template would set properties a second time, potentially causing an\n // object to be set to an instance more than once. Creating the\n // instance async from flushing data ensures this doesn't happen. If\n // we wanted a sync option in the future, simply having flush\n // (or clear) its template's pending host properties before creating\n // the instance would also avoid the problem.\n this.__renderDebouncer = Debouncer.debounce(\n this.__renderDebouncer\n , microTask\n , () => this.__render());\n enqueueDebouncer(this.__renderDebouncer);\n }\n\n /**\n * @override\n * @return {void}\n */\n disconnectedCallback() {\n super.disconnectedCallback();\n if (!this.parentNode ||\n (this.parentNode.nodeType == Node.DOCUMENT_FRAGMENT_NODE &&\n !this.parentNode.host)) {\n this.__teardownInstance();\n }\n }\n\n /**\n * @override\n * @return {void}\n */\n connectedCallback() {\n super.connectedCallback();\n this.style.display = 'none';\n if (this.if) {\n this.__debounceRender();\n }\n }\n\n /**\n * Forces the element to render its content. Normally rendering is\n * asynchronous to a provoking change. This is done for efficiency so\n * that multiple changes trigger only a single render. The render method\n * should be called if, for example, template rendering is required to\n * validate application state.\n * @return {void}\n */\n render() {\n flush();\n }\n\n __render() {\n if (this.if) {\n if (!this.__ensureInstance()) {\n // No template found yet\n return;\n }\n this._showHideChildren();\n } else if (this.restamp) {\n this.__teardownInstance();\n }\n if (!this.restamp && this.__instance) {\n this._showHideChildren();\n }\n if (this.if != this._lastIf) {\n this.dispatchEvent(new CustomEvent('dom-change', {\n bubbles: true,\n composed: true\n }));\n this._lastIf = this.if;\n }\n }\n\n __ensureInstance() {\n let parentNode = this.parentNode;\n // Guard against element being detached while render was queued\n if (parentNode) {\n if (!this.__ctor) {\n let template = /** @type {HTMLTemplateElement} */(this.querySelector('template'));\n if (!template) {\n // Wait until childList changes and template should be there by then\n let observer = new MutationObserver(() => {\n if (this.querySelector('template')) {\n observer.disconnect();\n this.__render();\n } else {\n throw new Error('dom-if requires a child');\n }\n });\n observer.observe(this, {childList: true});\n return false;\n }\n this.__ctor = templatize(template, this, {\n // dom-if templatizer instances require `mutable: true`, as\n // `__syncHostProperties` relies on that behavior to sync objects\n mutableData: true,\n /**\n * @param {string} prop Property to forward\n * @param {*} value Value of property\n * @this {DomIf}\n */\n forwardHostProp: function(prop, value) {\n if (this.__instance) {\n if (this.if) {\n this.__instance.forwardHostProp(prop, value);\n } else {\n // If we have an instance but are squelching host property\n // forwarding due to if being false, note the invalidated\n // properties so `__syncHostProperties` can sync them the next\n // time `if` becomes true\n this.__invalidProps = this.__invalidProps || Object.create(null);\n this.__invalidProps[root(prop)] = true;\n }\n }\n }\n });\n }\n if (!this.__instance) {\n this.__instance = new this.__ctor();\n parentNode.insertBefore(this.__instance.root, this);\n } else {\n this.__syncHostProperties();\n let c$ = this.__instance.children;\n if (c$ && c$.length) {\n // Detect case where dom-if was re-attached in new position\n let lastChild = this.previousSibling;\n if (lastChild !== c$[c$.length-1]) {\n for (let i=0, n; (i {\n\n /**\n * @constructor\n * @extends {superClass}\n * @implements {Polymer_ElementMixin}\n * @private\n */\n let elementBase = ElementMixin(superClass);\n\n /**\n * @polymer\n * @mixinClass\n * @implements {Polymer_ArraySelectorMixin}\n * @unrestricted\n */\n class ArraySelectorMixin extends elementBase {\n\n static get properties() {\n\n return {\n\n /**\n * An array containing items from which selection will be made.\n */\n items: {\n type: Array,\n },\n\n /**\n * When `true`, multiple items may be selected at once (in this case,\n * `selected` is an array of currently selected items). When `false`,\n * only one item may be selected at a time.\n */\n multi: {\n type: Boolean,\n value: false,\n },\n\n /**\n * When `multi` is true, this is an array that contains any selected.\n * When `multi` is false, this is the currently selected item, or `null`\n * if no item is selected.\n * @type {?(Object|Array)}\n */\n selected: {\n type: Object,\n notify: true\n },\n\n /**\n * When `multi` is false, this is the currently selected item, or `null`\n * if no item is selected.\n * @type {?Object}\n */\n selectedItem: {\n type: Object,\n notify: true\n },\n\n /**\n * When `true`, calling `select` on an item that is already selected\n * will deselect the item.\n */\n toggle: {\n type: Boolean,\n value: false\n }\n\n };\n }\n\n static get observers() {\n return ['__updateSelection(multi, items.*)'];\n }\n\n constructor() {\n super();\n this.__lastItems = null;\n this.__lastMulti = null;\n this.__selectedMap = null;\n }\n\n __updateSelection(multi, itemsInfo) {\n let path = itemsInfo.path;\n if (path == 'items') {\n // Case 1 - items array changed, so diff against previous array and\n // deselect any removed items and adjust selected indices\n let newItems = itemsInfo.base || [];\n let lastItems = this.__lastItems;\n let lastMulti = this.__lastMulti;\n if (multi !== lastMulti) {\n this.clearSelection();\n }\n if (lastItems) {\n let splices = calculateSplices(newItems, lastItems);\n this.__applySplices(splices);\n }\n this.__lastItems = newItems;\n this.__lastMulti = multi;\n } else if (itemsInfo.path == 'items.splices') {\n // Case 2 - got specific splice information describing the array mutation:\n // deselect any removed items and adjust selected indices\n this.__applySplices(itemsInfo.value.indexSplices);\n } else {\n // Case 3 - an array element was changed, so deselect the previous\n // item for that index if it was previously selected\n let part = path.slice('items.'.length);\n let idx = parseInt(part, 10);\n if ((part.indexOf('.') < 0) && part == idx) {\n this.__deselectChangedIdx(idx);\n }\n }\n }\n\n __applySplices(splices) {\n let selected = this.__selectedMap;\n // Adjust selected indices and mark removals\n for (let i=0; i {\n if (idx < s.index) {\n // no change\n } else if (idx >= s.index + s.removed.length) {\n // adjust index\n selected.set(item, idx + s.addedCount - s.removed.length);\n } else {\n // remove index\n selected.set(item, -1);\n }\n });\n for (let j=0; j {\n if (idx < 0) {\n if (this.multi) {\n this.splice('selected', sidx, 1);\n } else {\n this.selected = this.selectedItem = null;\n }\n selected.delete(item);\n } else {\n sidx++;\n }\n });\n }\n\n __updateLinks() {\n this.__dataLinkedPaths = {};\n if (this.multi) {\n let sidx = 0;\n this.__selectedMap.forEach(idx => {\n if (idx >= 0) {\n this.linkPaths('items.' + idx, 'selected.' + sidx++);\n }\n });\n } else {\n this.__selectedMap.forEach(idx => {\n this.linkPaths('selected', 'items.' + idx);\n this.linkPaths('selectedItem', 'items.' + idx);\n });\n }\n }\n\n /**\n * Clears the selection state.\n * @return {void}\n */\n clearSelection() {\n // Unbind previous selection\n this.__dataLinkedPaths = {};\n // The selected map stores 3 pieces of information:\n // key: items array object\n // value: items array index\n // order: selected array index\n this.__selectedMap = new Map();\n // Initialize selection\n this.selected = this.multi ? [] : null;\n this.selectedItem = null;\n }\n\n /**\n * Returns whether the item is currently selected.\n *\n * @param {*} item Item from `items` array to test\n * @return {boolean} Whether the item is selected\n */\n isSelected(item) {\n return this.__selectedMap.has(item);\n }\n\n /**\n * Returns whether the item is currently selected.\n *\n * @param {number} idx Index from `items` array to test\n * @return {boolean} Whether the item is selected\n */\n isIndexSelected(idx) {\n return this.isSelected(this.items[idx]);\n }\n\n __deselectChangedIdx(idx) {\n let sidx = this.__selectedIndexForItemIndex(idx);\n if (sidx >= 0) {\n let i = 0;\n this.__selectedMap.forEach((idx, item) => {\n if (sidx == i++) {\n this.deselect(item);\n }\n });\n }\n }\n\n __selectedIndexForItemIndex(idx) {\n let selected = this.__dataLinkedPaths['items.' + idx];\n if (selected) {\n return parseInt(selected.slice('selected.'.length), 10);\n }\n }\n\n /**\n * Deselects the given item if it is already selected.\n *\n * @param {*} item Item from `items` array to deselect\n * @return {void}\n */\n deselect(item) {\n let idx = this.__selectedMap.get(item);\n if (idx >= 0) {\n this.__selectedMap.delete(item);\n let sidx;\n if (this.multi) {\n sidx = this.__selectedIndexForItemIndex(idx);\n }\n this.__updateLinks();\n if (this.multi) {\n this.splice('selected', sidx, 1);\n } else {\n this.selected = this.selectedItem = null;\n }\n }\n }\n\n /**\n * Deselects the given index if it is already selected.\n *\n * @param {number} idx Index from `items` array to deselect\n * @return {void}\n */\n deselectIndex(idx) {\n this.deselect(this.items[idx]);\n }\n\n /**\n * Selects the given item. When `toggle` is true, this will automatically\n * deselect the item if already selected.\n *\n * @param {*} item Item from `items` array to select\n * @return {void}\n */\n select(item) {\n this.selectIndex(this.items.indexOf(item));\n }\n\n /**\n * Selects the given index. When `toggle` is true, this will automatically\n * deselect the item if already selected.\n *\n * @param {number} idx Index from `items` array to select\n * @return {void}\n */\n selectIndex(idx) {\n let item = this.items[idx];\n if (!this.isSelected(item)) {\n if (!this.multi) {\n this.__selectedMap.clear();\n }\n this.__selectedMap.set(item, idx);\n this.__updateLinks();\n if (this.multi) {\n this.push('selected', item);\n } else {\n this.selected = this.selectedItem = item;\n }\n } else if (this.toggle) {\n this.deselectIndex(idx);\n }\n }\n\n }\n\n return ArraySelectorMixin;\n\n});\n\n// export mixin\nexport { ArraySelectorMixin };\n\n/**\n * @constructor\n * @extends {PolymerElement}\n * @implements {Polymer_ArraySelectorMixin}\n * @private\n */\nlet baseArraySelector = ArraySelectorMixin(PolymerElement);\n\n/**\n * Element implementing the `ArraySelector` mixin, which records\n * dynamic associations between item paths in a master `items` array and a\n * `selected` array such that path changes to the master array (at the host)\n * element or elsewhere via data-binding) are correctly propagated to items\n * in the selected array and vice-versa.\n *\n * The `items` property accepts an array of user data, and via the\n * `select(item)` and `deselect(item)` API, updates the `selected` property\n * which may be bound to other parts of the application, and any changes to\n * sub-fields of `selected` item(s) will be kept in sync with items in the\n * `items` array. When `multi` is false, `selected` is a property\n * representing the last selected item. When `multi` is true, `selected`\n * is an array of multiply selected items.\n *\n * Example:\n *\n * ```js\n * import {PolymerElement} from '@polymer/polymer';\n * import '@polymer/polymer/lib/elements/array-selector.js';\n *\n * class EmployeeList extends PolymerElement {\n * static get _template() {\n * return html`\n *
Employee list:
\n * \n * \n *
First name: {{item.first}}
\n *
Last name: {{item.last}}
\n * \n * \n * \n *\n * \n *\n *
Selected employees:
\n * \n * \n *
First name: {{item.first}}
\n *
Last name: {{item.last}}
\n * \n * `;\n * }\n * static get is() { return 'employee-list'; }\n * static get properties() {\n * return {\n * employees: {\n * value() {\n * return [\n * {first: 'Bob', last: 'Smith'},\n * {first: 'Sally', last: 'Johnson'},\n * ...\n * ];\n * }\n * }\n * };\n * }\n * toggleSelection(e) {\n * const item = this.$.employeeList.itemForElement(e.target);\n * this.$.selector.select(item);\n * }\n * }\n * ```\n *\n * @polymer\n * @customElement\n * @extends {baseArraySelector}\n * @appliesMixin ArraySelectorMixin\n * @summary Custom element that links paths between an input `items` array and\n * an output `selected` item or array based on calls to its selection API.\n */\nclass ArraySelector extends baseArraySelector {\n // Not needed to find template; can be removed once the analyzer\n // can find the tag name from customElements.define call\n static get is() { return 'array-selector'; }\n}\ncustomElements.define(ArraySelector.is, ArraySelector);\nexport { ArraySelector };\n","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\nimport { MutableData } from '../mixins/mutable-data.js';\n\nlet mutablePropertyChange;\n/** @suppress {missingProperties} */\n(() => {\n mutablePropertyChange = MutableData._mutablePropertyChange;\n})();\n\n/**\n * Legacy element behavior to skip strict dirty-checking for objects and arrays,\n * (always consider them to be \"dirty\") for use on legacy API Polymer elements.\n *\n * By default, `Polymer.PropertyEffects` performs strict dirty checking on\n * objects, which means that any deep modifications to an object or array will\n * not be propagated unless \"immutable\" data patterns are used (i.e. all object\n * references from the root to the mutation were changed).\n *\n * Polymer also provides a proprietary data mutation and path notification API\n * (e.g. `notifyPath`, `set`, and array mutation API's) that allow efficient\n * mutation and notification of deep changes in an object graph to all elements\n * bound to the same object graph.\n *\n * In cases where neither immutable patterns nor the data mutation API can be\n * used, applying this mixin will cause Polymer to skip dirty checking for\n * objects and arrays (always consider them to be \"dirty\"). This allows a\n * user to make a deep modification to a bound object graph, and then either\n * simply re-set the object (e.g. `this.items = this.items`) or call `notifyPath`\n * (e.g. `this.notifyPath('items')`) to update the tree. Note that all\n * elements that wish to be updated based on deep mutations must apply this\n * mixin or otherwise skip strict dirty checking for objects/arrays.\n * Specifically, any elements in the binding tree between the source of a\n * mutation and the consumption of it must apply this behavior or enable the\n * `Polymer.OptionalMutableDataBehavior`.\n *\n * In order to make the dirty check strategy configurable, see\n * `Polymer.OptionalMutableDataBehavior`.\n *\n * Note, the performance characteristics of propagating large object graphs\n * will be worse as opposed to using strict dirty checking with immutable\n * patterns or Polymer's path notification API.\n *\n * @polymerBehavior\n * @summary Behavior to skip strict dirty-checking for objects and\n * arrays\n */\nexport const MutableDataBehavior = {\n\n /**\n * Overrides `Polymer.PropertyEffects` to provide option for skipping\n * strict equality checking for Objects and Arrays.\n *\n * This method pulls the value to dirty check against from the `__dataTemp`\n * cache (rather than the normal `__data` cache) for Objects. Since the temp\n * cache is cleared at the end of a turn, this implementation allows\n * side-effects of deep object changes to be processed by re-setting the\n * same object (using the temp cache as an in-turn backstop to prevent\n * cycles due to 2-way notification).\n *\n * @param {string} property Property name\n * @param {*} value New property value\n * @param {*} old Previous property value\n * @return {boolean} Whether the property should be considered a change\n * @protected\n */\n _shouldPropertyChange(property, value, old) {\n return mutablePropertyChange(this, property, value, old, true);\n }\n};\n\n/**\n * Legacy element behavior to add the optional ability to skip strict\n * dirty-checking for objects and arrays (always consider them to be\n * \"dirty\") by setting a `mutable-data` attribute on an element instance.\n *\n * By default, `Polymer.PropertyEffects` performs strict dirty checking on\n * objects, which means that any deep modifications to an object or array will\n * not be propagated unless \"immutable\" data patterns are used (i.e. all object\n * references from the root to the mutation were changed).\n *\n * Polymer also provides a proprietary data mutation and path notification API\n * (e.g. `notifyPath`, `set`, and array mutation API's) that allow efficient\n * mutation and notification of deep changes in an object graph to all elements\n * bound to the same object graph.\n *\n * In cases where neither immutable patterns nor the data mutation API can be\n * used, applying this mixin will allow Polymer to skip dirty checking for\n * objects and arrays (always consider them to be \"dirty\"). This allows a\n * user to make a deep modification to a bound object graph, and then either\n * simply re-set the object (e.g. `this.items = this.items`) or call `notifyPath`\n * (e.g. `this.notifyPath('items')`) to update the tree. Note that all\n * elements that wish to be updated based on deep mutations must apply this\n * mixin or otherwise skip strict dirty checking for objects/arrays.\n * Specifically, any elements in the binding tree between the source of a\n * mutation and the consumption of it must enable this behavior or apply the\n * `Polymer.OptionalMutableDataBehavior`.\n *\n * While this behavior adds the ability to forgo Object/Array dirty checking,\n * the `mutableData` flag defaults to false and must be set on the instance.\n *\n * Note, the performance characteristics of propagating large object graphs\n * will be worse by relying on `mutableData: true` as opposed to using\n * strict dirty checking with immutable patterns or Polymer's path notification\n * API.\n *\n * @polymerBehavior\n * @summary Behavior to optionally skip strict dirty-checking for objects and\n * arrays\n */\nexport const OptionalMutableDataBehavior = {\n\n properties: {\n /**\n * Instance-level flag for configuring the dirty-checking strategy\n * for this element. When true, Objects and Arrays will skip dirty\n * checking, otherwise strict equality checking will be used.\n */\n mutableData: Boolean\n },\n\n /**\n * Overrides `Polymer.PropertyEffects` to skip strict equality checking\n * for Objects and Arrays.\n *\n * Pulls the value to dirty check against from the `__dataTemp` cache\n * (rather than the normal `__data` cache) for Objects. Since the temp\n * cache is cleared at the end of a turn, this implementation allows\n * side-effects of deep object changes to be processed by re-setting the\n * same object (using the temp cache as an in-turn backstop to prevent\n * cycles due to 2-way notification).\n *\n * @param {string} property Property name\n * @param {*} value New property value\n * @param {*} old Previous property value\n * @return {boolean} Whether the property should be considered a change\n * @this {this}\n * @protected\n */\n _shouldPropertyChange(property, value, old) {\n return mutablePropertyChange(this, property, value, old, this.mutableData);\n }\n};\n","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\nimport { LegacyElementMixin } from './lib/legacy/legacy-element-mixin.js';\nexport { Polymer } from './lib/legacy/polymer-fn.js';\n/* template elements */\nimport './lib/legacy/templatizer-behavior.js';\nimport './lib/elements/dom-bind.js';\nimport './lib/elements/dom-repeat.js';\nimport './lib/elements/dom-if.js';\nimport './lib/elements/array-selector.js';\n/* custom-style */\nimport './lib/elements/custom-style.js';\n/* bc behaviors */\nimport './lib/legacy/mutable-data-behavior.js';\n/* import html-tag to export html */\nexport { html } from './lib/utils/html-tag.js';\n\n// bc\nexport const Base = LegacyElementMixin(HTMLElement).prototype;\n","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\nimport './boot.js';\n\n/**\n * Class representing a static string value which can be used to filter\n * strings by asseting that they have been created via this class. The\n * `value` property returns the string passed to the constructor.\n */\nclass LiteralString {\n constructor(string) {\n /** @type {string} */\n this.value = string.toString();\n }\n /**\n * @return {string} LiteralString string value\n * @override\n */\n toString() {\n return this.value;\n }\n}\n\n/**\n * @param {*} value Object to stringify into HTML\n * @return {string} HTML stringified form of `obj`\n */\nfunction literalValue(value) {\n if (value instanceof LiteralString) {\n return /** @type {!LiteralString} */(value).value;\n } else {\n throw new Error(\n `non-literal value passed to Polymer's htmlLiteral function: ${value}`\n );\n }\n}\n\n/**\n * @param {*} value Object to stringify into HTML\n * @return {string} HTML stringified form of `obj`\n */\nfunction htmlValue(value) {\n if (value instanceof HTMLTemplateElement) {\n return /** @type {!HTMLTemplateElement } */(value).innerHTML;\n } else if (value instanceof LiteralString) {\n return literalValue(value);\n } else {\n throw new Error(\n `non-template value passed to Polymer's html function: ${value}`);\n }\n}\n\n/**\n * A template literal tag that creates an HTML element from the\n * contents of the string.\n *\n * This allows you to write a Polymer Template in JavaScript.\n *\n * Templates can be composed by interpolating `HTMLTemplateElement`s in\n * expressions in the JavaScript template literal. The nested template's\n * `innerHTML` is included in the containing template. The only other\n * values allowed in expressions are those returned from `htmlLiteral`\n * which ensures only literal values from JS source ever reach the HTML, to\n * guard against XSS risks.\n *\n * All other values are disallowed in expressions to help prevent XSS\n * attacks; however, `htmlLiteral` can be used to compose static\n * string values into templates. This is useful to compose strings into\n * places that do not accept html, like the css text of a `style`\n * element.\n *\n * Example:\n *\n * static get template() {\n * return html`\n * \n *
${this.partialTemplate}
\n * ${super.template}\n * `;\n * }\n * static get partialTemplate() { return html`Partial!`; }\n *\n * @param {!ITemplateArray} strings Constant parts of tagged template literal\n * @param {...*} values Variable parts of tagged template literal\n * @return {!HTMLTemplateElement} Constructed HTMLTemplateElement\n */\nexport const html = function html(strings, ...values) {\n const template = /** @type {!HTMLTemplateElement} */(document.createElement('template'));\n template.innerHTML = values.reduce((acc, v, idx) =>\n acc + htmlValue(v) + strings[idx + 1], strings[0]);\n return template;\n};\n\n/**\n * An html literal tag that can be used with `html` to compose.\n * a literal string.\n *\n * Example:\n *\n * static get template() {\n * return html`\n * \n *
${staticValue}
\n * ${super.template}\n * `;\n * }\n * static get styleTemplate() {\n * return htmlLiteral`.shadowed { background: gray; }`;\n * }\n *\n * @param {!ITemplateArray} strings Constant parts of tagged template literal\n * @param {...*} values Variable parts of tagged template literal\n * @return {!LiteralString} Constructed literal string\n */\nexport const htmlLiteral = function(strings, ...values) {\n return new LiteralString(values.reduce((acc, v, idx) =>\n acc + literalValue(v) + strings[idx + 1], strings[0]));\n};\n","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\nimport { Class } from './class.js';\n\nimport '../utils/boot.js';\n\n/**\n * Legacy class factory and registration helper for defining Polymer\n * elements.\n *\n * This method is equivalent to\n *\n * import {Class} from '@polymer/polymer/lib/legacy/class.js';\n * customElements.define(info.is, Class(info));\n *\n * See `Class` for details on valid legacy metadata format for `info`.\n *\n * @global\n * @override\n * @function\n * @param {!PolymerInit} info Object containing Polymer metadata and functions\n * to become class methods.\n * @return {function(new: HTMLElement)} Generated class\n * @suppress {duplicate, invalidCasts, checkTypes}\n */\nconst Polymer = function(info) {\n // if input is a `class` (aka a function with a prototype), use the prototype\n // remember that the `constructor` will never be called\n let klass;\n if (typeof info === 'function') {\n klass = info;\n } else {\n klass = Polymer.Class(info);\n }\n customElements.define(klass.is, /** @type {!HTMLElement} */(klass));\n return klass;\n};\n\nPolymer.Class = Class;\n\nexport { Polymer };","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\nimport './boot.js';\n\nimport { calculateSplices } from './array-splice.js';\nimport { microTask } from './async.js';\n\n/**\n * Returns true if `node` is a slot element\n * @param {!Node} node Node to test.\n * @return {boolean} Returns true if the given `node` is a slot\n * @private\n */\nfunction isSlot(node) {\n return (node.localName === 'slot');\n}\n\n/**\n * Class that listens for changes (additions or removals) to\n * \"flattened nodes\" on a given `node`. The list of flattened nodes consists\n * of a node's children and, for any children that are `` elements,\n * the expanded flattened list of `assignedNodes`.\n * For example, if the observed node has children ``\n * and the `` has one `
` assigned to it, then the flattened\n * nodes list is ``. If the `` has other\n * `` elements assigned to it, these are flattened as well.\n *\n * The provided `callback` is called whenever any change to this list\n * of flattened nodes occurs, where an addition or removal of a node is\n * considered a change. The `callback` is called with one argument, an object\n * containing an array of any `addedNodes` and `removedNodes`.\n *\n * Note: the callback is called asynchronous to any changes\n * at a microtask checkpoint. This is because observation is performed using\n * `MutationObserver` and the `` element's `slotchange` event which\n * are asynchronous.\n *\n * An example:\n * ```js\n * class TestSelfObserve extends PolymerElement {\n * static get is() { return 'test-self-observe';}\n * connectedCallback() {\n * super.connectedCallback();\n * this._observer = new FlattenedNodesObserver(this, (info) => {\n * this.info = info;\n * });\n * }\n * disconnectedCallback() {\n * super.disconnectedCallback();\n * this._observer.disconnect();\n * }\n * }\n * customElements.define(TestSelfObserve.is, TestSelfObserve);\n * ```\n *\n * @summary Class that listens for changes (additions or removals) to\n * \"flattened nodes\" on a given `node`.\n */\nexport class FlattenedNodesObserver {\n\n /**\n * Returns the list of flattened nodes for the given `node`.\n * This list consists of a node's children and, for any children\n * that are `` elements, the expanded flattened list of `assignedNodes`.\n * For example, if the observed node has children ``\n * and the `` has one `
` assigned to it, then the flattened\n * nodes list is ``. If the `` has other\n * `` elements assigned to it, these are flattened as well.\n *\n * @param {!HTMLElement|!HTMLSlotElement} node The node for which to\n * return the list of flattened nodes.\n * @return {!Array} The list of flattened nodes for the given `node`.\n * @nocollapse See https://github.com/google/closure-compiler/issues/2763\n */\n static getFlattenedNodes(node) {\n if (isSlot(node)) {\n node = /** @type {!HTMLSlotElement} */(node); // eslint-disable-line no-self-assign\n return node.assignedNodes({flatten: true});\n } else {\n return Array.from(node.childNodes).map((node) => {\n if (isSlot(node)) {\n node = /** @type {!HTMLSlotElement} */(node); // eslint-disable-line no-self-assign\n return node.assignedNodes({flatten: true});\n } else {\n return [node];\n }\n }).reduce((a, b) => a.concat(b), []);\n }\n }\n\n /**\n * @param {!HTMLElement} target Node on which to listen for changes.\n * @param {?function(this: Element, { target: !HTMLElement, addedNodes: !Array, removedNodes: !Array }):void} callback Function called when there are additions\n * or removals from the target's list of flattened nodes.\n */\n constructor(target, callback) {\n /**\n * @type {MutationObserver}\n * @private\n */\n this._shadyChildrenObserver = null;\n /**\n * @type {MutationObserver}\n * @private\n */\n this._nativeChildrenObserver = null;\n this._connected = false;\n /**\n * @type {!HTMLElement}\n * @private\n */\n this._target = target;\n this.callback = callback;\n this._effectiveNodes = [];\n this._observer = null;\n this._scheduled = false;\n /**\n * @type {function()}\n * @private\n */\n this._boundSchedule = () => {\n this._schedule();\n };\n this.connect();\n this._schedule();\n }\n\n /**\n * Activates an observer. This method is automatically called when\n * a `FlattenedNodesObserver` is created. It should only be called to\n * re-activate an observer that has been deactivated via the `disconnect` method.\n *\n * @return {void}\n */\n connect() {\n if (isSlot(this._target)) {\n this._listenSlots([this._target]);\n } else if (this._target.children) {\n this._listenSlots(\n /** @type {!NodeList} */ (this._target.children));\n if (window.ShadyDOM) {\n this._shadyChildrenObserver =\n ShadyDOM.observeChildren(this._target, (mutations) => {\n this._processMutations(mutations);\n });\n } else {\n this._nativeChildrenObserver =\n new MutationObserver((mutations) => {\n this._processMutations(mutations);\n });\n this._nativeChildrenObserver.observe(this._target, {childList: true});\n }\n }\n this._connected = true;\n }\n\n /**\n * Deactivates the flattened nodes observer. After calling this method\n * the observer callback will not be called when changes to flattened nodes\n * occur. The `connect` method may be subsequently called to reactivate\n * the observer.\n *\n * @return {void}\n */\n disconnect() {\n if (isSlot(this._target)) {\n this._unlistenSlots([this._target]);\n } else if (this._target.children) {\n this._unlistenSlots(\n /** @type {!NodeList} */ (this._target.children));\n if (window.ShadyDOM && this._shadyChildrenObserver) {\n ShadyDOM.unobserveChildren(this._shadyChildrenObserver);\n this._shadyChildrenObserver = null;\n } else if (this._nativeChildrenObserver) {\n this._nativeChildrenObserver.disconnect();\n this._nativeChildrenObserver = null;\n }\n }\n this._connected = false;\n }\n\n /**\n * @return {void}\n * @private\n */\n _schedule() {\n if (!this._scheduled) {\n this._scheduled = true;\n microTask.run(() => this.flush());\n }\n }\n\n /**\n * @param {Array} mutations Mutations signaled by the mutation observer\n * @return {void}\n * @private\n */\n _processMutations(mutations) {\n this._processSlotMutations(mutations);\n this.flush();\n }\n\n /**\n * @param {Array} mutations Mutations signaled by the mutation observer\n * @return {void}\n * @private\n */\n _processSlotMutations(mutations) {\n if (mutations) {\n for (let i=0; i < mutations.length; i++) {\n let mutation = mutations[i];\n if (mutation.addedNodes) {\n this._listenSlots(mutation.addedNodes);\n }\n if (mutation.removedNodes) {\n this._unlistenSlots(mutation.removedNodes);\n }\n }\n }\n }\n\n /**\n * Flushes the observer causing any pending changes to be immediately\n * delivered the observer callback. By default these changes are delivered\n * asynchronously at the next microtask checkpoint.\n *\n * @return {boolean} Returns true if any pending changes caused the observer\n * callback to run.\n */\n flush() {\n if (!this._connected) {\n return false;\n }\n if (window.ShadyDOM) {\n ShadyDOM.flush();\n }\n if (this._nativeChildrenObserver) {\n this._processSlotMutations(this._nativeChildrenObserver.takeRecords());\n } else if (this._shadyChildrenObserver) {\n this._processSlotMutations(this._shadyChildrenObserver.takeRecords());\n }\n this._scheduled = false;\n let info = {\n target: this._target,\n addedNodes: [],\n removedNodes: []\n };\n let newNodes = this.constructor.getFlattenedNodes(this._target);\n let splices = calculateSplices(newNodes,\n this._effectiveNodes);\n // process removals\n for (let i=0, s; (i|!NodeList} nodeList Nodes that could change\n * @return {void}\n * @private\n */\n _listenSlots(nodeList) {\n for (let i=0; i < nodeList.length; i++) {\n let n = nodeList[i];\n if (isSlot(n)) {\n n.addEventListener('slotchange', this._boundSchedule);\n }\n }\n }\n\n /**\n * @param {!Array|!NodeList} nodeList Nodes that could change\n * @return {void}\n * @private\n */\n _unlistenSlots(nodeList) {\n for (let i=0; i < nodeList.length; i++) {\n let n = nodeList[i];\n if (isSlot(n)) {\n n.removeEventListener('slotchange', this._boundSchedule);\n }\n }\n }\n\n}\n","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\nimport '../utils/boot.js';\n\nimport '../utils/settings.js';\nimport { FlattenedNodesObserver } from '../utils/flattened-nodes-observer.js';\nexport { flush, enqueueDebouncer as addDebouncer } from '../utils/flush.js';\n/* eslint-disable no-unused-vars */\nimport { Debouncer } from '../utils/debounce.js'; // used in type annotations\n/* eslint-enable no-unused-vars */\n\nconst p = Element.prototype;\n/**\n * @const {function(this:Node, string): boolean}\n */\nconst normalizedMatchesSelector = p.matches || p.matchesSelector ||\n p.mozMatchesSelector || p.msMatchesSelector ||\n p.oMatchesSelector || p.webkitMatchesSelector;\n\n/**\n * Cross-platform `element.matches` shim.\n *\n * @function matchesSelector\n * @param {!Node} node Node to check selector against\n * @param {string} selector Selector to match\n * @return {boolean} True if node matched selector\n */\nexport const matchesSelector = function(node, selector) {\n return normalizedMatchesSelector.call(node, selector);\n};\n\n/**\n * Node API wrapper class returned from `Polymer.dom.(target)` when\n * `target` is a `Node`.\n *\n */\nexport class DomApi {\n\n /**\n * @param {Node} node Node for which to create a Polymer.dom helper object.\n */\n constructor(node) {\n this.node = node;\n }\n\n /**\n * Returns an instance of `FlattenedNodesObserver` that\n * listens for node changes on this element.\n *\n * @param {function(this:HTMLElement, { target: !HTMLElement, addedNodes: !Array, removedNodes: !Array }):void} callback Called when direct or distributed children\n * of this element changes\n * @return {!FlattenedNodesObserver} Observer instance\n */\n observeNodes(callback) {\n return new FlattenedNodesObserver(\n /** @type {!HTMLElement} */(this.node), callback);\n }\n\n /**\n * Disconnects an observer previously created via `observeNodes`\n *\n * @param {!FlattenedNodesObserver} observerHandle Observer instance\n * to disconnect.\n * @return {void}\n */\n unobserveNodes(observerHandle) {\n observerHandle.disconnect();\n }\n\n /**\n * Provided as a backwards-compatible API only. This method does nothing.\n * @return {void}\n */\n notifyObserver() {}\n\n /**\n * Returns true if the provided node is contained with this element's\n * light-DOM children or shadow root, including any nested shadow roots\n * of children therein.\n *\n * @param {Node} node Node to test\n * @return {boolean} Returns true if the given `node` is contained within\n * this element's light or shadow DOM.\n */\n deepContains(node) {\n if (this.node.contains(node)) {\n return true;\n }\n let n = node;\n let doc = node.ownerDocument;\n // walk from node to `this` or `document`\n while (n && n !== doc && n !== this.node) {\n // use logical parentnode, or native ShadowRoot host\n n = n.parentNode || n.host;\n }\n return n === this.node;\n }\n\n /**\n * Returns the root node of this node. Equivalent to `getRootNode()`.\n *\n * @return {Node} Top most element in the dom tree in which the node\n * exists. If the node is connected to a document this is either a\n * shadowRoot or the document; otherwise, it may be the node\n * itself or a node or document fragment containing it.\n */\n getOwnerRoot() {\n return this.node.getRootNode();\n }\n\n /**\n * For slot elements, returns the nodes assigned to the slot; otherwise\n * an empty array. It is equivalent to `.addignedNodes({flatten:true})`.\n *\n * @return {!Array} Array of assigned nodes\n */\n getDistributedNodes() {\n return (this.node.localName === 'slot') ?\n this.node.assignedNodes({flatten: true}) :\n [];\n }\n\n /**\n * Returns an array of all slots this element was distributed to.\n *\n * @return {!Array} Description\n */\n getDestinationInsertionPoints() {\n let ip$ = [];\n let n = this.node.assignedSlot;\n while (n) {\n ip$.push(n);\n n = n.assignedSlot;\n }\n return ip$;\n }\n\n /**\n * Calls `importNode` on the `ownerDocument` for this node.\n *\n * @param {!Node} node Node to import\n * @param {boolean} deep True if the node should be cloned deeply during\n * import\n * @return {Node} Clone of given node imported to this owner document\n */\n importNode(node, deep) {\n let doc = this.node instanceof Document ? this.node :\n this.node.ownerDocument;\n return doc.importNode(node, deep);\n }\n\n /**\n * @return {!Array} Returns a flattened list of all child nodes and\n * nodes assigned to child slots.\n */\n getEffectiveChildNodes() {\n return FlattenedNodesObserver.getFlattenedNodes(\n /** @type {!HTMLElement} */ (this.node));\n }\n\n /**\n * Returns a filtered list of flattened child elements for this element based\n * on the given selector.\n *\n * @param {string} selector Selector to filter nodes against\n * @return {!Array} List of flattened child elements\n */\n queryDistributedElements(selector) {\n let c$ = this.getEffectiveChildNodes();\n let list = [];\n for (let i=0, l=c$.length, c; (i} The nodes this event propagated through\n */\n get path() {\n return this.event.composedPath();\n }\n}\n\n/**\n * @function\n * @param {boolean=} deep\n * @return {!Node}\n */\nDomApi.prototype.cloneNode;\n/**\n * @function\n * @param {!Node} node\n * @return {!Node}\n */\nDomApi.prototype.appendChild;\n/**\n * @function\n * @param {!Node} newChild\n * @param {Node} refChild\n * @return {!Node}\n */\nDomApi.prototype.insertBefore;\n/**\n * @function\n * @param {!Node} node\n * @return {!Node}\n */\nDomApi.prototype.removeChild;\n/**\n * @function\n * @param {!Node} oldChild\n * @param {!Node} newChild\n * @return {!Node}\n */\nDomApi.prototype.replaceChild;\n/**\n * @function\n * @param {string} name\n * @param {string} value\n * @return {void}\n */\nDomApi.prototype.setAttribute;\n/**\n * @function\n * @param {string} name\n * @return {void}\n */\nDomApi.prototype.removeAttribute;\n/**\n * @function\n * @param {string} selector\n * @return {?Element}\n */\nDomApi.prototype.querySelector;\n/**\n * @function\n * @param {string} selector\n * @return {!NodeList}\n */\nDomApi.prototype.querySelectorAll;\n\n/** @type {?Node} */\nDomApi.prototype.parentNode;\n/** @type {?Node} */\nDomApi.prototype.firstChild;\n/** @type {?Node} */\nDomApi.prototype.lastChild;\n/** @type {?Node} */\nDomApi.prototype.nextSibling;\n/** @type {?Node} */\nDomApi.prototype.previousSibling;\n/** @type {?HTMLElement} */\nDomApi.prototype.firstElementChild;\n/** @type {?HTMLElement} */\nDomApi.prototype.lastElementChild;\n/** @type {?HTMLElement} */\nDomApi.prototype.nextElementSibling;\n/** @type {?HTMLElement} */\nDomApi.prototype.previousElementSibling;\n/** @type {!Array} */\nDomApi.prototype.childNodes;\n/** @type {!Array} */\nDomApi.prototype.children;\n/** @type {?DOMTokenList} */\nDomApi.prototype.classList;\n\n/** @type {string} */\nDomApi.prototype.textContent;\n/** @type {string} */\nDomApi.prototype.innerHTML;\n\nforwardMethods(DomApi.prototype, [\n 'cloneNode', 'appendChild', 'insertBefore', 'removeChild',\n 'replaceChild', 'setAttribute', 'removeAttribute',\n 'querySelector', 'querySelectorAll'\n]);\n\nforwardReadOnlyProperties(DomApi.prototype, [\n 'parentNode', 'firstChild', 'lastChild',\n 'nextSibling', 'previousSibling', 'firstElementChild',\n 'lastElementChild', 'nextElementSibling', 'previousElementSibling',\n 'childNodes', 'children', 'classList'\n]);\n\nforwardProperties(DomApi.prototype, [\n 'textContent', 'innerHTML'\n]);\n\n/**\n * Legacy DOM and Event manipulation API wrapper factory used to abstract\n * differences between native Shadow DOM and \"Shady DOM\" when polyfilling on\n * older browsers.\n *\n * Note that in Polymer 2.x use of `Polymer.dom` is no longer required and\n * in the majority of cases simply facades directly to the standard native\n * API.\n *\n * @summary Legacy DOM and Event manipulation API wrapper factory used to\n * abstract differences between native Shadow DOM and \"Shady DOM.\"\n * @param {(Node|Event)=} obj Node or event to operate on\n * @return {!DomApi|!EventApi} Wrapper providing either node API or event API\n */\nexport const dom = function(obj) {\n obj = obj || document;\n if (!obj.__domApi) {\n let helper;\n if (obj instanceof Event) {\n helper = new EventApi(obj);\n } else {\n helper = new DomApi(obj);\n }\n obj.__domApi = helper;\n }\n return obj.__domApi;\n};\n","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\n/* eslint-disable no-unused-vars */\n/**\n * When using Closure Compiler, JSCompiler_renameProperty(property, object) is replaced by the munged name for object[property]\n * We cannot alias this function, so we have to use a small shim that has the same behavior when not compiling.\n *\n * @param {string} prop Property name\n * @param {?Object} obj Reference object\n * @return {string} Potentially renamed property name\n */\nwindow.JSCompiler_renameProperty = function(prop, obj) {\n return prop;\n};\n/* eslint-enable */\n\nexport {};\n","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\nimport { ElementMixin, version } from './lib/mixins/element-mixin.js';\nexport { html } from './lib/utils/html-tag.js';\n\nexport { version };\n\n/**\n * Base class that provides the core API for Polymer's meta-programming\n * features including template stamping, data-binding, attribute deserialization,\n * and property change observation.\n *\n * @customElement\n * @polymer\n * @constructor\n * @implements {Polymer_ElementMixin}\n * @extends HTMLElement\n * @appliesMixin ElementMixin\n * @summary Custom element base class that provides the core API for Polymer's\n * key meta-programming features including template stamping, data-binding,\n * attribute deserialization, and property change observation\n */\nexport const PolymerElement = ElementMixin(HTMLElement);\n","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\nimport './boot.js';\n\n// unique global id for deduping mixins.\nlet dedupeId = 0;\n\n/**\n * @constructor\n * @extends {Function}\n * @private\n */\nfunction MixinFunction(){}\n/** @type {(WeakMap | undefined)} */\nMixinFunction.prototype.__mixinApplications;\n/** @type {(Object | undefined)} */\nMixinFunction.prototype.__mixinSet;\n\n/* eslint-disable valid-jsdoc */\n/**\n * Wraps an ES6 class expression mixin such that the mixin is only applied\n * if it has not already been applied its base argument. Also memoizes mixin\n * applications.\n *\n * @template T\n * @param {T} mixin ES6 class expression mixin to wrap\n * @return {T}\n * @suppress {invalidCasts}\n */\nexport const dedupingMixin = function(mixin) {\n let mixinApplications = /** @type {!MixinFunction} */(mixin).__mixinApplications;\n if (!mixinApplications) {\n mixinApplications = new WeakMap();\n /** @type {!MixinFunction} */(mixin).__mixinApplications = mixinApplications;\n }\n // maintain a unique id for each mixin\n let mixinDedupeId = dedupeId++;\n function dedupingMixin(base) {\n let baseSet = /** @type {!MixinFunction} */(base).__mixinSet;\n if (baseSet && baseSet[mixinDedupeId]) {\n return base;\n }\n let map = mixinApplications;\n let extended = map.get(base);\n if (!extended) {\n extended = /** @type {!Function} */(mixin)(base);\n map.set(base, extended);\n }\n // copy inherited mixin set from the extended class, or the base class\n // NOTE: we avoid use of Set here because some browser (IE11)\n // cannot extend a base Set via the constructor.\n let mixinSet = Object.create(/** @type {!MixinFunction} */(extended).__mixinSet || baseSet || null);\n mixinSet[mixinDedupeId] = true;\n /** @type {!MixinFunction} */(extended).__mixinSet = mixinSet;\n return extended;\n }\n\n return dedupingMixin;\n};\n/* eslint-enable valid-jsdoc */\n","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\nimport './boot.js';\n\nimport { pathFromUrl } from './resolve-url.js';\nexport const useShadow = !(window.ShadyDOM);\nexport const useNativeCSSProperties = Boolean(!window.ShadyCSS || window.ShadyCSS.nativeCss);\nexport const useNativeCustomElements = !(window.customElements.polyfillWrapFlushCallback);\n\n\n/**\n * Globally settable property that is automatically assigned to\n * `ElementMixin` instances, useful for binding in templates to\n * make URL's relative to an application's root. Defaults to the main\n * document URL, but can be overridden by users. It may be useful to set\n * `rootPath` to provide a stable application mount path when\n * using client side routing.\n */\nexport let rootPath = undefined ||\n pathFromUrl(document.baseURI || window.location.href);\n\n/**\n * Sets the global rootPath property used by `ElementMixin` and\n * available via `rootPath`.\n *\n * @param {string} path The new root path\n * @return {void}\n */\nexport const setRootPath = function(path) {\n rootPath = path;\n};\n\n/**\n * A global callback used to sanitize any value before inserting it into the DOM.\n * The callback signature is:\n *\n * function sanitizeDOMValue(value, name, type, node) { ... }\n *\n * Where:\n *\n * `value` is the value to sanitize.\n * `name` is the name of an attribute or property (for example, href).\n * `type` indicates where the value is being inserted: one of property, attribute, or text.\n * `node` is the node where the value is being inserted.\n *\n * @type {(function(*,string,string,Node):*)|undefined}\n */\nexport let sanitizeDOMValue = window.Polymer && window.Polymer.sanitizeDOMValue || undefined;\n\n/**\n * Sets the global sanitizeDOMValue available via this module's exported\n * `sanitizeDOMValue` variable.\n *\n * @param {(function(*,string,string,Node):*)|undefined} newSanitizeDOMValue the global sanitizeDOMValue callback\n * @return {void}\n */\nexport const setSanitizeDOMValue = function(newSanitizeDOMValue) {\n sanitizeDOMValue = newSanitizeDOMValue;\n};\n\n/**\n * Globally settable property to make Polymer Gestures use passive TouchEvent listeners when recognizing gestures.\n * When set to `true`, gestures made from touch will not be able to prevent scrolling, allowing for smoother\n * scrolling performance.\n * Defaults to `false` for backwards compatibility.\n */\nexport let passiveTouchGestures = false;\n\n/**\n * Sets `passiveTouchGestures` globally for all elements using Polymer Gestures.\n *\n * @param {boolean} usePassive enable or disable passive touch gestures globally\n * @return {void}\n */\nexport const setPassiveTouchGestures = function(usePassive) {\n passiveTouchGestures = usePassive;\n};\n\n/**\n * Setting to ensure Polymer template evaluation only occurs based on tempates\n * defined in trusted script. When true, `` re-registration is\n * disallowed, `` is disabled, and ``/``\n * templates will only evaluate in the context of a trusted element template.\n */\nexport let strictTemplatePolicy = false;\n\n/**\n * Sets `strictTemplatePolicy` globally for all elements\n *\n * @param {boolean} useStrictPolicy enable or disable strict template policy\n * globally\n * @return {void}\n */\nexport const setStrictTemplatePolicy = function(useStrictPolicy) {\n strictTemplatePolicy = useStrictPolicy;\n};\n\n/**\n * Setting to enable dom-module lookup from Polymer.Element. By default,\n * templates must be defined in script using the `static get template()`\n * getter and the `html` tag function. To enable legacy loading of templates\n * via dom-module, set this flag to true.\n */\nexport let allowTemplateFromDomModule = false;\n\n/**\n * Sets `lookupTemplateFromDomModule` globally for all elements\n *\n * @param {boolean} allowDomModule enable or disable template lookup \n * globally\n * @return {void}\n */\nexport const setAllowTemplateFromDomModule = function(allowDomModule) {\n allowTemplateFromDomModule = allowDomModule;\n};\n","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\n/**\n * @fileoverview\n *\n * This module provides a number of strategies for enqueuing asynchronous\n * tasks. Each sub-module provides a standard `run(fn)` interface that returns a\n * handle, and a `cancel(handle)` interface for canceling async tasks before\n * they run.\n *\n * @summary Module that provides a number of strategies for enqueuing\n * asynchronous tasks.\n */\n\nimport './boot.js';\n\n// Microtask implemented using Mutation Observer\nlet microtaskCurrHandle = 0;\nlet microtaskLastHandle = 0;\nlet microtaskCallbacks = [];\nlet microtaskNodeContent = 0;\nlet microtaskNode = document.createTextNode('');\nnew window.MutationObserver(microtaskFlush).observe(microtaskNode, {characterData: true});\n\nfunction microtaskFlush() {\n const len = microtaskCallbacks.length;\n for (let i = 0; i < len; i++) {\n let cb = microtaskCallbacks[i];\n if (cb) {\n try {\n cb();\n } catch (e) {\n setTimeout(() => { throw e; });\n }\n }\n }\n microtaskCallbacks.splice(0, len);\n microtaskLastHandle += len;\n}\n\n/**\n * Async interface wrapper around `setTimeout`.\n *\n * @namespace\n * @summary Async interface wrapper around `setTimeout`.\n */\nconst timeOut = {\n /**\n * Returns a sub-module with the async interface providing the provided\n * delay.\n *\n * @memberof timeOut\n * @param {number=} delay Time to wait before calling callbacks in ms\n * @return {!AsyncInterface} An async timeout interface\n */\n after(delay) {\n return {\n run(fn) { return window.setTimeout(fn, delay); },\n cancel(handle) {\n window.clearTimeout(handle);\n }\n };\n },\n /**\n * Enqueues a function called in the next task.\n *\n * @memberof timeOut\n * @param {!Function} fn Callback to run\n * @param {number=} delay Delay in milliseconds\n * @return {number} Handle used for canceling task\n */\n run(fn, delay) {\n return window.setTimeout(fn, delay);\n },\n /**\n * Cancels a previously enqueued `timeOut` callback.\n *\n * @memberof timeOut\n * @param {number} handle Handle returned from `run` of callback to cancel\n * @return {void}\n */\n cancel(handle) {\n window.clearTimeout(handle);\n }\n};\nexport {timeOut};\n\n/**\n * Async interface wrapper around `requestAnimationFrame`.\n *\n * @namespace\n * @summary Async interface wrapper around `requestAnimationFrame`.\n */\nconst animationFrame = {\n /**\n * Enqueues a function called at `requestAnimationFrame` timing.\n *\n * @memberof animationFrame\n * @param {function(number):void} fn Callback to run\n * @return {number} Handle used for canceling task\n */\n run(fn) {\n return window.requestAnimationFrame(fn);\n },\n /**\n * Cancels a previously enqueued `animationFrame` callback.\n *\n * @memberof animationFrame\n * @param {number} handle Handle returned from `run` of callback to cancel\n * @return {void}\n */\n cancel(handle) {\n window.cancelAnimationFrame(handle);\n }\n};\nexport {animationFrame};\n\n/**\n * Async interface wrapper around `requestIdleCallback`. Falls back to\n * `setTimeout` on browsers that do not support `requestIdleCallback`.\n *\n * @namespace\n * @summary Async interface wrapper around `requestIdleCallback`.\n */\nconst idlePeriod = {\n /**\n * Enqueues a function called at `requestIdleCallback` timing.\n *\n * @memberof idlePeriod\n * @param {function(!IdleDeadline):void} fn Callback to run\n * @return {number} Handle used for canceling task\n */\n run(fn) {\n return window.requestIdleCallback ?\n window.requestIdleCallback(fn) :\n window.setTimeout(fn, 16);\n },\n /**\n * Cancels a previously enqueued `idlePeriod` callback.\n *\n * @memberof idlePeriod\n * @param {number} handle Handle returned from `run` of callback to cancel\n * @return {void}\n */\n cancel(handle) {\n window.cancelIdleCallback ?\n window.cancelIdleCallback(handle) :\n window.clearTimeout(handle);\n }\n};\nexport {idlePeriod};\n\n/**\n * Async interface for enqueuing callbacks that run at microtask timing.\n *\n * Note that microtask timing is achieved via a single `MutationObserver`,\n * and thus callbacks enqueued with this API will all run in a single\n * batch, and not interleaved with other microtasks such as promises.\n * Promises are avoided as an implementation choice for the time being\n * due to Safari bugs that cause Promises to lack microtask guarantees.\n *\n * @namespace\n * @summary Async interface for enqueuing callbacks that run at microtask\n * timing.\n */\nconst microTask = {\n\n /**\n * Enqueues a function called at microtask timing.\n *\n * @memberof microTask\n * @param {!Function=} callback Callback to run\n * @return {number} Handle used for canceling task\n */\n run(callback) {\n microtaskNode.textContent = microtaskNodeContent++;\n microtaskCallbacks.push(callback);\n return microtaskCurrHandle++;\n },\n\n /**\n * Cancels a previously enqueued `microTask` callback.\n *\n * @memberof microTask\n * @param {number} handle Handle returned from `run` of callback to cancel\n * @return {void}\n */\n cancel(handle) {\n const idx = handle - microtaskLastHandle;\n if (idx >= 0) {\n if (!microtaskCallbacks[idx]) {\n throw new Error('invalid async handle: ' + handle);\n }\n microtaskCallbacks[idx] = null;\n }\n }\n\n};\nexport {microTask};\n","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\nimport './boot.js';\n\nimport './mixin.js';\nimport './async.js';\n\n/**\n * @summary Collapse multiple callbacks into one invocation after a timer.\n */\nexport class Debouncer {\n constructor() {\n this._asyncModule = null;\n this._callback = null;\n this._timer = null;\n }\n /**\n * Sets the scheduler; that is, a module with the Async interface,\n * a callback and optional arguments to be passed to the run function\n * from the async module.\n *\n * @param {!AsyncInterface} asyncModule Object with Async interface.\n * @param {function()} callback Callback to run.\n * @return {void}\n */\n setConfig(asyncModule, callback) {\n this._asyncModule = asyncModule;\n this._callback = callback;\n this._timer = this._asyncModule.run(() => {\n this._timer = null;\n this._callback();\n });\n }\n /**\n * Cancels an active debouncer and returns a reference to itself.\n *\n * @return {void}\n */\n cancel() {\n if (this.isActive()) {\n this._asyncModule.cancel(/** @type {number} */(this._timer));\n this._timer = null;\n }\n }\n /**\n * Flushes an active debouncer and returns a reference to itself.\n *\n * @return {void}\n */\n flush() {\n if (this.isActive()) {\n this.cancel();\n this._callback();\n }\n }\n /**\n * Returns true if the debouncer is active.\n *\n * @return {boolean} True if active.\n */\n isActive() {\n return this._timer != null;\n }\n /**\n * Creates a debouncer if no debouncer is passed as a parameter\n * or it cancels an active debouncer otherwise. The following\n * example shows how a debouncer can be called multiple times within a\n * microtask and \"debounced\" such that the provided callback function is\n * called once. Add this method to a custom element:\n *\n * ```js\n * import {microTask} from '@polymer/polymer/lib/utils/async.js';\n * import {Debouncer} from '@polymer/polymer/lib/utils/debounce.js';\n * // ...\n *\n * _debounceWork() {\n * this._debounceJob = Debouncer.debounce(this._debounceJob,\n * microTask, () => this._doWork());\n * }\n * ```\n *\n * If the `_debounceWork` method is called multiple times within the same\n * microtask, the `_doWork` function will be called only once at the next\n * microtask checkpoint.\n *\n * Note: In testing it is often convenient to avoid asynchrony. To accomplish\n * this with a debouncer, you can use `enqueueDebouncer` and\n * `flush`. For example, extend the above example by adding\n * `enqueueDebouncer(this._debounceJob)` at the end of the\n * `_debounceWork` method. Then in a test, call `flush` to ensure\n * the debouncer has completed.\n *\n * @param {Debouncer?} debouncer Debouncer object.\n * @param {!AsyncInterface} asyncModule Object with Async interface\n * @param {function()} callback Callback to run.\n * @return {!Debouncer} Returns a debouncer object.\n */\n static debounce(debouncer, asyncModule, callback) {\n if (debouncer instanceof Debouncer) {\n debouncer.cancel();\n } else {\n debouncer = new Debouncer();\n }\n debouncer.setConfig(asyncModule, callback);\n return debouncer;\n }\n}\n","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\nimport './boot.js';\n/* eslint-disable no-unused-vars */\nimport { Debouncer } from '../utils/debounce.js'; // used in type annotations\n/* eslint-enable no-unused-vars */\n\nlet debouncerQueue = [];\n\n/**\n * Adds a `Debouncer` to a list of globally flushable tasks.\n *\n * @param {!Debouncer} debouncer Debouncer to enqueue\n * @return {void}\n */\nexport const enqueueDebouncer = function(debouncer) {\n debouncerQueue.push(debouncer);\n};\n\nfunction flushDebouncers() {\n const didFlush = Boolean(debouncerQueue.length);\n while (debouncerQueue.length) {\n try {\n debouncerQueue.shift().flush();\n } catch(e) {\n setTimeout(() => {\n throw e;\n });\n }\n }\n return didFlush;\n}\n\n/**\n * Forces several classes of asynchronously queued tasks to flush:\n * - Debouncers added via `enqueueDebouncer`\n * - ShadyDOM distribution\n *\n * @return {void}\n */\nexport const flush = function() {\n let shadyDOM, debouncers;\n do {\n shadyDOM = window.ShadyDOM && ShadyDOM.flush();\n if (window.ShadyCSS && window.ShadyCSS.ScopingShim) {\n window.ShadyCSS.ScopingShim.flush();\n }\n debouncers = flushDebouncers();\n } while (shadyDOM || debouncers);\n};\n","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\nimport './boot.js';\n\nlet CSS_URL_RX = /(url\\()([^)]*)(\\))/g;\nlet ABS_URL = /(^\\/)|(^#)|(^[\\w-\\d]*:)/;\nlet workingURL;\nlet resolveDoc;\n/**\n * Resolves the given URL against the provided `baseUri'.\n *\n * Note that this function performs no resolution for URLs that start\n * with `/` (absolute URLs) or `#` (hash identifiers). For general purpose\n * URL resolution, use `window.URL`.\n *\n * @param {string} url Input URL to resolve\n * @param {?string=} baseURI Base URI to resolve the URL against\n * @return {string} resolved URL\n */\nexport function resolveUrl(url, baseURI) {\n if (url && ABS_URL.test(url)) {\n return url;\n }\n // Lazy feature detection.\n if (workingURL === undefined) {\n workingURL = false;\n try {\n const u = new URL('b', 'http://a');\n u.pathname = 'c%20d';\n workingURL = (u.href === 'http://a/c%20d');\n } catch (e) {\n // silently fail\n }\n }\n if (!baseURI) {\n baseURI = document.baseURI || window.location.href;\n }\n if (workingURL) {\n return (new URL(url, baseURI)).href;\n }\n // Fallback to creating an anchor into a disconnected document.\n if (!resolveDoc) {\n resolveDoc = document.implementation.createHTMLDocument('temp');\n resolveDoc.base = resolveDoc.createElement('base');\n resolveDoc.head.appendChild(resolveDoc.base);\n resolveDoc.anchor = resolveDoc.createElement('a');\n resolveDoc.body.appendChild(resolveDoc.anchor);\n }\n resolveDoc.base.href = baseURI;\n resolveDoc.anchor.href = url;\n return resolveDoc.anchor.href || url;\n\n}\n\n/**\n * Resolves any relative URL's in the given CSS text against the provided\n * `ownerDocument`'s `baseURI`.\n *\n * @param {string} cssText CSS text to process\n * @param {string} baseURI Base URI to resolve the URL against\n * @return {string} Processed CSS text with resolved URL's\n */\nexport function resolveCss(cssText, baseURI) {\n return cssText.replace(CSS_URL_RX, function(m, pre, url, post) {\n return pre + '\\'' +\n resolveUrl(url.replace(/[\"']/g, ''), baseURI) +\n '\\'' + post;\n });\n}\n\n/**\n * Returns a path from a given `url`. The path includes the trailing\n * `/` from the url.\n *\n * @param {string} url Input URL to transform\n * @return {string} resolved path\n */\nexport function pathFromUrl(url) {\n return url.substring(0, url.lastIndexOf('/') + 1);\n}\n","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\n/**\n * @fileoverview\n *\n * Module for adding listeners to a node for the following normalized\n * cross-platform \"gesture\" events:\n * - `down` - mouse or touch went down\n * - `up` - mouse or touch went up\n * - `tap` - mouse click or finger tap\n * - `track` - mouse drag or touch move\n *\n * @summary Module for adding cross-platform gesture event listeners.\n */\n\nimport './boot.js';\n\nimport { timeOut, microTask } from './async.js';\nimport { Debouncer } from './debounce.js';\nimport { passiveTouchGestures } from './settings.js';\n\n// detect native touch action support\nlet HAS_NATIVE_TA = typeof document.head.style.touchAction === 'string';\nlet GESTURE_KEY = '__polymerGestures';\nlet HANDLED_OBJ = '__polymerGesturesHandled';\nlet TOUCH_ACTION = '__polymerGesturesTouchAction';\n// radius for tap and track\nlet TAP_DISTANCE = 25;\nlet TRACK_DISTANCE = 5;\n// number of last N track positions to keep\nlet TRACK_LENGTH = 2;\n\n// Disabling \"mouse\" handlers for 2500ms is enough\nlet MOUSE_TIMEOUT = 2500;\nlet MOUSE_EVENTS = ['mousedown', 'mousemove', 'mouseup', 'click'];\n// an array of bitmask values for mapping MouseEvent.which to MouseEvent.buttons\nlet MOUSE_WHICH_TO_BUTTONS = [0, 1, 4, 2];\nlet MOUSE_HAS_BUTTONS = (function() {\n try {\n return new MouseEvent('test', {buttons: 1}).buttons === 1;\n } catch (e) {\n return false;\n }\n})();\n\n/**\n * @param {string} name Possible mouse event name\n * @return {boolean} true if mouse event, false if not\n */\nfunction isMouseEvent(name) {\n return MOUSE_EVENTS.indexOf(name) > -1;\n}\n\n/* eslint no-empty: [\"error\", { \"allowEmptyCatch\": true }] */\n// check for passive event listeners\nlet SUPPORTS_PASSIVE = false;\n(function() {\n try {\n let opts = Object.defineProperty({}, 'passive', {get() {SUPPORTS_PASSIVE = true;}});\n window.addEventListener('test', null, opts);\n window.removeEventListener('test', null, opts);\n } catch(e) {}\n})();\n\n/**\n * Generate settings for event listeners, dependant on `passiveTouchGestures`\n *\n * @param {string} eventName Event name to determine if `{passive}` option is\n * needed\n * @return {{passive: boolean} | undefined} Options to use for addEventListener\n * and removeEventListener\n */\nfunction PASSIVE_TOUCH(eventName) {\n if (isMouseEvent(eventName) || eventName === 'touchend') {\n return;\n }\n if (HAS_NATIVE_TA && SUPPORTS_PASSIVE && passiveTouchGestures) {\n return {passive: true};\n } else {\n return;\n }\n}\n\n// Check for touch-only devices\nlet IS_TOUCH_ONLY = navigator.userAgent.match(/iP(?:[oa]d|hone)|Android/);\n\n// keep track of any labels hit by the mouseCanceller\n/** @type {!Array} */\nconst clickedLabels = [];\n\n/** @type {!Object} */\nconst labellable = {\n 'button': true,\n 'input': true,\n 'keygen': true,\n 'meter': true,\n 'output': true,\n 'textarea': true,\n 'progress': true,\n 'select': true\n};\n\n// Defined at https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#enabling-and-disabling-form-controls:-the-disabled-attribute\n/** @type {!Object} */\nconst canBeDisabled = {\n 'button': true,\n 'command': true,\n 'fieldset': true,\n 'input': true,\n 'keygen': true,\n 'optgroup': true,\n 'option': true,\n 'select': true,\n 'textarea': true\n};\n\n/**\n * @param {HTMLElement} el Element to check labelling status\n * @return {boolean} element can have labels\n */\nfunction canBeLabelled(el) {\n return labellable[el.localName] || false;\n}\n\n/**\n * @param {HTMLElement} el Element that may be labelled.\n * @return {!Array} Relevant label for `el`\n */\nfunction matchingLabels(el) {\n let labels = Array.prototype.slice.call(/** @type {HTMLInputElement} */(el).labels || []);\n // IE doesn't have `labels` and Safari doesn't populate `labels`\n // if element is in a shadowroot.\n // In this instance, finding the non-ancestor labels is enough,\n // as the mouseCancellor code will handle ancstor labels\n if (!labels.length) {\n labels = [];\n let root = el.getRootNode();\n // if there is an id on `el`, check for all labels with a matching `for` attribute\n if (el.id) {\n let matching = root.querySelectorAll(`label[for = ${el.id}]`);\n for (let i = 0; i < matching.length; i++) {\n labels.push(/** @type {!HTMLLabelElement} */(matching[i]));\n }\n }\n }\n return labels;\n}\n\n// touch will make synthetic mouse events\n// `preventDefault` on touchend will cancel them,\n// but this breaks `` focus and link clicks\n// disable mouse handlers for MOUSE_TIMEOUT ms after\n// a touchend to ignore synthetic mouse events\nlet mouseCanceller = function(mouseEvent) {\n // Check for sourceCapabilities, used to distinguish synthetic events\n // if mouseEvent did not come from a device that fires touch events,\n // it was made by a real mouse and should be counted\n // http://wicg.github.io/InputDeviceCapabilities/#dom-inputdevicecapabilities-firestouchevents\n let sc = mouseEvent.sourceCapabilities;\n if (sc && !sc.firesTouchEvents) {\n return;\n }\n // skip synthetic mouse events\n mouseEvent[HANDLED_OBJ] = {skip: true};\n // disable \"ghost clicks\"\n if (mouseEvent.type === 'click') {\n let clickFromLabel = false;\n let path = mouseEvent.composedPath && mouseEvent.composedPath();\n if (path) {\n for (let i = 0; i < path.length; i++) {\n if (path[i].nodeType === Node.ELEMENT_NODE) {\n if (path[i].localName === 'label') {\n clickedLabels.push(path[i]);\n } else if (canBeLabelled(path[i])) {\n let ownerLabels = matchingLabels(path[i]);\n // check if one of the clicked labels is labelling this element\n for (let j = 0; j < ownerLabels.length; j++) {\n clickFromLabel = clickFromLabel || clickedLabels.indexOf(ownerLabels[j]) > -1;\n }\n }\n }\n if (path[i] === POINTERSTATE.mouse.target) {\n return;\n }\n }\n }\n // if one of the clicked labels was labelling the target element,\n // this is not a ghost click\n if (clickFromLabel) {\n return;\n }\n mouseEvent.preventDefault();\n mouseEvent.stopPropagation();\n }\n};\n\n/**\n * @param {boolean=} setup True to add, false to remove.\n * @return {void}\n */\nfunction setupTeardownMouseCanceller(setup) {\n let events = IS_TOUCH_ONLY ? ['click'] : MOUSE_EVENTS;\n for (let i = 0, en; i < events.length; i++) {\n en = events[i];\n if (setup) {\n // reset clickLabels array\n clickedLabels.length = 0;\n document.addEventListener(en, mouseCanceller, true);\n } else {\n document.removeEventListener(en, mouseCanceller, true);\n }\n }\n}\n\nfunction ignoreMouse(e) {\n if (!POINTERSTATE.mouse.mouseIgnoreJob) {\n setupTeardownMouseCanceller(true);\n }\n let unset = function() {\n setupTeardownMouseCanceller();\n POINTERSTATE.mouse.target = null;\n POINTERSTATE.mouse.mouseIgnoreJob = null;\n };\n POINTERSTATE.mouse.target = e.composedPath()[0];\n POINTERSTATE.mouse.mouseIgnoreJob = Debouncer.debounce(\n POINTERSTATE.mouse.mouseIgnoreJob\n , timeOut.after(MOUSE_TIMEOUT)\n , unset);\n}\n\n/**\n * @param {MouseEvent} ev event to test for left mouse button down\n * @return {boolean} has left mouse button down\n */\nfunction hasLeftMouseButton(ev) {\n let type = ev.type;\n // exit early if the event is not a mouse event\n if (!isMouseEvent(type)) {\n return false;\n }\n // ev.button is not reliable for mousemove (0 is overloaded as both left button and no buttons)\n // instead we use ev.buttons (bitmask of buttons) or fall back to ev.which (deprecated, 0 for no buttons, 1 for left button)\n if (type === 'mousemove') {\n // allow undefined for testing events\n let buttons = ev.buttons === undefined ? 1 : ev.buttons;\n if ((ev instanceof window.MouseEvent) && !MOUSE_HAS_BUTTONS) {\n buttons = MOUSE_WHICH_TO_BUTTONS[ev.which] || 0;\n }\n // buttons is a bitmask, check that the left button bit is set (1)\n return Boolean(buttons & 1);\n } else {\n // allow undefined for testing events\n let button = ev.button === undefined ? 0 : ev.button;\n // ev.button is 0 in mousedown/mouseup/click for left button activation\n return button === 0;\n }\n}\n\nfunction isSyntheticClick(ev) {\n if (ev.type === 'click') {\n // ev.detail is 0 for HTMLElement.click in most browsers\n if (ev.detail === 0) {\n return true;\n }\n // in the worst case, check that the x/y position of the click is within\n // the bounding box of the target of the event\n // Thanks IE 10 >:(\n let t = _findOriginalTarget(ev);\n // make sure the target of the event is an element so we can use getBoundingClientRect,\n // if not, just assume it is a synthetic click\n if (!t.nodeType || /** @type {Element} */(t).nodeType !== Node.ELEMENT_NODE) {\n return true;\n }\n let bcr = /** @type {Element} */(t).getBoundingClientRect();\n // use page x/y to account for scrolling\n let x = ev.pageX, y = ev.pageY;\n // ev is a synthetic click if the position is outside the bounding box of the target\n return !((x >= bcr.left && x <= bcr.right) && (y >= bcr.top && y <= bcr.bottom));\n }\n return false;\n}\n\nlet POINTERSTATE = {\n mouse: {\n target: null,\n mouseIgnoreJob: null\n },\n touch: {\n x: 0,\n y: 0,\n id: -1,\n scrollDecided: false\n }\n};\n\nfunction firstTouchAction(ev) {\n let ta = 'auto';\n let path = ev.composedPath && ev.composedPath();\n if (path) {\n for (let i = 0, n; i < path.length; i++) {\n n = path[i];\n if (n[TOUCH_ACTION]) {\n ta = n[TOUCH_ACTION];\n break;\n }\n }\n }\n return ta;\n}\n\nfunction trackDocument(stateObj, movefn, upfn) {\n stateObj.movefn = movefn;\n stateObj.upfn = upfn;\n document.addEventListener('mousemove', movefn);\n document.addEventListener('mouseup', upfn);\n}\n\nfunction untrackDocument(stateObj) {\n document.removeEventListener('mousemove', stateObj.movefn);\n document.removeEventListener('mouseup', stateObj.upfn);\n stateObj.movefn = null;\n stateObj.upfn = null;\n}\n\n// use a document-wide touchend listener to start the ghost-click prevention mechanism\n// Use passive event listeners, if supported, to not affect scrolling performance\ndocument.addEventListener('touchend', ignoreMouse, SUPPORTS_PASSIVE ? {passive: true} : false);\n\n/** @type {!Object} */\nexport const gestures = {};\n\n/** @type {!Array} */\nexport const recognizers = [];\n\n/**\n * Finds the element rendered on the screen at the provided coordinates.\n *\n * Similar to `document.elementFromPoint`, but pierces through\n * shadow roots.\n *\n * @param {number} x Horizontal pixel coordinate\n * @param {number} y Vertical pixel coordinate\n * @return {Element} Returns the deepest shadowRoot inclusive element\n * found at the screen position given.\n */\nexport function deepTargetFind(x, y) {\n let node = document.elementFromPoint(x, y);\n let next = node;\n // this code path is only taken when native ShadowDOM is used\n // if there is a shadowroot, it may have a node at x/y\n // if there is not a shadowroot, exit the loop\n while (next && next.shadowRoot && !window.ShadyDOM) {\n // if there is a node at x/y in the shadowroot, look deeper\n let oldNext = next;\n next = next.shadowRoot.elementFromPoint(x, y);\n // on Safari, elementFromPoint may return the shadowRoot host\n if (oldNext === next) {\n break;\n }\n if (next) {\n node = next;\n }\n }\n return node;\n}\n\n/**\n * a cheaper check than ev.composedPath()[0];\n *\n * @private\n * @param {Event|Touch} ev Event.\n * @return {EventTarget} Returns the event target.\n */\nfunction _findOriginalTarget(ev) {\n // shadowdom\n if (ev.composedPath) {\n const targets = /** @type {!Array} */(ev.composedPath());\n // It shouldn't be, but sometimes targets is empty (window on Safari).\n return targets.length > 0 ? targets[0] : ev.target;\n }\n // shadydom\n return ev.target;\n}\n\n/**\n * @private\n * @param {Event} ev Event.\n * @return {void}\n */\nfunction _handleNative(ev) {\n let handled;\n let type = ev.type;\n let node = ev.currentTarget;\n let gobj = node[GESTURE_KEY];\n if (!gobj) {\n return;\n }\n let gs = gobj[type];\n if (!gs) {\n return;\n }\n if (!ev[HANDLED_OBJ]) {\n ev[HANDLED_OBJ] = {};\n if (type.slice(0, 5) === 'touch') {\n ev = /** @type {TouchEvent} */(ev); // eslint-disable-line no-self-assign\n let t = ev.changedTouches[0];\n if (type === 'touchstart') {\n // only handle the first finger\n if (ev.touches.length === 1) {\n POINTERSTATE.touch.id = t.identifier;\n }\n }\n if (POINTERSTATE.touch.id !== t.identifier) {\n return;\n }\n if (!HAS_NATIVE_TA) {\n if (type === 'touchstart' || type === 'touchmove') {\n _handleTouchAction(ev);\n }\n }\n }\n }\n handled = ev[HANDLED_OBJ];\n // used to ignore synthetic mouse events\n if (handled.skip) {\n return;\n }\n // reset recognizer state\n for (let i = 0, r; i < recognizers.length; i++) {\n r = recognizers[i];\n if (gs[r.name] && !handled[r.name]) {\n if (r.flow && r.flow.start.indexOf(ev.type) > -1 && r.reset) {\n r.reset();\n }\n }\n }\n // enforce gesture recognizer order\n for (let i = 0, r; i < recognizers.length; i++) {\n r = recognizers[i];\n if (gs[r.name] && !handled[r.name]) {\n handled[r.name] = true;\n r[type](ev);\n }\n }\n}\n\n/**\n * @private\n * @param {TouchEvent} ev Event.\n * @return {void}\n */\nfunction _handleTouchAction(ev) {\n let t = ev.changedTouches[0];\n let type = ev.type;\n if (type === 'touchstart') {\n POINTERSTATE.touch.x = t.clientX;\n POINTERSTATE.touch.y = t.clientY;\n POINTERSTATE.touch.scrollDecided = false;\n } else if (type === 'touchmove') {\n if (POINTERSTATE.touch.scrollDecided) {\n return;\n }\n POINTERSTATE.touch.scrollDecided = true;\n let ta = firstTouchAction(ev);\n let shouldPrevent = false;\n let dx = Math.abs(POINTERSTATE.touch.x - t.clientX);\n let dy = Math.abs(POINTERSTATE.touch.y - t.clientY);\n if (!ev.cancelable) {\n // scrolling is happening\n } else if (ta === 'none') {\n shouldPrevent = true;\n } else if (ta === 'pan-x') {\n shouldPrevent = dy > dx;\n } else if (ta === 'pan-y') {\n shouldPrevent = dx > dy;\n }\n if (shouldPrevent) {\n ev.preventDefault();\n } else {\n prevent('track');\n }\n }\n}\n\n/**\n * Adds an event listener to a node for the given gesture type.\n *\n * @param {!EventTarget} node Node to add listener on\n * @param {string} evType Gesture type: `down`, `up`, `track`, or `tap`\n * @param {!function(!Event):void} handler Event listener function to call\n * @return {boolean} Returns true if a gesture event listener was added.\n */\nexport function addListener(node, evType, handler) {\n if (gestures[evType]) {\n _add(node, evType, handler);\n return true;\n }\n return false;\n}\n\n/**\n * Removes an event listener from a node for the given gesture type.\n *\n * @param {!EventTarget} node Node to remove listener from\n * @param {string} evType Gesture type: `down`, `up`, `track`, or `tap`\n * @param {!function(!Event):void} handler Event listener function previously passed to\n * `addListener`.\n * @return {boolean} Returns true if a gesture event listener was removed.\n */\nexport function removeListener(node, evType, handler) {\n if (gestures[evType]) {\n _remove(node, evType, handler);\n return true;\n }\n return false;\n}\n\n/**\n * automate the event listeners for the native events\n *\n * @private\n * @param {!EventTarget} node Node on which to add the event.\n * @param {string} evType Event type to add.\n * @param {function(!Event)} handler Event handler function.\n * @return {void}\n */\nfunction _add(node, evType, handler) {\n let recognizer = gestures[evType];\n let deps = recognizer.deps;\n let name = recognizer.name;\n let gobj = node[GESTURE_KEY];\n if (!gobj) {\n node[GESTURE_KEY] = gobj = {};\n }\n for (let i = 0, dep, gd; i < deps.length; i++) {\n dep = deps[i];\n // don't add mouse handlers on iOS because they cause gray selection overlays\n if (IS_TOUCH_ONLY && isMouseEvent(dep) && dep !== 'click') {\n continue;\n }\n gd = gobj[dep];\n if (!gd) {\n gobj[dep] = gd = {_count: 0};\n }\n if (gd._count === 0) {\n node.addEventListener(dep, _handleNative, PASSIVE_TOUCH(dep));\n }\n gd[name] = (gd[name] || 0) + 1;\n gd._count = (gd._count || 0) + 1;\n }\n node.addEventListener(evType, handler);\n if (recognizer.touchAction) {\n setTouchAction(node, recognizer.touchAction);\n }\n}\n\n/**\n * automate event listener removal for native events\n *\n * @private\n * @param {!EventTarget} node Node on which to remove the event.\n * @param {string} evType Event type to remove.\n * @param {function(!Event): void} handler Event handler function.\n * @return {void}\n */\nfunction _remove(node, evType, handler) {\n let recognizer = gestures[evType];\n let deps = recognizer.deps;\n let name = recognizer.name;\n let gobj = node[GESTURE_KEY];\n if (gobj) {\n for (let i = 0, dep, gd; i < deps.length; i++) {\n dep = deps[i];\n gd = gobj[dep];\n if (gd && gd[name]) {\n gd[name] = (gd[name] || 1) - 1;\n gd._count = (gd._count || 1) - 1;\n if (gd._count === 0) {\n node.removeEventListener(dep, _handleNative, PASSIVE_TOUCH(dep));\n }\n }\n }\n }\n node.removeEventListener(evType, handler);\n}\n\n/**\n * Registers a new gesture event recognizer for adding new custom\n * gesture event types.\n *\n * @param {!GestureRecognizer} recog Gesture recognizer descriptor\n * @return {void}\n */\nexport function register(recog) {\n recognizers.push(recog);\n for (let i = 0; i < recog.emits.length; i++) {\n gestures[recog.emits[i]] = recog;\n }\n}\n\n/**\n * @private\n * @param {string} evName Event name.\n * @return {Object} Returns the gesture for the given event name.\n */\nfunction _findRecognizerByEvent(evName) {\n for (let i = 0, r; i < recognizers.length; i++) {\n r = recognizers[i];\n for (let j = 0, n; j < r.emits.length; j++) {\n n = r.emits[j];\n if (n === evName) {\n return r;\n }\n }\n }\n return null;\n}\n\n/**\n * Sets scrolling direction on node.\n *\n * This value is checked on first move, thus it should be called prior to\n * adding event listeners.\n *\n * @param {!EventTarget} node Node to set touch action setting on\n * @param {string} value Touch action value\n * @return {void}\n */\nexport function setTouchAction(node, value) {\n if (HAS_NATIVE_TA && node instanceof HTMLElement) {\n // NOTE: add touchAction async so that events can be added in\n // custom element constructors. Otherwise we run afoul of custom\n // elements restriction against settings attributes (style) in the\n // constructor.\n microTask.run(() => {\n node.style.touchAction = value;\n });\n }\n node[TOUCH_ACTION] = value;\n}\n\n/**\n * Dispatches an event on the `target` element of `type` with the given\n * `detail`.\n * @private\n * @param {!EventTarget} target The element on which to fire an event.\n * @param {string} type The type of event to fire.\n * @param {!Object=} detail The detail object to populate on the event.\n * @return {void}\n */\nfunction _fire(target, type, detail) {\n let ev = new Event(type, { bubbles: true, cancelable: true, composed: true });\n ev.detail = detail;\n target.dispatchEvent(ev);\n // forward `preventDefault` in a clean way\n if (ev.defaultPrevented) {\n let preventer = detail.preventer || detail.sourceEvent;\n if (preventer && preventer.preventDefault) {\n preventer.preventDefault();\n }\n }\n}\n\n/**\n * Prevents the dispatch and default action of the given event name.\n *\n * @param {string} evName Event name.\n * @return {void}\n */\nexport function prevent(evName) {\n let recognizer = _findRecognizerByEvent(evName);\n if (recognizer.info) {\n recognizer.info.prevent = true;\n }\n}\n\n/**\n * Reset the 2500ms timeout on processing mouse input after detecting touch input.\n *\n * Touch inputs create synthesized mouse inputs anywhere from 0 to 2000ms after the touch.\n * This method should only be called during testing with simulated touch inputs.\n * Calling this method in production may cause duplicate taps or other Gestures.\n *\n * @return {void}\n */\nexport function resetMouseCanceller() {\n if (POINTERSTATE.mouse.mouseIgnoreJob) {\n POINTERSTATE.mouse.mouseIgnoreJob.flush();\n }\n}\n\n/* eslint-disable valid-jsdoc */\n\nregister({\n name: 'downup',\n deps: ['mousedown', 'touchstart', 'touchend'],\n flow: {\n start: ['mousedown', 'touchstart'],\n end: ['mouseup', 'touchend']\n },\n emits: ['down', 'up'],\n\n info: {\n movefn: null,\n upfn: null\n },\n\n /**\n * @this {GestureRecognizer}\n * @return {void}\n */\n reset: function() {\n untrackDocument(this.info);\n },\n\n /**\n * @this {GestureRecognizer}\n * @param {MouseEvent} e\n * @return {void}\n */\n mousedown: function(e) {\n if (!hasLeftMouseButton(e)) {\n return;\n }\n let t = _findOriginalTarget(e);\n let self = this;\n let movefn = function movefn(e) {\n if (!hasLeftMouseButton(e)) {\n downupFire('up', t, e);\n untrackDocument(self.info);\n }\n };\n let upfn = function upfn(e) {\n if (hasLeftMouseButton(e)) {\n downupFire('up', t, e);\n }\n untrackDocument(self.info);\n };\n trackDocument(this.info, movefn, upfn);\n downupFire('down', t, e);\n },\n /**\n * @this {GestureRecognizer}\n * @param {TouchEvent} e\n * @return {void}\n */\n touchstart: function(e) {\n downupFire('down', _findOriginalTarget(e), e.changedTouches[0], e);\n },\n /**\n * @this {GestureRecognizer}\n * @param {TouchEvent} e\n * @return {void}\n */\n touchend: function(e) {\n downupFire('up', _findOriginalTarget(e), e.changedTouches[0], e);\n }\n});\n\n/**\n * @param {string} type\n * @param {EventTarget} target\n * @param {Event|Touch} event\n * @param {Event=} preventer\n * @return {void}\n */\nfunction downupFire(type, target, event, preventer) {\n if (!target) {\n return;\n }\n _fire(target, type, {\n x: event.clientX,\n y: event.clientY,\n sourceEvent: event,\n preventer: preventer,\n prevent: function(e) {\n return prevent(e);\n }\n });\n}\n\nregister({\n name: 'track',\n touchAction: 'none',\n deps: ['mousedown', 'touchstart', 'touchmove', 'touchend'],\n flow: {\n start: ['mousedown', 'touchstart'],\n end: ['mouseup', 'touchend']\n },\n emits: ['track'],\n\n info: {\n x: 0,\n y: 0,\n state: 'start',\n started: false,\n moves: [],\n /** @this {GestureInfo} */\n addMove: function(move) {\n if (this.moves.length > TRACK_LENGTH) {\n this.moves.shift();\n }\n this.moves.push(move);\n },\n movefn: null,\n upfn: null,\n prevent: false\n },\n\n /**\n * @this {GestureRecognizer}\n * @return {void}\n */\n reset: function() {\n this.info.state = 'start';\n this.info.started = false;\n this.info.moves = [];\n this.info.x = 0;\n this.info.y = 0;\n this.info.prevent = false;\n untrackDocument(this.info);\n },\n\n /**\n * @this {GestureRecognizer}\n * @param {MouseEvent} e\n * @return {void}\n */\n mousedown: function(e) {\n if (!hasLeftMouseButton(e)) {\n return;\n }\n let t = _findOriginalTarget(e);\n let self = this;\n let movefn = function movefn(e) {\n let x = e.clientX, y = e.clientY;\n if (trackHasMovedEnough(self.info, x, y)) {\n // first move is 'start', subsequent moves are 'move', mouseup is 'end'\n self.info.state = self.info.started ? (e.type === 'mouseup' ? 'end' : 'track') : 'start';\n if (self.info.state === 'start') {\n // if and only if tracking, always prevent tap\n prevent('tap');\n }\n self.info.addMove({x: x, y: y});\n if (!hasLeftMouseButton(e)) {\n // always fire \"end\"\n self.info.state = 'end';\n untrackDocument(self.info);\n }\n if (t) {\n trackFire(self.info, t, e);\n }\n self.info.started = true;\n }\n };\n let upfn = function upfn(e) {\n if (self.info.started) {\n movefn(e);\n }\n\n // remove the temporary listeners\n untrackDocument(self.info);\n };\n // add temporary document listeners as mouse retargets\n trackDocument(this.info, movefn, upfn);\n this.info.x = e.clientX;\n this.info.y = e.clientY;\n },\n /**\n * @this {GestureRecognizer}\n * @param {TouchEvent} e\n * @return {void}\n */\n touchstart: function(e) {\n let ct = e.changedTouches[0];\n this.info.x = ct.clientX;\n this.info.y = ct.clientY;\n },\n /**\n * @this {GestureRecognizer}\n * @param {TouchEvent} e\n * @return {void}\n */\n touchmove: function(e) {\n let t = _findOriginalTarget(e);\n let ct = e.changedTouches[0];\n let x = ct.clientX, y = ct.clientY;\n if (trackHasMovedEnough(this.info, x, y)) {\n if (this.info.state === 'start') {\n // if and only if tracking, always prevent tap\n prevent('tap');\n }\n this.info.addMove({x: x, y: y});\n trackFire(this.info, t, ct);\n this.info.state = 'track';\n this.info.started = true;\n }\n },\n /**\n * @this {GestureRecognizer}\n * @param {TouchEvent} e\n * @return {void}\n */\n touchend: function(e) {\n let t = _findOriginalTarget(e);\n let ct = e.changedTouches[0];\n // only trackend if track was started and not aborted\n if (this.info.started) {\n // reset started state on up\n this.info.state = 'end';\n this.info.addMove({x: ct.clientX, y: ct.clientY});\n trackFire(this.info, t, ct);\n }\n }\n});\n\n/**\n * @param {!GestureInfo} info\n * @param {number} x\n * @param {number} y\n * @return {boolean}\n */\nfunction trackHasMovedEnough(info, x, y) {\n if (info.prevent) {\n return false;\n }\n if (info.started) {\n return true;\n }\n let dx = Math.abs(info.x - x);\n let dy = Math.abs(info.y - y);\n return (dx >= TRACK_DISTANCE || dy >= TRACK_DISTANCE);\n}\n\n/**\n * @param {!GestureInfo} info\n * @param {?EventTarget} target\n * @param {Touch} touch\n * @return {void}\n */\nfunction trackFire(info, target, touch) {\n if (!target) {\n return;\n }\n let secondlast = info.moves[info.moves.length - 2];\n let lastmove = info.moves[info.moves.length - 1];\n let dx = lastmove.x - info.x;\n let dy = lastmove.y - info.y;\n let ddx, ddy = 0;\n if (secondlast) {\n ddx = lastmove.x - secondlast.x;\n ddy = lastmove.y - secondlast.y;\n }\n _fire(target, 'track', {\n state: info.state,\n x: touch.clientX,\n y: touch.clientY,\n dx: dx,\n dy: dy,\n ddx: ddx,\n ddy: ddy,\n sourceEvent: touch,\n hover: function() {\n return deepTargetFind(touch.clientX, touch.clientY);\n }\n });\n}\n\nregister({\n name: 'tap',\n deps: ['mousedown', 'click', 'touchstart', 'touchend'],\n flow: {\n start: ['mousedown', 'touchstart'],\n end: ['click', 'touchend']\n },\n emits: ['tap'],\n info: {\n x: NaN,\n y: NaN,\n prevent: false\n },\n /**\n * @this {GestureRecognizer}\n * @return {void}\n */\n reset: function() {\n this.info.x = NaN;\n this.info.y = NaN;\n this.info.prevent = false;\n },\n /**\n * @this {GestureRecognizer}\n * @param {MouseEvent} e\n * @return {void}\n */\n mousedown: function(e) {\n if (hasLeftMouseButton(e)) {\n this.info.x = e.clientX;\n this.info.y = e.clientY;\n }\n },\n /**\n * @this {GestureRecognizer}\n * @param {MouseEvent} e\n * @return {void}\n */\n click: function(e) {\n if (hasLeftMouseButton(e)) {\n trackForward(this.info, e);\n }\n },\n /**\n * @this {GestureRecognizer}\n * @param {TouchEvent} e\n * @return {void}\n */\n touchstart: function(e) {\n const touch = e.changedTouches[0];\n this.info.x = touch.clientX;\n this.info.y = touch.clientY;\n },\n /**\n * @this {GestureRecognizer}\n * @param {TouchEvent} e\n * @return {void}\n */\n touchend: function(e) {\n trackForward(this.info, e.changedTouches[0], e);\n }\n});\n\n/**\n * @param {!GestureInfo} info\n * @param {Event | Touch} e\n * @param {Event=} preventer\n * @return {void}\n */\nfunction trackForward(info, e, preventer) {\n let dx = Math.abs(e.clientX - info.x);\n let dy = Math.abs(e.clientY - info.y);\n // find original target from `preventer` for TouchEvents, or `e` for MouseEvents\n let t = _findOriginalTarget((preventer || e));\n if (!t || (canBeDisabled[/** @type {!HTMLElement} */(t).localName] && t.hasAttribute('disabled'))) {\n return;\n }\n // dx,dy can be NaN if `click` has been simulated and there was no `down` for `start`\n if (isNaN(dx) || isNaN(dy) || (dx <= TAP_DISTANCE && dy <= TAP_DISTANCE) || isSyntheticClick(e)) {\n // prevent taps from being generated if an event has canceled them\n if (!info.prevent) {\n _fire(t, 'tap', {\n x: e.clientX,\n y: e.clientY,\n sourceEvent: e,\n preventer: preventer\n });\n }\n }\n}\n\n/* eslint-enable valid-jsdoc */\n\n/** @deprecated */\nexport const findOriginalTarget = _findOriginalTarget;\n\n/** @deprecated */\nexport const add = addListener;\n\n/** @deprecated */\nexport const remove = removeListener;\n","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\nimport './boot.js';\n\n/**\n * Module with utilities for manipulating structured data path strings.\n *\n * @summary Module with utilities for manipulating structured data path strings.\n */\n\n/**\n * Returns true if the given string is a structured data path (has dots).\n *\n * Example:\n *\n * ```\n * isPath('foo.bar.baz') // true\n * isPath('foo') // false\n * ```\n *\n * @param {string} path Path string\n * @return {boolean} True if the string contained one or more dots\n */\nexport function isPath(path) {\n return path.indexOf('.') >= 0;\n}\n\n/**\n * Returns the root property name for the given path.\n *\n * Example:\n *\n * ```\n * root('foo.bar.baz') // 'foo'\n * root('foo') // 'foo'\n * ```\n *\n * @param {string} path Path string\n * @return {string} Root property name\n */\nexport function root(path) {\n let dotIndex = path.indexOf('.');\n if (dotIndex === -1) {\n return path;\n }\n return path.slice(0, dotIndex);\n}\n\n/**\n * Given `base` is `foo.bar`, `foo` is an ancestor, `foo.bar` is not\n * Returns true if the given path is an ancestor of the base path.\n *\n * Example:\n *\n * ```\n * isAncestor('foo.bar', 'foo') // true\n * isAncestor('foo.bar', 'foo.bar') // false\n * isAncestor('foo.bar', 'foo.bar.baz') // false\n * ```\n *\n * @param {string} base Path string to test against.\n * @param {string} path Path string to test.\n * @return {boolean} True if `path` is an ancestor of `base`.\n */\nexport function isAncestor(base, path) {\n // base.startsWith(path + '.');\n return base.indexOf(path + '.') === 0;\n}\n\n/**\n * Given `base` is `foo.bar`, `foo.bar.baz` is an descendant\n *\n * Example:\n *\n * ```\n * isDescendant('foo.bar', 'foo.bar.baz') // true\n * isDescendant('foo.bar', 'foo.bar') // false\n * isDescendant('foo.bar', 'foo') // false\n * ```\n *\n * @param {string} base Path string to test against.\n * @param {string} path Path string to test.\n * @return {boolean} True if `path` is a descendant of `base`.\n */\nexport function isDescendant(base, path) {\n // path.startsWith(base + '.');\n return path.indexOf(base + '.') === 0;\n}\n\n/**\n * Replaces a previous base path with a new base path, preserving the\n * remainder of the path.\n *\n * User must ensure `path` has a prefix of `base`.\n *\n * Example:\n *\n * ```\n * translate('foo.bar', 'zot', 'foo.bar.baz') // 'zot.baz'\n * ```\n *\n * @param {string} base Current base string to remove\n * @param {string} newBase New base string to replace with\n * @param {string} path Path to translate\n * @return {string} Translated string\n */\nexport function translate(base, newBase, path) {\n return newBase + path.slice(base.length);\n}\n\n/**\n * @param {string} base Path string to test against\n * @param {string} path Path string to test\n * @return {boolean} True if `path` is equal to `base`\n */\nexport function matches(base, path) {\n return (base === path) ||\n isAncestor(base, path) ||\n isDescendant(base, path);\n}\n\n/**\n * Converts array-based paths to flattened path. String-based paths\n * are returned as-is.\n *\n * Example:\n *\n * ```\n * normalize(['foo.bar', 0, 'baz']) // 'foo.bar.0.baz'\n * normalize('foo.bar.0.baz') // 'foo.bar.0.baz'\n * ```\n *\n * @param {string | !Array} path Input path\n * @return {string} Flattened path\n */\nexport function normalize(path) {\n if (Array.isArray(path)) {\n let parts = [];\n for (let i=0; i} path Input path\n * @return {!Array} Array of path parts\n * @suppress {checkTypes}\n */\nexport function split(path) {\n if (Array.isArray(path)) {\n return normalize(path).split('.');\n }\n return path.toString().split('.');\n}\n\n/**\n * Reads a value from a path. If any sub-property in the path is `undefined`,\n * this method returns `undefined` (will never throw.\n *\n * @param {Object} root Object from which to dereference path from\n * @param {string | !Array} path Path to read\n * @param {Object=} info If an object is provided to `info`, the normalized\n * (flattened) path will be set to `info.path`.\n * @return {*} Value at path, or `undefined` if the path could not be\n * fully dereferenced.\n */\nexport function get(root, path, info) {\n let prop = root;\n let parts = split(path);\n // Loop over path parts[0..n-1] and dereference\n for (let i=0; i} path Path to set\n * @param {*} value Value to set to path\n * @return {string | undefined} The normalized version of the input path\n */\nexport function set(root, path, value) {\n let prop = root;\n let parts = split(path);\n let last = parts[parts.length-1];\n if (parts.length > 1) {\n // Loop over path parts[0..n-2] and dereference\n for (let i=0; i m[1].toUpperCase()\n )\n );\n}\n\n/**\n * Converts \"camelCase\" identifier (e.g. `fooBarBaz`) to \"dash-case\"\n * (e.g. `foo-bar-baz`).\n *\n * @param {string} camel Camel-case identifier\n * @return {string} Dash-case representation of the identifier\n */\nexport function camelToDashCase(camel) {\n return caseMap[camel] || (\n caseMap[camel] = camel.replace(CAMEL_TO_DASH, '-$1').toLowerCase()\n );\n}\n","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\n/**\n * Module for scheduling flushable pre-render and post-render tasks.\n *\n * @summary Module for scheduling flushable pre-render and post-render tasks.\n */\n\nimport './boot.js';\n\nlet scheduled = false;\nlet beforeRenderQueue = [];\nlet afterRenderQueue = [];\n\nfunction schedule() {\n scheduled = true;\n // before next render\n requestAnimationFrame(function() {\n scheduled = false;\n flushQueue(beforeRenderQueue);\n // after the render\n setTimeout(function() {\n runQueue(afterRenderQueue);\n });\n });\n}\n\nfunction flushQueue(queue) {\n while (queue.length) {\n callMethod(queue.shift());\n }\n}\n\nfunction runQueue(queue) {\n for (let i=0, l=queue.length; i < l; i++) {\n callMethod(queue.shift());\n }\n}\n\nfunction callMethod(info) {\n const context = info[0];\n const callback = info[1];\n const args = info[2];\n try {\n callback.apply(context, args);\n } catch(e) {\n setTimeout(() => {\n throw e;\n });\n }\n}\n\n/**\n * Flushes all `beforeNextRender` tasks, followed by all `afterNextRender`\n * tasks.\n *\n * @return {void}\n */\nexport function flush() {\n while (beforeRenderQueue.length || afterRenderQueue.length) {\n flushQueue(beforeRenderQueue);\n flushQueue(afterRenderQueue);\n }\n scheduled = false;\n}\n\n\n/**\n * Enqueues a callback which will be run before the next render, at\n * `requestAnimationFrame` timing.\n *\n * This method is useful for enqueuing work that requires DOM measurement,\n * since measurement may not be reliable in custom element callbacks before\n * the first render, as well as for batching measurement tasks in general.\n *\n * Tasks in this queue may be flushed by calling `flush()`.\n *\n * @param {*} context Context object the callback function will be bound to\n * @param {function(...*):void} callback Callback function\n * @param {!Array=} args An array of arguments to call the callback function with\n * @return {void}\n */\nexport function beforeNextRender(context, callback, args) {\n if (!scheduled) {\n schedule();\n }\n beforeRenderQueue.push([context, callback, args]);\n}\n\n/**\n * Enqueues a callback which will be run after the next render, equivalent\n * to one task (`setTimeout`) after the next `requestAnimationFrame`.\n *\n * This method is useful for tuning the first-render performance of an\n * element or application by deferring non-critical work until after the\n * first paint. Typical non-render-critical work may include adding UI\n * event listeners and aria attributes.\n *\n * @param {*} context Context object the callback function will be bound to\n * @param {function(...*):void} callback Callback function\n * @param {!Array=} args An array of arguments to call the callback function with\n * @return {void}\n */\nexport function afterNextRender(context, callback, args) {\n if (!scheduled) {\n schedule();\n }\n afterRenderQueue.push([context, callback, args]);\n}\n\n","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\nimport '../utils/boot.js';\n\nimport { dedupingMixin } from '../utils/mixin.js';\nimport { PropertiesChanged } from './properties-changed.js';\n\n/**\n * Creates a copy of `props` with each property normalized such that\n * upgraded it is an object with at least a type property { type: Type}.\n *\n * @param {Object} props Properties to normalize\n * @return {Object} Copy of input `props` with normalized properties that\n * are in the form {type: Type}\n * @private\n */\nfunction normalizeProperties(props) {\n const output = {};\n for (let p in props) {\n const o = props[p];\n output[p] = (typeof o === 'function') ? {type: o} : o;\n }\n return output;\n}\n\n/**\n * Mixin that provides a minimal starting point to using the PropertiesChanged\n * mixin by providing a mechanism to declare properties in a static\n * getter (e.g. static get properties() { return { foo: String } }). Changes\n * are reported via the `_propertiesChanged` method.\n *\n * This mixin provides no specific support for rendering. Users are expected\n * to create a ShadowRoot and put content into it and update it in whatever\n * way makes sense. This can be done in reaction to properties changing by\n * implementing `_propertiesChanged`.\n *\n * @mixinFunction\n * @polymer\n * @appliesMixin PropertiesChanged\n * @summary Mixin that provides a minimal starting point for using\n * the PropertiesChanged mixin by providing a declarative `properties` object.\n */\nexport const PropertiesMixin = dedupingMixin(superClass => {\n\n /**\n * @constructor\n * @implements {Polymer_PropertiesChanged}\n * @private\n */\n const base = PropertiesChanged(superClass);\n\n /**\n * Returns the super class constructor for the given class, if it is an\n * instance of the PropertiesMixin.\n *\n * @param {!PropertiesMixinConstructor} constructor PropertiesMixin constructor\n * @return {?PropertiesMixinConstructor} Super class constructor\n */\n function superPropertiesClass(constructor) {\n const superCtor = Object.getPrototypeOf(constructor);\n\n // Note, the `PropertiesMixin` class below only refers to the class\n // generated by this call to the mixin; the instanceof test only works\n // because the mixin is deduped and guaranteed only to apply once, hence\n // all constructors in a proto chain will see the same `PropertiesMixin`\n return (superCtor.prototype instanceof PropertiesMixin) ?\n /** @type {!PropertiesMixinConstructor} */ (superCtor) : null;\n }\n\n /**\n * Returns a memoized version of the `properties` object for the\n * given class. Properties not in object format are converted to at\n * least {type}.\n *\n * @param {PropertiesMixinConstructor} constructor PropertiesMixin constructor\n * @return {Object} Memoized properties object\n */\n function ownProperties(constructor) {\n if (!constructor.hasOwnProperty(JSCompiler_renameProperty('__ownProperties', constructor))) {\n let props = null;\n\n if (constructor.hasOwnProperty(JSCompiler_renameProperty('properties', constructor))) {\n const properties = constructor.properties;\n\n if (properties) {\n props = normalizeProperties(properties);\n }\n }\n\n constructor.__ownProperties = props;\n }\n return constructor.__ownProperties;\n }\n\n /**\n * @polymer\n * @mixinClass\n * @extends {base}\n * @implements {Polymer_PropertiesMixin}\n * @unrestricted\n */\n class PropertiesMixin extends base {\n\n /**\n * Implements standard custom elements getter to observes the attributes\n * listed in `properties`.\n * @suppress {missingProperties} Interfaces in closure do not inherit statics, but classes do\n */\n static get observedAttributes() {\n const props = this._properties;\n return props ? Object.keys(props).map(p => this.attributeNameForProperty(p)) : [];\n }\n\n /**\n * Finalizes an element definition, including ensuring any super classes\n * are also finalized. This includes ensuring property\n * accessors exist on the element prototype. This method calls\n * `_finalizeClass` to finalize each constructor in the prototype chain.\n * @return {void}\n */\n static finalize() {\n if (!this.hasOwnProperty(JSCompiler_renameProperty('__finalized', this))) {\n const superCtor = superPropertiesClass(/** @type {!PropertiesMixinConstructor} */(this));\n if (superCtor) {\n superCtor.finalize();\n }\n this.__finalized = true;\n this._finalizeClass();\n }\n }\n\n /**\n * Finalize an element class. This includes ensuring property\n * accessors exist on the element prototype. This method is called by\n * `finalize` and finalizes the class constructor.\n *\n * @protected\n */\n static _finalizeClass() {\n const props = ownProperties(/** @type {!PropertiesMixinConstructor} */(this));\n if (props) {\n this.createProperties(props);\n }\n }\n\n /**\n * Returns a memoized version of all properties, including those inherited\n * from super classes. Properties not in object format are converted to\n * at least {type}.\n *\n * @return {Object} Object containing properties for this class\n * @protected\n */\n static get _properties() {\n if (!this.hasOwnProperty(\n JSCompiler_renameProperty('__properties', this))) {\n const superCtor = superPropertiesClass(/** @type {!PropertiesMixinConstructor} */(this));\n this.__properties = Object.assign({},\n superCtor && superCtor._properties,\n ownProperties(/** @type {PropertiesMixinConstructor} */(this)));\n }\n return this.__properties;\n }\n\n /**\n * Overrides `PropertiesChanged` method to return type specified in the\n * static `properties` object for the given property.\n * @param {string} name Name of property\n * @return {*} Type to which to deserialize attribute\n *\n * @protected\n */\n static typeForProperty(name) {\n const info = this._properties[name];\n return info && info.type;\n }\n\n /**\n * Overrides `PropertiesChanged` method and adds a call to\n * `finalize` which lazily configures the element's property accessors.\n * @override\n * @return {void}\n */\n _initializeProperties() {\n this.constructor.finalize();\n super._initializeProperties();\n }\n\n /**\n * Called when the element is added to a document.\n * Calls `_enableProperties` to turn on property system from\n * `PropertiesChanged`.\n * @suppress {missingProperties} Super may or may not implement the callback\n * @return {void}\n * @override\n */\n connectedCallback() {\n if (super.connectedCallback) {\n super.connectedCallback();\n }\n this._enableProperties();\n }\n\n /**\n * Called when the element is removed from a document\n * @suppress {missingProperties} Super may or may not implement the callback\n * @return {void}\n * @override\n */\n disconnectedCallback() {\n if (super.disconnectedCallback) {\n super.disconnectedCallback();\n }\n }\n\n }\n\n return PropertiesMixin;\n\n});\n","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\nimport '../utils/boot.js';\n\nimport { rootPath, strictTemplatePolicy, allowTemplateFromDomModule } from '../utils/settings.js';\nimport { dedupingMixin } from '../utils/mixin.js';\nimport { stylesFromTemplate, stylesFromModuleImports } from '../utils/style-gather.js';\nimport { pathFromUrl, resolveCss, resolveUrl } from '../utils/resolve-url.js';\nimport { DomModule } from '../elements/dom-module.js';\nimport { PropertyEffects } from './property-effects.js';\nimport { PropertiesMixin } from './properties-mixin.js';\n\n/**\n * Current Polymer version in Semver notation.\n * @type {string} Semver notation of the current version of Polymer.\n */\nexport const version = '3.0.5';\n\n/**\n * Element class mixin that provides the core API for Polymer's meta-programming\n * features including template stamping, data-binding, attribute deserialization,\n * and property change observation.\n *\n * Subclassers may provide the following static getters to return metadata\n * used to configure Polymer's features for the class:\n *\n * - `static get is()`: When the template is provided via a `dom-module`,\n * users should return the `dom-module` id from a static `is` getter. If\n * no template is needed or the template is provided directly via the\n * `template` getter, there is no need to define `is` for the element.\n *\n * - `static get template()`: Users may provide the template directly (as\n * opposed to via `dom-module`) by implementing a static `template` getter.\n * The getter must return an `HTMLTemplateElement`.\n *\n * - `static get properties()`: Should return an object describing\n * property-related metadata used by Polymer features (key: property name\n * value: object containing property metadata). Valid keys in per-property\n * metadata include:\n * - `type` (String|Number|Object|Array|...): Used by\n * `attributeChangedCallback` to determine how string-based attributes\n * are deserialized to JavaScript property values.\n * - `notify` (boolean): Causes a change in the property to fire a\n * non-bubbling event called `-changed`. Elements that have\n * enabled two-way binding to the property use this event to observe changes.\n * - `readOnly` (boolean): Creates a getter for the property, but no setter.\n * To set a read-only property, use the private setter method\n * `_setProperty(property, value)`.\n * - `observer` (string): Observer method name that will be called when\n * the property changes. The arguments of the method are\n * `(value, previousValue)`.\n * - `computed` (string): String describing method and dependent properties\n * for computing the value of this property (e.g. `'computeFoo(bar, zot)'`).\n * Computed properties are read-only by default and can only be changed\n * via the return value of the computing method.\n *\n * - `static get observers()`: Array of strings describing multi-property\n * observer methods and their dependent properties (e.g.\n * `'observeABC(a, b, c)'`).\n *\n * The base class provides default implementations for the following standard\n * custom element lifecycle callbacks; users may override these, but should\n * call the super method to ensure\n * - `constructor`: Run when the element is created or upgraded\n * - `connectedCallback`: Run each time the element is connected to the\n * document\n * - `disconnectedCallback`: Run each time the element is disconnected from\n * the document\n * - `attributeChangedCallback`: Run each time an attribute in\n * `observedAttributes` is set or removed (note: this element's default\n * `observedAttributes` implementation will automatically return an array\n * of dash-cased attributes based on `properties`)\n *\n * @mixinFunction\n * @polymer\n * @appliesMixin PropertyEffects\n * @appliesMixin PropertiesMixin\n * @property rootPath {string} Set to the value of `rootPath`,\n * which defaults to the main document path\n * @property importPath {string} Set to the value of the class's static\n * `importPath` property, which defaults to the path of this element's\n * `dom-module` (when `is` is used), but can be overridden for other\n * import strategies.\n * @summary Element class mixin that provides the core API for Polymer's\n * meta-programming features.\n */\nexport const ElementMixin = dedupingMixin(base => {\n\n /**\n * @constructor\n * @extends {base}\n * @implements {Polymer_PropertyEffects}\n * @implements {Polymer_PropertiesMixin}\n * @private\n */\n const polymerElementBase = PropertiesMixin(PropertyEffects(base));\n\n /**\n * Returns a list of properties with default values.\n * This list is created as an optimization since it is a subset of\n * the list returned from `_properties`.\n * This list is used in `_initializeProperties` to set property defaults.\n *\n * @param {PolymerElementConstructor} constructor Element class\n * @return {PolymerElementProperties} Flattened properties for this class\n * that have default values\n * @private\n */\n function propertyDefaults(constructor) {\n if (!constructor.hasOwnProperty(\n JSCompiler_renameProperty('__propertyDefaults', constructor))) {\n constructor.__propertyDefaults = null;\n let props = constructor._properties;\n for (let p in props) {\n let info = props[p];\n if ('value' in info) {\n constructor.__propertyDefaults = constructor.__propertyDefaults || {};\n constructor.__propertyDefaults[p] = info;\n }\n }\n }\n return constructor.__propertyDefaults;\n }\n\n /**\n * Returns a memoized version of the `observers` array.\n * @param {PolymerElementConstructor} constructor Element class\n * @return {Array} Array containing own observers for the given class\n * @protected\n */\n function ownObservers(constructor) {\n if (!constructor.hasOwnProperty(\n JSCompiler_renameProperty('__ownObservers', constructor))) {\n constructor.__ownObservers =\n constructor.hasOwnProperty(JSCompiler_renameProperty('observers', constructor)) ?\n /** @type {PolymerElementConstructor} */ (constructor).observers : null;\n }\n return constructor.__ownObservers;\n }\n\n /**\n * Creates effects for a property.\n *\n * Note, once a property has been set to\n * `readOnly`, `computed`, `reflectToAttribute`, or `notify`\n * these values may not be changed. For example, a subclass cannot\n * alter these settings. However, additional `observers` may be added\n * by subclasses.\n *\n * The info object should contain property metadata as follows:\n *\n * * `type`: {function} type to which an attribute matching the property\n * is deserialized. Note the property is camel-cased from a dash-cased\n * attribute. For example, 'foo-bar' attribute is deserialized to a\n * property named 'fooBar'.\n *\n * * `readOnly`: {boolean} creates a readOnly property and\n * makes a private setter for the private of the form '_setFoo' for a\n * property 'foo',\n *\n * * `computed`: {string} creates a computed property. A computed property\n * is also automatically set to `readOnly: true`. The value is calculated\n * by running a method and arguments parsed from the given string. For\n * example 'compute(foo)' will compute a given property when the\n * 'foo' property changes by executing the 'compute' method. This method\n * must return the computed value.\n *\n * * `reflectToAttribute`: {boolean} If true, the property value is reflected\n * to an attribute of the same name. Note, the attribute is dash-cased\n * so a property named 'fooBar' is reflected as 'foo-bar'.\n *\n * * `notify`: {boolean} sends a non-bubbling notification event when\n * the property changes. For example, a property named 'foo' sends an\n * event named 'foo-changed' with `event.detail` set to the value of\n * the property.\n *\n * * observer: {string} name of a method that runs when the property\n * changes. The arguments of the method are (value, previousValue).\n *\n * Note: Users may want control over modifying property\n * effects via subclassing. For example, a user might want to make a\n * reflectToAttribute property not do so in a subclass. We've chosen to\n * disable this because it leads to additional complication.\n * For example, a readOnly effect generates a special setter. If a subclass\n * disables the effect, the setter would fail unexpectedly.\n * Based on feedback, we may want to try to make effects more malleable\n * and/or provide an advanced api for manipulating them.\n * Also consider adding warnings when an effect cannot be changed.\n *\n * @param {!PolymerElement} proto Element class prototype to add accessors\n * and effects to\n * @param {string} name Name of the property.\n * @param {Object} info Info object from which to create property effects.\n * Supported keys:\n * @param {Object} allProps Flattened map of all properties defined in this\n * element (including inherited properties)\n * @return {void}\n * @private\n */\n function createPropertyFromConfig(proto, name, info, allProps) {\n // computed forces readOnly...\n if (info.computed) {\n info.readOnly = true;\n }\n // Note, since all computed properties are readOnly, this prevents\n // adding additional computed property effects (which leads to a confusing\n // setup where multiple triggers for setting a property)\n // While we do have `hasComputedEffect` this is set on the property's\n // dependencies rather than itself.\n if (info.computed && !proto._hasReadOnlyEffect(name)) {\n proto._createComputedProperty(name, info.computed, allProps);\n }\n if (info.readOnly && !proto._hasReadOnlyEffect(name)) {\n proto._createReadOnlyProperty(name, !info.computed);\n }\n if (info.reflectToAttribute && !proto._hasReflectEffect(name)) {\n proto._createReflectedProperty(name);\n }\n if (info.notify && !proto._hasNotifyEffect(name)) {\n proto._createNotifyingProperty(name);\n }\n // always add observer\n if (info.observer) {\n proto._createPropertyObserver(name, info.observer, allProps[info.observer]);\n }\n // always create the mapping from attribute back to property for deserialization.\n proto._addPropertyToAttributeMap(name);\n }\n\n /**\n * Process all style elements in the element template. Styles with the\n * `include` attribute are processed such that any styles in\n * the associated \"style modules\" are included in the element template.\n * @param {PolymerElementConstructor} klass Element class\n * @param {!HTMLTemplateElement} template Template to process\n * @param {string} is Name of element\n * @param {string} baseURI Base URI for element\n * @private\n */\n function processElementStyles(klass, template, is, baseURI) {\n const templateStyles = template.content.querySelectorAll('style');\n const stylesWithImports = stylesFromTemplate(template);\n // insert styles from at the top of the template\n const linkedStyles = stylesFromModuleImports(is);\n const firstTemplateChild = template.content.firstElementChild;\n for (let idx = 0; idx < linkedStyles.length; idx++) {\n let s = linkedStyles[idx];\n s.textContent = klass._processStyleText(s.textContent, baseURI);\n template.content.insertBefore(s, firstTemplateChild);\n }\n // keep track of the last \"concrete\" style in the template we have encountered\n let templateStyleIndex = 0;\n // ensure all gathered styles are actually in this template.\n for (let i = 0; i < stylesWithImports.length; i++) {\n let s = stylesWithImports[i];\n let templateStyle = templateStyles[templateStyleIndex];\n // if the style is not in this template, it's been \"included\" and\n // we put a clone of it in the template before the style that included it\n if (templateStyle !== s) {\n s = s.cloneNode(true);\n templateStyle.parentNode.insertBefore(s, templateStyle);\n } else {\n templateStyleIndex++;\n }\n s.textContent = klass._processStyleText(s.textContent, baseURI);\n }\n if (window.ShadyCSS) {\n window.ShadyCSS.prepareTemplate(template, is);\n }\n }\n\n /**\n * Look up template from dom-module for element\n *\n * @param {!string} is Element name to look up\n * @return {!HTMLTemplateElement} Template found in dom module, or\n * undefined if not found\n * @protected\n */\n function getTemplateFromDomModule(is) {\n let template = null;\n // Under strictTemplatePolicy in 3.x+, dom-module lookup is only allowed\n // when opted-in via allowTemplateFromDomModule\n if (is && (!strictTemplatePolicy || allowTemplateFromDomModule)) {\n template = DomModule.import(is, 'template');\n // Under strictTemplatePolicy, require any element with an `is`\n // specified to have a dom-module\n if (strictTemplatePolicy && !template) {\n throw new Error(`strictTemplatePolicy: expecting dom-module or null template for ${is}`);\n }\n }\n return template;\n }\n\n /**\n * @polymer\n * @mixinClass\n * @unrestricted\n * @implements {Polymer_ElementMixin}\n */\n class PolymerElement extends polymerElementBase {\n\n /**\n * Current Polymer version in Semver notation.\n * @type {string} Semver notation of the current version of Polymer.\n */\n static get polymerElementVersion() {\n return version;\n }\n\n /**\n * Override of PropertiesMixin _finalizeClass to create observers and\n * find the template.\n * @return {void}\n * @protected\n * @override\n * @suppress {missingProperties} Interfaces in closure do not inherit statics, but classes do\n */\n static _finalizeClass() {\n super._finalizeClass();\n if (this.hasOwnProperty(\n JSCompiler_renameProperty('is', this)) && this.is) {\n register(this.prototype);\n }\n const observers = ownObservers(this);\n if (observers) {\n this.createObservers(observers, this._properties);\n }\n // note: create \"working\" template that is finalized at instance time\n let template = /** @type {PolymerElementConstructor} */ (this).template;\n if (template) {\n if (typeof template === 'string') {\n console.error('template getter must return HTMLTemplateElement');\n template = null;\n } else {\n template = template.cloneNode(true);\n }\n }\n\n this.prototype._template = template;\n }\n\n /**\n * Override of PropertiesChanged createProperties to create accessors\n * and property effects for all of the properties.\n * @return {void}\n * @protected\n * @override\n */\n static createProperties(props) {\n for (let p in props) {\n createPropertyFromConfig(this.prototype, p, props[p], props);\n }\n }\n\n /**\n * Creates observers for the given `observers` array.\n * Leverages `PropertyEffects` to create observers.\n * @param {Object} observers Array of observer descriptors for\n * this class\n * @param {Object} dynamicFns Object containing keys for any properties\n * that are functions and should trigger the effect when the function\n * reference is changed\n * @return {void}\n * @protected\n */\n static createObservers(observers, dynamicFns) {\n const proto = this.prototype;\n for (let i=0; i < observers.length; i++) {\n proto._createMethodObserver(observers[i], dynamicFns);\n }\n }\n\n /**\n * Returns the template that will be stamped into this element's shadow root.\n *\n * If a `static get is()` getter is defined, the default implementation\n * will return the first `` in a `dom-module` whose `id`\n * matches this element's `is`.\n *\n * Users may override this getter to return an arbitrary template\n * (in which case the `is` getter is unnecessary). The template returned\n * must be an `HTMLTemplateElement`.\n *\n * Note that when subclassing, if the super class overrode the default\n * implementation and the subclass would like to provide an alternate\n * template via a `dom-module`, it should override this getter and\n * return `DomModule.import(this.is, 'template')`.\n *\n * If a subclass would like to modify the super class template, it should\n * clone it rather than modify it in place. If the getter does expensive\n * work such as cloning/modifying a template, it should memoize the\n * template for maximum performance:\n *\n * let memoizedTemplate;\n * class MySubClass extends MySuperClass {\n * static get template() {\n * if (!memoizedTemplate) {\n * memoizedTemplate = super.template.cloneNode(true);\n * let subContent = document.createElement('div');\n * subContent.textContent = 'This came from MySubClass';\n * memoizedTemplate.content.appendChild(subContent);\n * }\n * return memoizedTemplate;\n * }\n * }\n *\n * @return {!HTMLTemplateElement|string} Template to be stamped\n */\n static get template() {\n // Explanation of template-related properties:\n // - constructor.template (this getter): the template for the class.\n // This can come from the prototype (for legacy elements), from a\n // dom-module, or from the super class's template (or can be overridden\n // altogether by the user)\n // - constructor._template: memoized version of constructor.template\n // - prototype._template: working template for the element, which will be\n // parsed and modified in place. It is a cloned version of\n // constructor.template, saved in _finalizeClass(). Note that before\n // this getter is called, for legacy elements this could be from a\n // _template field on the info object passed to Polymer(), a behavior,\n // or set in registered(); once the static getter runs, a clone of it\n // will overwrite it on the prototype as the working template.\n if (!this.hasOwnProperty(JSCompiler_renameProperty('_template', this))) {\n this._template =\n // If user has put template on prototype (e.g. in legacy via registered\n // callback or info object), prefer that first\n this.prototype.hasOwnProperty(JSCompiler_renameProperty('_template', this.prototype)) ?\n this.prototype._template :\n // Look in dom-module associated with this element's is\n (getTemplateFromDomModule(/** @type {PolymerElementConstructor}*/ (this).is) ||\n // Next look for superclass template (call the super impl this\n // way so that `this` points to the superclass)\n Object.getPrototypeOf(/** @type {PolymerElementConstructor}*/ (this).prototype).constructor.template);\n }\n return this._template;\n }\n\n /**\n * Set the template.\n *\n * @param {!HTMLTemplateElement|string} value Template to set.\n */\n static set template(value) {\n this._template = value;\n }\n\n /**\n * Path matching the url from which the element was imported.\n *\n * This path is used to resolve url's in template style cssText.\n * The `importPath` property is also set on element instances and can be\n * used to create bindings relative to the import path.\n *\n * For elements defined in ES modules, users should implement\n * `static get importMeta() { return import.meta; }`, and the default\n * implementation of `importPath` will return `import.meta.url`'s path.\n * For elements defined in HTML imports, this getter will return the path\n * to the document containing a `dom-module` element matching this\n * element's static `is` property.\n *\n * Note, this path should contain a trailing `/`.\n *\n * @return {string} The import path for this element class\n * @suppress {missingProperties}\n */\n static get importPath() {\n if (!this.hasOwnProperty(JSCompiler_renameProperty('_importPath', this))) {\n const meta = this.importMeta;\n if (meta) {\n this._importPath = pathFromUrl(meta.url);\n } else {\n const module = DomModule.import(/** @type {PolymerElementConstructor} */ (this).is);\n this._importPath = (module && module.assetpath) ||\n Object.getPrototypeOf(/** @type {PolymerElementConstructor}*/ (this).prototype).constructor.importPath;\n }\n }\n return this._importPath;\n }\n\n constructor() {\n super();\n /** @type {HTMLTemplateElement} */\n this._template;\n /** @type {string} */\n this._importPath;\n /** @type {string} */\n this.rootPath;\n /** @type {string} */\n this.importPath;\n /** @type {StampedTemplate | HTMLElement | ShadowRoot} */\n this.root;\n /** @type {!Object} */\n this.$;\n }\n\n /**\n * Overrides the default `PropertyAccessors` to ensure class\n * metaprogramming related to property accessors and effects has\n * completed (calls `finalize`).\n *\n * It also initializes any property defaults provided via `value` in\n * `properties` metadata.\n *\n * @return {void}\n * @override\n * @suppress {invalidCasts}\n */\n _initializeProperties() {\n instanceCount++;\n this.constructor.finalize();\n // note: finalize template when we have access to `localName` to\n // avoid dependence on `is` for polyfilling styling.\n this.constructor._finalizeTemplate(/** @type {!HTMLElement} */(this).localName);\n super._initializeProperties();\n // set path defaults\n this.rootPath = rootPath;\n this.importPath = this.constructor.importPath;\n // apply property defaults...\n let p$ = propertyDefaults(this.constructor);\n if (!p$) {\n return;\n }\n for (let p in p$) {\n let info = p$[p];\n // Don't set default value if there is already an own property, which\n // happens when a `properties` property with default but no effects had\n // a property set (e.g. bound) by its host before upgrade\n if (!this.hasOwnProperty(p)) {\n let value = typeof info.value == 'function' ?\n info.value.call(this) :\n info.value;\n // Set via `_setProperty` if there is an accessor, to enable\n // initializing readOnly property defaults\n if (this._hasAccessor(p)) {\n this._setPendingProperty(p, value, true);\n } else {\n this[p] = value;\n }\n }\n }\n }\n\n /**\n * Gather style text for a style element in the template.\n *\n * @param {string} cssText Text containing styling to process\n * @param {string} baseURI Base URI to rebase CSS paths against\n * @return {string} The processed CSS text\n * @protected\n */\n static _processStyleText(cssText, baseURI) {\n return resolveCss(cssText, baseURI);\n }\n\n /**\n * Configures an element `proto` to function with a given `template`.\n * The element name `is` and extends `ext` must be specified for ShadyCSS\n * style scoping.\n *\n * @param {string} is Tag name (or type extension name) for this element\n * @return {void}\n * @protected\n */\n static _finalizeTemplate(is) {\n /** @const {HTMLTemplateElement} */\n const template = this.prototype._template;\n if (template && !template.__polymerFinalized) {\n template.__polymerFinalized = true;\n const importPath = this.importPath;\n const baseURI = importPath ? resolveUrl(importPath) : '';\n // e.g. support `include=\"module-name\"`, and ShadyCSS\n processElementStyles(this, template, is, baseURI);\n this.prototype._bindTemplate(template);\n }\n }\n\n /**\n * Provides a default implementation of the standard Custom Elements\n * `connectedCallback`.\n *\n * The default implementation enables the property effects system and\n * flushes any pending properties, and updates shimmed CSS properties\n * when using the ShadyCSS scoping/custom properties polyfill.\n *\n * @suppress {missingProperties, invalidCasts} Super may or may not implement the callback\n * @return {void}\n */\n connectedCallback() {\n if (window.ShadyCSS && this._template) {\n window.ShadyCSS.styleElement(/** @type {!HTMLElement} */(this));\n }\n super.connectedCallback();\n }\n\n /**\n * Stamps the element template.\n *\n * @return {void}\n * @override\n */\n ready() {\n if (this._template) {\n this.root = this._stampTemplate(this._template);\n this.$ = this.root.$;\n }\n super.ready();\n }\n\n /**\n * Implements `PropertyEffects`'s `_readyClients` call. Attaches\n * element dom by calling `_attachDom` with the dom stamped from the\n * element's template via `_stampTemplate`. Note that this allows\n * client dom to be attached to the element prior to any observers\n * running.\n *\n * @return {void}\n * @override\n */\n _readyClients() {\n if (this._template) {\n this.root = this._attachDom(/** @type {StampedTemplate} */(this.root));\n }\n // The super._readyClients here sets the clients initialized flag.\n // We must wait to do this until after client dom is created/attached\n // so that this flag can be checked to prevent notifications fired\n // during this process from being handled before clients are ready.\n super._readyClients();\n }\n\n\n /**\n * Attaches an element's stamped dom to itself. By default,\n * this method creates a `shadowRoot` and adds the dom to it.\n * However, this method may be overridden to allow an element\n * to put its dom in another location.\n *\n * @throws {Error}\n * @suppress {missingReturn}\n * @param {StampedTemplate} dom to attach to the element.\n * @return {ShadowRoot} node to which the dom has been attached.\n */\n _attachDom(dom) {\n if (this.attachShadow) {\n if (dom) {\n if (!this.shadowRoot) {\n this.attachShadow({mode: 'open'});\n }\n this.shadowRoot.appendChild(dom);\n return this.shadowRoot;\n }\n return null;\n } else {\n throw new Error('ShadowDOM not available. ' +\n // TODO(sorvell): move to compile-time conditional when supported\n 'PolymerElement can create dom as children instead of in ' +\n 'ShadowDOM by setting `this.root = this;\\` before \\`ready\\`.');\n }\n }\n\n /**\n * When using the ShadyCSS scoping and custom property shim, causes all\n * shimmed styles in this element (and its subtree) to be updated\n * based on current custom property values.\n *\n * The optional parameter overrides inline custom property styles with an\n * object of properties where the keys are CSS properties, and the values\n * are strings.\n *\n * Example: `this.updateStyles({'--color': 'blue'})`\n *\n * These properties are retained unless a value of `null` is set.\n *\n * Note: This function does not support updating CSS mixins.\n * You can not dynamically change the value of an `@apply`.\n *\n * @param {Object=} properties Bag of custom property key/values to\n * apply to this element.\n * @return {void}\n * @suppress {invalidCasts}\n */\n updateStyles(properties) {\n if (window.ShadyCSS) {\n window.ShadyCSS.styleSubtree(/** @type {!HTMLElement} */(this), properties);\n }\n }\n\n /**\n * Rewrites a given URL relative to a base URL. The base URL defaults to\n * the original location of the document containing the `dom-module` for\n * this element. This method will return the same URL before and after\n * bundling.\n *\n * Note that this function performs no resolution for URLs that start\n * with `/` (absolute URLs) or `#` (hash identifiers). For general purpose\n * URL resolution, use `window.URL`.\n *\n * @param {string} url URL to resolve.\n * @param {string=} base Optional base URL to resolve against, defaults\n * to the element's `importPath`\n * @return {string} Rewritten URL relative to base\n */\n resolveUrl(url, base) {\n if (!base && this.importPath) {\n base = resolveUrl(this.importPath);\n }\n return resolveUrl(url, base);\n }\n\n /**\n * Overrides `PropertyAccessors` to add map of dynamic functions on\n * template info, for consumption by `PropertyEffects` template binding\n * code. This map determines which method templates should have accessors\n * created for them.\n *\n * @override\n * @suppress {missingProperties} Interfaces in closure do not inherit statics, but classes do\n */\n static _parseTemplateContent(template, templateInfo, nodeInfo) {\n templateInfo.dynamicFns = templateInfo.dynamicFns || this._properties;\n return super._parseTemplateContent(template, templateInfo, nodeInfo);\n }\n\n }\n\n return PolymerElement;\n});\n\n/**\n * Total number of Polymer element instances created.\n * @type {number}\n */\nexport let instanceCount = 0;\n\n/**\n * Array of Polymer element classes that have been finalized.\n * @type {Array}\n */\nexport const registrations = [];\n\n/**\n * @param {!PolymerElementConstructor} prototype Element prototype to log\n * @this {this}\n * @private\n */\nfunction _regLog(prototype) {\n console.log('[' + prototype.is + ']: registered');\n}\n\n/**\n * Registers a class prototype for telemetry purposes.\n * @param {HTMLElement} prototype Element prototype to register\n * @this {this}\n * @protected\n */\nexport function register(prototype) {\n registrations.push(prototype);\n}\n\n/**\n * Logs all elements registered with an `is` to the console.\n * @public\n * @this {this}\n */\nexport function dumpRegistrations() {\n registrations.forEach(_regLog);\n}\n\n/**\n * When using the ShadyCSS scoping and custom property shim, causes all\n * shimmed `styles` (via `custom-style`) in the document (and its subtree)\n * to be updated based on current custom property values.\n *\n * The optional parameter overrides inline custom property styles with an\n * object of properties where the keys are CSS properties, and the values\n * are strings.\n *\n * Example: `updateStyles({'--color': 'blue'})`\n *\n * These properties are retained unless a value of `null` is set.\n *\n * @param {Object=} props Bag of custom property key/values to\n * apply to the document.\n * @return {void}\n */\nexport const updateStyles = function(props) {\n if (window.ShadyCSS) {\n window.ShadyCSS.styleDocument(props);\n }\n};\n","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\n\nimport {IronMeta} from '@polymer/iron-meta/iron-meta.js';\nimport {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';\nimport {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';\n/**\n * The `iron-iconset-svg` element allows users to define their own icon sets\n * that contain svg icons. The svg icon elements should be children of the\n * `iron-iconset-svg` element. Multiple icons should be given distinct id's.\n *\n * Using svg elements to create icons has a few advantages over traditional\n * bitmap graphics like jpg or png. Icons that use svg are vector based so\n * they are resolution independent and should look good on any device. They\n * are stylable via css. Icons can be themed, colorized, and even animated.\n *\n * Example:\n *\n * \n * \n * \n *\n * This will automatically register the icon set \"my-svg-icons\" to the iconset\n * database. To use these icons from within another element, make a\n * `iron-iconset` element and call the `byId` method\n * to retrieve a given iconset. To apply a particular icon inside an\n * element use the `applyIcon` method. For example:\n *\n * iconset.applyIcon(iconNode, 'car');\n *\n * @element iron-iconset-svg\n * @demo demo/index.html\n * @implements {Polymer.Iconset}\n */\nPolymer({\n is: 'iron-iconset-svg',\n\n properties: {\n\n /**\n * The name of the iconset.\n */\n name: {type: String, observer: '_nameChanged'},\n\n /**\n * The size of an individual icon. Note that icons must be square.\n */\n size: {type: Number, value: 24},\n\n /**\n * Set to true to enable mirroring of icons where specified when they are\n * stamped. Icons that should be mirrored should be decorated with a\n * `mirror-in-rtl` attribute.\n *\n * NOTE: For performance reasons, direction will be resolved once per\n * document per iconset, so moving icons in and out of RTL subtrees will\n * not cause their mirrored state to change.\n */\n rtlMirroring: {type: Boolean, value: false},\n\n /**\n * Set to true to measure RTL based on the dir attribute on the body or\n * html elements (measured on document.body or document.documentElement as\n * available).\n */\n useGlobalRtlAttribute: {type: Boolean, value: false}\n },\n\n created: function() {\n this._meta = new IronMeta({type: 'iconset', key: null, value: null});\n },\n\n attached: function() {\n this.style.display = 'none';\n },\n\n /**\n * Construct an array of all icon names in this iconset.\n *\n * @return {!Array} Array of icon names.\n */\n getIconNames: function() {\n this._icons = this._createIconMap();\n return Object.keys(this._icons).map(function(n) {\n return this.name + ':' + n;\n }, this);\n },\n\n /**\n * Applies an icon to the given element.\n *\n * An svg icon is prepended to the element's shadowRoot if it exists,\n * otherwise to the element itself.\n *\n * If RTL mirroring is enabled, and the icon is marked to be mirrored in\n * RTL, the element will be tested (once and only once ever for each\n * iconset) to determine the direction of the subtree the element is in.\n * This direction will apply to all future icon applications, although only\n * icons marked to be mirrored will be affected.\n *\n * @method applyIcon\n * @param {Element} element Element to which the icon is applied.\n * @param {string} iconName Name of the icon to apply.\n * @return {?Element} The svg element which renders the icon.\n */\n applyIcon: function(element, iconName) {\n // Remove old svg element\n this.removeIcon(element);\n // install new svg element\n var svg = this._cloneIcon(\n iconName, this.rtlMirroring && this._targetIsRTL(element));\n if (svg) {\n // insert svg element into shadow root, if it exists\n var pde = dom(element.root || element);\n pde.insertBefore(svg, pde.childNodes[0]);\n return element._svgIcon = svg;\n }\n return null;\n },\n\n /**\n * Remove an icon from the given element by undoing the changes effected\n * by `applyIcon`.\n *\n * @param {Element} element The element from which the icon is removed.\n */\n removeIcon: function(element) {\n // Remove old svg element\n if (element._svgIcon) {\n dom(element.root || element).removeChild(element._svgIcon);\n element._svgIcon = null;\n }\n },\n\n /**\n * Measures and memoizes the direction of the element. Note that this\n * measurement is only done once and the result is memoized for future\n * invocations.\n */\n _targetIsRTL: function(target) {\n if (this.__targetIsRTL == null) {\n if (this.useGlobalRtlAttribute) {\n var globalElement =\n (document.body && document.body.hasAttribute('dir')) ?\n document.body :\n document.documentElement;\n\n this.__targetIsRTL = globalElement.getAttribute('dir') === 'rtl';\n } else {\n if (target && target.nodeType !== Node.ELEMENT_NODE) {\n target = target.host;\n }\n\n this.__targetIsRTL =\n target && window.getComputedStyle(target)['direction'] === 'rtl';\n }\n }\n\n return this.__targetIsRTL;\n },\n\n /**\n *\n * When name is changed, register iconset metadata\n *\n */\n _nameChanged: function() {\n this._meta.value = null;\n this._meta.key = this.name;\n this._meta.value = this;\n\n this.async(function() {\n this.fire('iron-iconset-added', this, {node: window});\n });\n },\n\n /**\n * Create a map of child SVG elements by id.\n *\n * @return {!Object} Map of id's to SVG elements.\n */\n _createIconMap: function() {\n // Objects chained to Object.prototype (`{}`) have members. Specifically,\n // on FF there is a `watch` method that confuses the icon map, so we\n // need to use a null-based object here.\n var icons = Object.create(null);\n dom(this).querySelectorAll('[id]').forEach(function(icon) {\n icons[icon.id] = icon;\n });\n return icons;\n },\n\n /**\n * Produce installable clone of the SVG element matching `id` in this\n * iconset, or `undefined` if there is no matching element.\n *\n * @return {Element} Returns an installable clone of the SVG element\n * matching `id`.\n */\n _cloneIcon: function(id, mirrorAllowed) {\n // create the icon map on-demand, since the iconset itself has no discrete\n // signal to know when it's children are fully parsed\n this._icons = this._icons || this._createIconMap();\n return this._prepareSvgClone(this._icons[id], this.size, mirrorAllowed);\n },\n\n /**\n * @param {Element} sourceSvg\n * @param {number} size\n * @param {Boolean} mirrorAllowed\n * @return {Element}\n */\n _prepareSvgClone: function(sourceSvg, size, mirrorAllowed) {\n if (sourceSvg) {\n var content = sourceSvg.cloneNode(true),\n svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'),\n viewBox =\n content.getAttribute('viewBox') || '0 0 ' + size + ' ' + size,\n cssText =\n 'pointer-events: none; display: block; width: 100%; height: 100%;';\n\n if (mirrorAllowed && content.hasAttribute('mirror-in-rtl')) {\n cssText +=\n '-webkit-transform:scale(-1,1);transform:scale(-1,1);transform-origin:center;';\n }\n\n svg.setAttribute('viewBox', viewBox);\n svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');\n svg.setAttribute('focusable', 'false');\n // TODO(dfreedm): `pointer-events: none` works around\n // https://crbug.com/370136\n // TODO(sjmiles): inline style may not be ideal, but avoids requiring a\n // shadow-root\n svg.style.cssText = cssText;\n svg.appendChild(content).removeAttribute('id');\n return svg;\n }\n return null;\n }\n\n});\n","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\n'use strict';\n\nexport const nativeShadow = !(window['ShadyDOM'] && window['ShadyDOM']['inUse']);\nlet nativeCssVariables_;\n\n/**\n * @param {(ShadyCSSOptions | ShadyCSSInterface)=} settings\n */\nfunction calcCssVariables(settings) {\n if (settings && settings['shimcssproperties']) {\n nativeCssVariables_ = false;\n } else {\n // chrome 49 has semi-working css vars, check if box-shadow works\n // safari 9.1 has a recalc bug: https://bugs.webkit.org/show_bug.cgi?id=155782\n // However, shim css custom properties are only supported with ShadyDOM enabled,\n // so fall back on native if we do not detect ShadyDOM\n // Edge 15: custom properties used in ::before and ::after will also be used in the parent element\n // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12414257/\n nativeCssVariables_ = nativeShadow || Boolean(!navigator.userAgent.match(/AppleWebKit\\/601|Edge\\/15/) &&\n window.CSS && CSS.supports && CSS.supports('box-shadow', '0 0 0 var(--foo)'));\n }\n}\n\n/** @type {string | undefined} */\nexport let cssBuild;\nif (window.ShadyCSS && window.ShadyCSS.cssBuild !== undefined) {\n cssBuild = window.ShadyCSS.cssBuild;\n}\n\n/** @type {boolean} */\nexport const disableRuntime = Boolean(window.ShadyCSS && window.ShadyCSS.disableRuntime);\n\nif (window.ShadyCSS && window.ShadyCSS.nativeCss !== undefined) {\n nativeCssVariables_ = window.ShadyCSS.nativeCss;\n} else if (window.ShadyCSS) {\n calcCssVariables(window.ShadyCSS);\n // reset window variable to let ShadyCSS API take its place\n window.ShadyCSS = undefined;\n} else {\n calcCssVariables(window['WebComponents'] && window['WebComponents']['flags']);\n}\n\n// Hack for type error under new type inference which doesn't like that\n// nativeCssVariables is updated in a function and assigns the type\n// `function(): ?` instead of `boolean`.\nexport const nativeCssVariables = /** @type {boolean} */(nativeCssVariables_);","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\nexport const VAR_ASSIGN = /(?:^|[;\\s{]\\s*)(--[\\w-]*?)\\s*:\\s*(?:((?:'(?:\\\\'|.)*?'|\"(?:\\\\\"|.)*?\"|\\([^)]*?\\)|[^};{])+)|\\{([^}]*)\\}(?:(?=[;\\s}])|$))/gi;\nexport const MIXIN_MATCH = /(?:^|\\W+)@apply\\s*\\(?([^);\\n]*)\\)?/gi;\nexport const VAR_CONSUMED = /(--[\\w-]+)\\s*([:,;)]|$)/gi;\nexport const ANIMATION_MATCH = /(animation\\s*:)|(animation-name\\s*:)/;\nexport const MEDIA_MATCH = /@media\\s(.*)/;\nexport const IS_VAR = /^--/;\nexport const BRACKETED = /\\{[^}]*\\}/g;\nexport const HOST_PREFIX = '(?:^|[^.#[:])';\nexport const HOST_SUFFIX = '($|[.:[\\\\s>+~])';\n","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\n'use strict';\n\nimport { MIXIN_MATCH, VAR_ASSIGN } from './common-regex.js';\n\n/**\n * @param {Element} element\n * @param {Object=} properties\n */\nexport function updateNativeProperties(element, properties) {\n // remove previous properties\n for (let p in properties) {\n // NOTE: for bc with shim, don't apply null values.\n if (p === null) {\n element.style.removeProperty(p);\n } else {\n element.style.setProperty(p, properties[p]);\n }\n }\n}\n\n/**\n * @param {Element} element\n * @param {string} property\n * @return {string}\n */\nexport function getComputedStyleValue(element, property) {\n /**\n * @const {string}\n */\n const value = window.getComputedStyle(element).getPropertyValue(property);\n if (!value) {\n return '';\n } else {\n return value.trim();\n }\n}\n\n/**\n * return true if `cssText` contains a mixin definition or consumption\n * @param {string} cssText\n * @return {boolean}\n */\nexport function detectMixin(cssText) {\n const has = MIXIN_MATCH.test(cssText) || VAR_ASSIGN.test(cssText);\n // reset state of the regexes\n MIXIN_MATCH.lastIndex = 0;\n VAR_ASSIGN.lastIndex = 0;\n return has;\n}\n","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\nimport '../utils/boot.js';\n\nimport { resolveUrl, pathFromUrl } from '../utils/resolve-url.js';\nimport { strictTemplatePolicy } from '../utils/settings.js';\n\nlet modules = {};\nlet lcModules = {};\n/**\n * Sets a dom-module into the global registry by id.\n *\n * @param {string} id dom-module id\n * @param {DomModule} module dom-module instance\n * @return {void}\n */\nfunction setModule(id, module) {\n // store id separate from lowercased id so that\n // in all cases mixedCase id will stored distinctly\n // and lowercase version is a fallback\n modules[id] = lcModules[id.toLowerCase()] = module;\n}\n/**\n * Retrieves a dom-module from the global registry by id.\n *\n * @param {string} id dom-module id\n * @return {DomModule!} dom-module instance\n */\nfunction findModule(id) {\n return modules[id] || lcModules[id.toLowerCase()];\n}\n\nfunction styleOutsideTemplateCheck(inst) {\n if (inst.querySelector('style')) {\n console.warn('dom-module %s has style outside template', inst.id);\n }\n}\n\n/**\n * The `dom-module` element registers the dom it contains to the name given\n * by the module's id attribute. It provides a unified database of dom\n * accessible via its static `import` API.\n *\n * A key use case of `dom-module` is for providing custom element ``s\n * via HTML imports that are parsed by the native HTML parser, that can be\n * relocated during a bundling pass and still looked up by `id`.\n *\n * Example:\n *\n * \n * \n * \n *\n * Then in code in some other location that cannot access the dom-module above\n *\n * let img = customElements.get('dom-module').import('foo', 'img');\n *\n * @customElement\n * @extends HTMLElement\n * @summary Custom element that provides a registry of relocatable DOM content\n * by `id` that is agnostic to bundling.\n * @unrestricted\n */\nexport class DomModule extends HTMLElement {\n\n static get observedAttributes() { return ['id']; }\n\n /**\n * Retrieves the element specified by the css `selector` in the module\n * registered by `id`. For example, this.import('foo', 'img');\n * @param {string} id The id of the dom-module in which to search.\n * @param {string=} selector The css selector by which to find the element.\n * @return {Element} Returns the element which matches `selector` in the\n * module registered at the specified `id`.\n *\n * @export\n * @nocollapse Referred to indirectly in style-gather.js\n */\n static import(id, selector) {\n if (id) {\n let m = findModule(id);\n if (m && selector) {\n return m.querySelector(selector);\n }\n return m;\n }\n return null;\n }\n\n /* eslint-disable no-unused-vars */\n /**\n * @param {string} name Name of attribute.\n * @param {?string} old Old value of attribute.\n * @param {?string} value Current value of attribute.\n * @param {?string} namespace Attribute namespace.\n * @return {void}\n * @override\n */\n attributeChangedCallback(name, old, value, namespace) {\n if (old !== value) {\n this.register();\n }\n }\n /* eslint-enable no-unused-args */\n\n /**\n * The absolute URL of the original location of this `dom-module`.\n *\n * This value will differ from this element's `ownerDocument` in the\n * following ways:\n * - Takes into account any `assetpath` attribute added during bundling\n * to indicate the original location relative to the bundled location\n * - Uses the HTMLImports polyfill's `importForElement` API to ensure\n * the path is relative to the import document's location since\n * `ownerDocument` is not currently polyfilled\n */\n get assetpath() {\n // Don't override existing assetpath.\n if (!this.__assetpath) {\n // note: assetpath set via an attribute must be relative to this\n // element's location; accomodate polyfilled HTMLImports\n const owner = window.HTMLImports && HTMLImports.importForElement ?\n HTMLImports.importForElement(this) || document : this.ownerDocument;\n const url = resolveUrl(\n this.getAttribute('assetpath') || '', owner.baseURI);\n this.__assetpath = pathFromUrl(url);\n }\n return this.__assetpath;\n }\n\n /**\n * Registers the dom-module at a given id. This method should only be called\n * when a dom-module is imperatively created. For\n * example, `document.createElement('dom-module').register('foo')`.\n * @param {string=} id The id at which to register the dom-module.\n * @return {void}\n */\n register(id) {\n id = id || this.id;\n if (id) {\n // Under strictTemplatePolicy, reject and null out any re-registered\n // dom-module since it is ambiguous whether first-in or last-in is trusted\n if (strictTemplatePolicy && findModule(id) !== undefined) {\n setModule(id, null);\n throw new Error(`strictTemplatePolicy: dom-module ${id} re-registered`);\n }\n this.id = id;\n setModule(id, this);\n styleOutsideTemplateCheck(this);\n }\n }\n}\n\nDomModule.prototype['modules'] = modules;\n\ncustomElements.define('dom-module', DomModule);\n","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\nimport { LegacyElementMixin } from './legacy-element-mixin.js';\n\nlet metaProps = {\n attached: true,\n detached: true,\n ready: true,\n created: true,\n beforeRegister: true,\n registered: true,\n attributeChanged: true,\n // meta objects\n behaviors: true\n};\n\n/**\n * Applies a \"legacy\" behavior or array of behaviors to the provided class.\n *\n * Note: this method will automatically also apply the `LegacyElementMixin`\n * to ensure that any legacy behaviors can rely on legacy Polymer API on\n * the underlying element.\n *\n * @function\n * @template T\n * @param {!Object|!Array} behaviors Behavior object or array of behaviors.\n * @param {function(new:T)} klass Element class.\n * @return {?} Returns a new Element class extended by the\n * passed in `behaviors` and also by `LegacyElementMixin`.\n * @suppress {invalidCasts, checkTypes}\n */\nexport function mixinBehaviors(behaviors, klass) {\n if (!behaviors) {\n klass = /** @type {HTMLElement} */(klass); // eslint-disable-line no-self-assign\n return klass;\n }\n // NOTE: ensure the behavior is extending a class with\n // legacy element api. This is necessary since behaviors expect to be able\n // to access 1.x legacy api.\n klass = LegacyElementMixin(klass);\n if (!Array.isArray(behaviors)) {\n behaviors = [behaviors];\n }\n let superBehaviors = klass.prototype.behaviors;\n // get flattened, deduped list of behaviors *not* already on super class\n behaviors = flattenBehaviors(behaviors, null, superBehaviors);\n // mixin new behaviors\n klass = _mixinBehaviors(behaviors, klass);\n if (superBehaviors) {\n behaviors = superBehaviors.concat(behaviors);\n }\n // Set behaviors on prototype for BC...\n klass.prototype.behaviors = behaviors;\n return klass;\n}\n\n// NOTE:\n// 1.x\n// Behaviors were mixed in *in reverse order* and de-duped on the fly.\n// The rule was that behavior properties were copied onto the element\n// prototype if and only if the property did not already exist.\n// Given: Polymer{ behaviors: [A, B, C, A, B]}, property copy order was:\n// (1), B, (2), A, (3) C. This means prototype properties win over\n// B properties win over A win over C. This mirrors what would happen\n// with inheritance if element extended B extended A extended C.\n//\n// Again given, Polymer{ behaviors: [A, B, C, A, B]}, the resulting\n// `behaviors` array was [C, A, B].\n// Behavior lifecycle methods were called in behavior array order\n// followed by the element, e.g. (1) C.created, (2) A.created,\n// (3) B.created, (4) element.created. There was no support for\n// super, and \"super-behavior\" methods were callable only by name).\n//\n// 2.x\n// Behaviors are made into proper mixins which live in the\n// element's prototype chain. Behaviors are placed in the element prototype\n// eldest to youngest and de-duped youngest to oldest:\n// So, first [A, B, C, A, B] becomes [C, A, B] then,\n// the element prototype becomes (oldest) (1) PolymerElement, (2) class(C),\n// (3) class(A), (4) class(B), (5) class(Polymer({...})).\n// Result:\n// This means element properties win over B properties win over A win\n// over C. (same as 1.x)\n// If lifecycle is called (super then me), order is\n// (1) C.created, (2) A.created, (3) B.created, (4) element.created\n// (again same as 1.x)\nfunction _mixinBehaviors(behaviors, klass) {\n for (let i=0; i= 0; i--) {\n let b = behaviors[i];\n if (b) {\n if (Array.isArray(b)) {\n flattenBehaviors(b, list);\n } else {\n // dedup\n if (list.indexOf(b) < 0 && (!exclude || exclude.indexOf(b) < 0)) {\n list.unshift(b);\n }\n }\n } else {\n console.warn('behavior is null, check for missing or 404 import');\n }\n }\n return list;\n}\n\n/**\n * @param {!PolymerInit} info Polymer info object\n * @param {function(new:HTMLElement)} Base base class to extend with info object\n * @return {function(new:HTMLElement)} Generated class\n * @suppress {checkTypes}\n * @private\n */\nfunction GenerateClassFromInfo(info, Base) {\n\n /** @private */\n class PolymerGenerated extends Base {\n\n static get properties() {\n return info.properties;\n }\n\n static get observers() {\n return info.observers;\n }\n\n /**\n * @return {void}\n */\n created() {\n super.created();\n if (info.created) {\n info.created.call(this);\n }\n }\n\n /**\n * @return {void}\n */\n _registered() {\n super._registered();\n /* NOTE: `beforeRegister` is called here for bc, but the behavior\n is different than in 1.x. In 1.0, the method was called *after*\n mixing prototypes together but *before* processing of meta-objects.\n However, dynamic effects can still be set here and can be done either\n in `beforeRegister` or `registered`. It is no longer possible to set\n `is` in `beforeRegister` as you could in 1.x.\n */\n if (info.beforeRegister) {\n info.beforeRegister.call(Object.getPrototypeOf(this));\n }\n if (info.registered) {\n info.registered.call(Object.getPrototypeOf(this));\n }\n }\n\n /**\n * @return {void}\n */\n _applyListeners() {\n super._applyListeners();\n if (info.listeners) {\n for (let l in info.listeners) {\n this._addMethodEventListenerToNode(this, l, info.listeners[l]);\n }\n }\n }\n\n // note: exception to \"super then me\" rule;\n // do work before calling super so that super attributes\n // only apply if not already set.\n /**\n * @return {void}\n */\n _ensureAttributes() {\n if (info.hostAttributes) {\n for (let a in info.hostAttributes) {\n this._ensureAttribute(a, info.hostAttributes[a]);\n }\n }\n super._ensureAttributes();\n }\n\n /**\n * @return {void}\n */\n ready() {\n super.ready();\n if (info.ready) {\n info.ready.call(this);\n }\n }\n\n /**\n * @return {void}\n */\n attached() {\n super.attached();\n if (info.attached) {\n info.attached.call(this);\n }\n }\n\n /**\n * @return {void}\n */\n detached() {\n super.detached();\n if (info.detached) {\n info.detached.call(this);\n }\n }\n\n /**\n * Implements native Custom Elements `attributeChangedCallback` to\n * set an attribute value to a property via `_attributeToProperty`.\n *\n * @param {string} name Name of attribute that changed\n * @param {?string} old Old attribute value\n * @param {?string} value New attribute value\n * @return {void}\n */\n attributeChanged(name, old, value) {\n super.attributeChanged(name, old, value);\n if (info.attributeChanged) {\n info.attributeChanged.call(this, name, old, value);\n }\n }\n }\n\n PolymerGenerated.generatedFrom = info;\n\n for (let p in info) {\n // NOTE: cannot copy `metaProps` methods onto prototype at least because\n // `super.ready` must be called and is not included in the user fn.\n if (!(p in metaProps)) {\n let pd = Object.getOwnPropertyDescriptor(info, p);\n if (pd) {\n Object.defineProperty(PolymerGenerated.prototype, p, pd);\n }\n }\n }\n\n return PolymerGenerated;\n}\n\n/**\n * Generates a class that extends `LegacyElement` based on the\n * provided info object. Metadata objects on the `info` object\n * (`properties`, `observers`, `listeners`, `behaviors`, `is`) are used\n * for Polymer's meta-programming systems, and any functions are copied\n * to the generated class.\n *\n * Valid \"metadata\" values are as follows:\n *\n * `is`: String providing the tag name to register the element under. In\n * addition, if a `dom-module` with the same id exists, the first template\n * in that `dom-module` will be stamped into the shadow root of this element,\n * with support for declarative event listeners (`on-...`), Polymer data\n * bindings (`[[...]]` and `{{...}}`), and id-based node finding into\n * `this.$`.\n *\n * `properties`: Object describing property-related metadata used by Polymer\n * features (key: property names, value: object containing property metadata).\n * Valid keys in per-property metadata include:\n * - `type` (String|Number|Object|Array|...): Used by\n * `attributeChangedCallback` to determine how string-based attributes\n * are deserialized to JavaScript property values.\n * - `notify` (boolean): Causes a change in the property to fire a\n * non-bubbling event called `-changed`. Elements that have\n * enabled two-way binding to the property use this event to observe changes.\n * - `readOnly` (boolean): Creates a getter for the property, but no setter.\n * To set a read-only property, use the private setter method\n * `_setProperty(property, value)`.\n * - `observer` (string): Observer method name that will be called when\n * the property changes. The arguments of the method are\n * `(value, previousValue)`.\n * - `computed` (string): String describing method and dependent properties\n * for computing the value of this property (e.g. `'computeFoo(bar, zot)'`).\n * Computed properties are read-only by default and can only be changed\n * via the return value of the computing method.\n *\n * `observers`: Array of strings describing multi-property observer methods\n * and their dependent properties (e.g. `'observeABC(a, b, c)'`).\n *\n * `listeners`: Object describing event listeners to be added to each\n * instance of this element (key: event name, value: method name).\n *\n * `behaviors`: Array of additional `info` objects containing metadata\n * and callbacks in the same format as the `info` object here which are\n * merged into this element.\n *\n * `hostAttributes`: Object listing attributes to be applied to the host\n * once created (key: attribute name, value: attribute value). Values\n * are serialized based on the type of the value. Host attributes should\n * generally be limited to attributes such as `tabIndex` and `aria-...`.\n * Attributes in `hostAttributes` are only applied if a user-supplied\n * attribute is not already present (attributes in markup override\n * `hostAttributes`).\n *\n * In addition, the following Polymer-specific callbacks may be provided:\n * - `registered`: called after first instance of this element,\n * - `created`: called during `constructor`\n * - `attached`: called during `connectedCallback`\n * - `detached`: called during `disconnectedCallback`\n * - `ready`: called before first `attached`, after all properties of\n * this element have been propagated to its template and all observers\n * have run\n *\n * @param {!PolymerInit} info Object containing Polymer metadata and functions\n * to become class methods.\n * @template T\n * @param {function(T):T} mixin Optional mixin to apply to legacy base class\n * before extending with Polymer metaprogramming.\n * @return {function(new:HTMLElement)} Generated class\n */\nexport const Class = function(info, mixin) {\n if (!info) {\n console.warn(`Polymer's Class function requires \\`info\\` argument`);\n }\n const baseWithBehaviors = info.behaviors ?\n // note: mixinBehaviors ensures `LegacyElementMixin`.\n mixinBehaviors(info.behaviors, HTMLElement) :\n LegacyElementMixin(HTMLElement);\n const baseWithMixin = mixin ? mixin(baseWithBehaviors) : baseWithBehaviors;\n const klass = GenerateClassFromInfo(info, baseWithMixin);\n // decorate klass with registration info\n klass.is = info.is;\n return klass;\n};\n","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\n\nimport {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';\n\nexport class IronMeta {\n /**\n * @param {{\n * type: (string|null|undefined),\n * key: (string|null|undefined),\n * value: *,\n * }=} options\n */\n constructor(options) {\n IronMeta[' '](options);\n\n /** @type {string} */\n this.type = (options && options.type) || 'default';\n /** @type {string|null|undefined} */\n this.key = options && options.key;\n if (options && 'value' in options) {\n /** @type {*} */\n this.value = options.value;\n }\n }\n\n /** @return {*} */\n get value() {\n var type = this.type;\n var key = this.key;\n\n if (type && key) {\n return IronMeta.types[type] && IronMeta.types[type][key];\n }\n }\n\n /** @param {*} value */\n set value(value) {\n var type = this.type;\n var key = this.key;\n\n if (type && key) {\n type = IronMeta.types[type] = IronMeta.types[type] || {};\n if (value == null) {\n delete type[key];\n } else {\n type[key] = value;\n }\n }\n }\n\n /** @return {!Array<*>} */\n get list() {\n var type = this.type;\n\n if (type) {\n var items = IronMeta.types[this.type];\n if (!items) {\n return [];\n }\n\n return Object.keys(items).map(function(key) {\n return metaDatas[this.type][key];\n }, this);\n }\n }\n\n /**\n * @param {string} key\n * @return {*}\n */\n byKey(key) {\n this.key = key;\n return this.value;\n }\n};\n\n// This function is used to convince Closure not to remove constructor calls\n// for instances that are not held anywhere. For example, when\n// `new IronMeta({...})` is used only for the side effect of adding a value.\nIronMeta[' '] = function() {};\n\nIronMeta.types = {};\n\nvar metaDatas = IronMeta.types;\n\n/**\n`iron-meta` is a generic element you can use for sharing information across the\nDOM tree. It uses [monostate pattern](http://c2.com/cgi/wiki?MonostatePattern)\nsuch that any instance of iron-meta has access to the shared information. You\ncan use `iron-meta` to share whatever you want (or create an extension [like\nx-meta] for enhancements).\n\nThe `iron-meta` instances containing your actual data can be loaded in an\nimport, or constructed in any way you see fit. The only requirement is that you\ncreate them before you try to access them.\n\nExamples:\n\nIf I create an instance like this:\n\n \n\nNote that value=\"foo/bar\" is the metadata I've defined. I could define more\nattributes or use child nodes to define additional metadata.\n\nNow I can access that element (and it's metadata) from any iron-meta instance\nvia the byKey method, e.g.\n\n meta.byKey('info');\n\nPure imperative form would be like:\n\n document.createElement('iron-meta').byKey('info');\n\nOr, in a Polymer element, you can include a meta in your template:\n\n \n ...\n this.$.meta.byKey('info');\n\n@group Iron Elements\n@demo demo/index.html\n@element iron-meta\n*/\nPolymer({\n\n is: 'iron-meta',\n\n properties: {\n\n /**\n * The type of meta-data. All meta-data of the same type is stored\n * together.\n * @type {string}\n */\n type: {\n type: String,\n value: 'default',\n },\n\n /**\n * The key used to store `value` under the `type` namespace.\n * @type {?string}\n */\n key: {\n type: String,\n },\n\n /**\n * The meta-data to store or retrieve.\n * @type {*}\n */\n value: {\n type: String,\n notify: true,\n },\n\n /**\n * If true, `value` is set to the iron-meta instance itself.\n */\n self: {type: Boolean, observer: '_selfChanged'},\n\n __meta: {type: Boolean, computed: '__computeMeta(type, key, value)'}\n },\n\n hostAttributes: {hidden: true},\n\n __computeMeta: function(type, key, value) {\n var meta = new IronMeta({type: type, key: key});\n\n if (value !== undefined && value !== meta.value) {\n meta.value = value;\n } else if (this.value !== meta.value) {\n this.value = meta.value;\n }\n\n return meta;\n },\n\n get list() {\n return this.__meta && this.__meta.list;\n },\n\n _selfChanged: function(self) {\n if (self) {\n this.value = this;\n }\n },\n\n /**\n * Retrieves meta data value by key.\n *\n * @method byKey\n * @param {string} key The key of the meta-data to be returned.\n * @return {*}\n */\n byKey: function(key) {\n return new IronMeta({type: this.type, key: key}).value;\n }\n});\n","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\nimport '../utils/boot.js';\n\nimport { dedupingMixin } from '../utils/mixin.js';\n\n// 1.x backwards-compatible auto-wrapper for template type extensions\n// This is a clear layering violation and gives favored-nation status to\n// dom-if and dom-repeat templates. This is a conceit we're choosing to keep\n// a.) to ease 1.x backwards-compatibility due to loss of `is`, and\n// b.) to maintain if/repeat capability in parser-constrained elements\n// (e.g. table, select) in lieu of native CE type extensions without\n// massive new invention in this space (e.g. directive system)\nconst templateExtensions = {\n 'dom-if': true,\n 'dom-repeat': true\n};\nfunction wrapTemplateExtension(node) {\n let is = node.getAttribute('is');\n if (is && templateExtensions[is]) {\n let t = node;\n t.removeAttribute('is');\n node = t.ownerDocument.createElement(is);\n t.parentNode.replaceChild(node, t);\n node.appendChild(t);\n while(t.attributes.length) {\n node.setAttribute(t.attributes[0].name, t.attributes[0].value);\n t.removeAttribute(t.attributes[0].name);\n }\n }\n return node;\n}\n\nfunction findTemplateNode(root, nodeInfo) {\n // recursively ascend tree until we hit root\n let parent = nodeInfo.parentInfo && findTemplateNode(root, nodeInfo.parentInfo);\n // unwind the stack, returning the indexed node at each level\n if (parent) {\n // note: marginally faster than indexing via childNodes\n // (http://jsperf.com/childnodes-lookup)\n for (let n=parent.firstChild, i=0; n; n=n.nextSibling) {\n if (nodeInfo.parentIndex === i++) {\n return n;\n }\n }\n } else {\n return root;\n }\n}\n\n// construct `$` map (from id annotations)\nfunction applyIdToMap(inst, map, node, nodeInfo) {\n if (nodeInfo.id) {\n map[nodeInfo.id] = node;\n }\n}\n\n// install event listeners (from event annotations)\nfunction applyEventListener(inst, node, nodeInfo) {\n if (nodeInfo.events && nodeInfo.events.length) {\n for (let j=0, e$=nodeInfo.events, e; (j {\n\n /**\n * @polymer\n * @mixinClass\n * @implements {Polymer_TemplateStamp}\n */\n class TemplateStamp extends superClass {\n\n /**\n * Scans a template to produce template metadata.\n *\n * Template-specific metadata are stored in the object returned, and node-\n * specific metadata are stored in objects in its flattened `nodeInfoList`\n * array. Only nodes in the template that were parsed as nodes of\n * interest contain an object in `nodeInfoList`. Each `nodeInfo` object\n * contains an `index` (`childNodes` index in parent) and optionally\n * `parent`, which points to node info of its parent (including its index).\n *\n * The template metadata object returned from this method has the following\n * structure (many fields optional):\n *\n * ```js\n * {\n * // Flattened list of node metadata (for nodes that generated metadata)\n * nodeInfoList: [\n * {\n * // `id` attribute for any nodes with id's for generating `$` map\n * id: {string},\n * // `on-event=\"handler\"` metadata\n * events: [\n * {\n * name: {string}, // event name\n * value: {string}, // handler method name\n * }, ...\n * ],\n * // Notes when the template contained a `` for shady DOM\n * // optimization purposes\n * hasInsertionPoint: {boolean},\n * // For nested ``` nodes, nested template metadata\n * templateInfo: {object}, // nested template metadata\n * // Metadata to allow efficient retrieval of instanced node\n * // corresponding to this metadata\n * parentInfo: {number}, // reference to parent nodeInfo>\n * parentIndex: {number}, // index in parent's `childNodes` collection\n * infoIndex: {number}, // index of this `nodeInfo` in `templateInfo.nodeInfoList`\n * },\n * ...\n * ],\n * // When true, the template had the `strip-whitespace` attribute\n * // or was nested in a template with that setting\n * stripWhitespace: {boolean},\n * // For nested templates, nested template content is moved into\n * // a document fragment stored here; this is an optimization to\n * // avoid the cost of nested template cloning\n * content: {DocumentFragment}\n * }\n * ```\n *\n * This method kicks off a recursive treewalk as follows:\n *\n * ```\n * _parseTemplate <---------------------+\n * _parseTemplateContent |\n * _parseTemplateNode <------------|--+\n * _parseTemplateNestedTemplate --+ |\n * _parseTemplateChildNodes ---------+\n * _parseTemplateNodeAttributes\n * _parseTemplateNodeAttribute\n *\n * ```\n *\n * These methods may be overridden to add custom metadata about templates\n * to either `templateInfo` or `nodeInfo`.\n *\n * Note that this method may be destructive to the template, in that\n * e.g. event annotations may be removed after being noted in the\n * template metadata.\n *\n * @param {!HTMLTemplateElement} template Template to parse\n * @param {TemplateInfo=} outerTemplateInfo Template metadata from the outer\n * template, for parsing nested templates\n * @return {!TemplateInfo} Parsed template metadata\n */\n static _parseTemplate(template, outerTemplateInfo) {\n // since a template may be re-used, memo-ize metadata\n if (!template._templateInfo) {\n let templateInfo = template._templateInfo = {};\n templateInfo.nodeInfoList = [];\n templateInfo.stripWhiteSpace =\n (outerTemplateInfo && outerTemplateInfo.stripWhiteSpace) ||\n template.hasAttribute('strip-whitespace');\n this._parseTemplateContent(template, templateInfo, {parent: null});\n }\n return template._templateInfo;\n }\n\n static _parseTemplateContent(template, templateInfo, nodeInfo) {\n return this._parseTemplateNode(template.content, templateInfo, nodeInfo);\n }\n\n /**\n * Parses template node and adds template and node metadata based on\n * the current node, and its `childNodes` and `attributes`.\n *\n * This method may be overridden to add custom node or template specific\n * metadata based on this node.\n *\n * @param {Node} node Node to parse\n * @param {!TemplateInfo} templateInfo Template metadata for current template\n * @param {!NodeInfo} nodeInfo Node metadata for current template.\n * @return {boolean} `true` if the visited node added node-specific\n * metadata to `nodeInfo`\n */\n static _parseTemplateNode(node, templateInfo, nodeInfo) {\n let noted;\n let element = /** @type {Element} */(node);\n if (element.localName == 'template' && !element.hasAttribute('preserve-content')) {\n noted = this._parseTemplateNestedTemplate(element, templateInfo, nodeInfo) || noted;\n } else if (element.localName === 'slot') {\n // For ShadyDom optimization, indicating there is an insertion point\n templateInfo.hasInsertionPoint = true;\n }\n if (element.firstChild) {\n noted = this._parseTemplateChildNodes(element, templateInfo, nodeInfo) || noted;\n }\n if (element.hasAttributes && element.hasAttributes()) {\n noted = this._parseTemplateNodeAttributes(element, templateInfo, nodeInfo) || noted;\n }\n return noted;\n }\n\n /**\n * Parses template child nodes for the given root node.\n *\n * This method also wraps whitelisted legacy template extensions\n * (`is=\"dom-if\"` and `is=\"dom-repeat\"`) with their equivalent element\n * wrappers, collapses text nodes, and strips whitespace from the template\n * if the `templateInfo.stripWhitespace` setting was provided.\n *\n * @param {Node} root Root node whose `childNodes` will be parsed\n * @param {!TemplateInfo} templateInfo Template metadata for current template\n * @param {!NodeInfo} nodeInfo Node metadata for current template.\n * @return {void}\n */\n static _parseTemplateChildNodes(root, templateInfo, nodeInfo) {\n if (root.localName === 'script' || root.localName === 'style') {\n return;\n }\n for (let node=root.firstChild, parentIndex=0, next; node; node=next) {\n // Wrap templates\n if (node.localName == 'template') {\n node = wrapTemplateExtension(node);\n }\n // collapse adjacent textNodes: fixes an IE issue that can cause\n // text nodes to be inexplicably split =(\n // note that root.normalize() should work but does not so we do this\n // manually.\n next = node.nextSibling;\n if (node.nodeType === Node.TEXT_NODE) {\n let /** Node */ n = next;\n while (n && (n.nodeType === Node.TEXT_NODE)) {\n node.textContent += n.textContent;\n next = n.nextSibling;\n root.removeChild(n);\n n = next;\n }\n // optionally strip whitespace\n if (templateInfo.stripWhiteSpace && !node.textContent.trim()) {\n root.removeChild(node);\n continue;\n }\n }\n let childInfo = { parentIndex, parentInfo: nodeInfo };\n if (this._parseTemplateNode(node, templateInfo, childInfo)) {\n childInfo.infoIndex = templateInfo.nodeInfoList.push(/** @type {!NodeInfo} */(childInfo)) - 1;\n }\n // Increment if not removed\n if (node.parentNode) {\n parentIndex++;\n }\n }\n }\n\n /**\n * Parses template content for the given nested ``.\n *\n * Nested template info is stored as `templateInfo` in the current node's\n * `nodeInfo`. `template.content` is removed and stored in `templateInfo`.\n * It will then be the responsibility of the host to set it back to the\n * template and for users stamping nested templates to use the\n * `_contentForTemplate` method to retrieve the content for this template\n * (an optimization to avoid the cost of cloning nested template content).\n *\n * @param {HTMLTemplateElement} node Node to parse (a )\n * @param {TemplateInfo} outerTemplateInfo Template metadata for current template\n * that includes the template `node`\n * @param {!NodeInfo} nodeInfo Node metadata for current template.\n * @return {boolean} `true` if the visited node added node-specific\n * metadata to `nodeInfo`\n */\n static _parseTemplateNestedTemplate(node, outerTemplateInfo, nodeInfo) {\n let templateInfo = this._parseTemplate(node, outerTemplateInfo);\n let content = templateInfo.content =\n node.content.ownerDocument.createDocumentFragment();\n content.appendChild(node.content);\n nodeInfo.templateInfo = templateInfo;\n return true;\n }\n\n /**\n * Parses template node attributes and adds node metadata to `nodeInfo`\n * for nodes of interest.\n *\n * @param {Element} node Node to parse\n * @param {TemplateInfo} templateInfo Template metadata for current template\n * @param {NodeInfo} nodeInfo Node metadata for current template.\n * @return {boolean} `true` if the visited node added node-specific\n * metadata to `nodeInfo`\n */\n static _parseTemplateNodeAttributes(node, templateInfo, nodeInfo) {\n // Make copy of original attribute list, since the order may change\n // as attributes are added and removed\n let noted = false;\n let attrs = Array.from(node.attributes);\n for (let i=attrs.length-1, a; (a=attrs[i]); i--) {\n noted = this._parseTemplateNodeAttribute(node, templateInfo, nodeInfo, a.name, a.value) || noted;\n }\n return noted;\n }\n\n /**\n * Parses a single template node attribute and adds node metadata to\n * `nodeInfo` for attributes of interest.\n *\n * This implementation adds metadata for `on-event=\"handler\"` attributes\n * and `id` attributes.\n *\n * @param {Element} node Node to parse\n * @param {!TemplateInfo} templateInfo Template metadata for current template\n * @param {!NodeInfo} nodeInfo Node metadata for current template.\n * @param {string} name Attribute name\n * @param {string} value Attribute value\n * @return {boolean} `true` if the visited node added node-specific\n * metadata to `nodeInfo`\n */\n static _parseTemplateNodeAttribute(node, templateInfo, nodeInfo, name, value) {\n // events (on-*)\n if (name.slice(0, 3) === 'on-') {\n node.removeAttribute(name);\n nodeInfo.events = nodeInfo.events || [];\n nodeInfo.events.push({\n name: name.slice(3),\n value\n });\n return true;\n }\n // static id\n else if (name === 'id') {\n nodeInfo.id = value;\n return true;\n }\n return false;\n }\n\n /**\n * Returns the `content` document fragment for a given template.\n *\n * For nested templates, Polymer performs an optimization to cache nested\n * template content to avoid the cost of cloning deeply nested templates.\n * This method retrieves the cached content for a given template.\n *\n * @param {HTMLTemplateElement} template Template to retrieve `content` for\n * @return {DocumentFragment} Content fragment\n */\n static _contentForTemplate(template) {\n let templateInfo = /** @type {HTMLTemplateElementWithInfo} */ (template)._templateInfo;\n return (templateInfo && templateInfo.content) || template.content;\n }\n\n /**\n * Clones the provided template content and returns a document fragment\n * containing the cloned dom.\n *\n * The template is parsed (once and memoized) using this library's\n * template parsing features, and provides the following value-added\n * features:\n * * Adds declarative event listeners for `on-event=\"handler\"` attributes\n * * Generates an \"id map\" for all nodes with id's under `$` on returned\n * document fragment\n * * Passes template info including `content` back to templates as\n * `_templateInfo` (a performance optimization to avoid deep template\n * cloning)\n *\n * Note that the memoized template parsing process is destructive to the\n * template: attributes for bindings and declarative event listeners are\n * removed after being noted in notes, and any nested `.content`\n * is removed and stored in notes as well.\n *\n * @param {!HTMLTemplateElement} template Template to stamp\n * @return {!StampedTemplate} Cloned template content\n * @override\n */\n _stampTemplate(template) {\n // Polyfill support: bootstrap the template if it has not already been\n if (template && !template.content &&\n window.HTMLTemplateElement && HTMLTemplateElement.decorate) {\n HTMLTemplateElement.decorate(template);\n }\n let templateInfo = this.constructor._parseTemplate(template);\n let nodeInfo = templateInfo.nodeInfoList;\n let content = templateInfo.content || template.content;\n let dom = /** @type {DocumentFragment} */ (document.importNode(content, true));\n // NOTE: ShadyDom optimization indicating there is an insertion point\n dom.__noInsertionPoint = !templateInfo.hasInsertionPoint;\n let nodes = dom.nodeList = new Array(nodeInfo.length);\n dom.$ = {};\n for (let i=0, l=nodeInfo.length, info; (i-changed')\n * @param {!PropertyEffectsType} inst Host element instance handling the notification event\n * @param {string} fromProp Child element property that was bound\n * @param {string} toPath Host property/path that was bound\n * @param {boolean} negate Whether the binding was negated\n * @return {void}\n * @private\n */\nfunction handleNotification(event, inst, fromProp, toPath, negate) {\n let value;\n let detail = /** @type {Object} */(event.detail);\n let fromPath = detail && detail.path;\n if (fromPath) {\n toPath = translate(fromProp, toPath, fromPath);\n value = detail && detail.value;\n } else {\n value = event.currentTarget[fromProp];\n }\n value = negate ? !value : value;\n if (!inst[TYPES.READ_ONLY] || !inst[TYPES.READ_ONLY][toPath]) {\n if (inst._setPendingPropertyOrPath(toPath, value, true, Boolean(fromPath))\n && (!detail || !detail.queueProperty)) {\n inst._invalidateProperties();\n }\n }\n}\n\n/**\n * Implements the \"reflect\" effect.\n *\n * Sets the attribute named `info.attrName` to the given property value.\n *\n * @param {!PropertyEffectsType} inst The instance the effect will be run on\n * @param {string} property Name of property\n * @param {Object} props Bag of current property changes\n * @param {Object} oldProps Bag of previous values for changed properties\n * @param {?} info Effect metadata\n * @return {void}\n * @private\n */\nfunction runReflectEffect(inst, property, props, oldProps, info) {\n let value = inst.__data[property];\n if (sanitizeDOMValue) {\n value = sanitizeDOMValue(value, info.attrName, 'attribute', /** @type {Node} */(inst));\n }\n inst._propertyToAttribute(property, info.attrName, value);\n}\n\n/**\n * Runs \"computed\" effects for a set of changed properties.\n *\n * This method differs from the generic `runEffects` method in that it\n * continues to run computed effects based on the output of each pass until\n * there are no more newly computed properties. This ensures that all\n * properties that will be computed by the initial set of changes are\n * computed before other effects (binding propagation, observers, and notify)\n * run.\n *\n * @param {!PropertyEffectsType} inst The instance the effect will be run on\n * @param {!Object} changedProps Bag of changed properties\n * @param {!Object} oldProps Bag of previous values for changed properties\n * @param {boolean} hasPaths True with `props` contains one or more paths\n * @return {void}\n * @private\n */\nfunction runComputedEffects(inst, changedProps, oldProps, hasPaths) {\n let computeEffects = inst[TYPES.COMPUTE];\n if (computeEffects) {\n let inputProps = changedProps;\n while (runEffects(inst, computeEffects, inputProps, oldProps, hasPaths)) {\n Object.assign(oldProps, inst.__dataOld);\n Object.assign(changedProps, inst.__dataPending);\n inputProps = inst.__dataPending;\n inst.__dataPending = null;\n }\n }\n}\n\n/**\n * Implements the \"computed property\" effect by running the method with the\n * values of the arguments specified in the `info` object and setting the\n * return value to the computed property specified.\n *\n * @param {!PropertyEffectsType} inst The instance the effect will be run on\n * @param {string} property Name of property\n * @param {Object} props Bag of current property changes\n * @param {Object} oldProps Bag of previous values for changed properties\n * @param {?} info Effect metadata\n * @return {void}\n * @private\n */\nfunction runComputedEffect(inst, property, props, oldProps, info) {\n let result = runMethodEffect(inst, property, props, oldProps, info);\n let computedProp = info.methodInfo;\n if (inst.__dataHasAccessor && inst.__dataHasAccessor[computedProp]) {\n inst._setPendingProperty(computedProp, result, true);\n } else {\n inst[computedProp] = result;\n }\n}\n\n/**\n * Computes path changes based on path links set up using the `linkPaths`\n * API.\n *\n * @param {!PropertyEffectsType} inst The instance whose props are changing\n * @param {string | !Array<(string|number)>} path Path that has changed\n * @param {*} value Value of changed path\n * @return {void}\n * @private\n */\nfunction computeLinkedPaths(inst, path, value) {\n let links = inst.__dataLinkedPaths;\n if (links) {\n let link;\n for (let a in links) {\n let b = links[a];\n if (isDescendant(a, path)) {\n link = translate(a, b, path);\n inst._setPendingPropertyOrPath(link, value, true, true);\n } else if (isDescendant(b, path)) {\n link = translate(b, a, path);\n inst._setPendingPropertyOrPath(link, value, true, true);\n }\n }\n }\n}\n\n// -- bindings ----------------------------------------------\n\n/**\n * Adds binding metadata to the current `nodeInfo`, and binding effects\n * for all part dependencies to `templateInfo`.\n *\n * @param {Function} constructor Class that `_parseTemplate` is currently\n * running on\n * @param {TemplateInfo} templateInfo Template metadata for current template\n * @param {NodeInfo} nodeInfo Node metadata for current template node\n * @param {string} kind Binding kind, either 'property', 'attribute', or 'text'\n * @param {string} target Target property name\n * @param {!Array} parts Array of binding part metadata\n * @param {string=} literal Literal text surrounding binding parts (specified\n * only for 'property' bindings, since these must be initialized as part\n * of boot-up)\n * @return {void}\n * @private\n */\nfunction addBinding(constructor, templateInfo, nodeInfo, kind, target, parts, literal) {\n // Create binding metadata and add to nodeInfo\n nodeInfo.bindings = nodeInfo.bindings || [];\n let /** Binding */ binding = { kind, target, parts, literal, isCompound: (parts.length !== 1) };\n nodeInfo.bindings.push(binding);\n // Add listener info to binding metadata\n if (shouldAddListener(binding)) {\n let {event, negate} = binding.parts[0];\n binding.listenerEvent = event || (camelToDashCase(target) + '-changed');\n binding.listenerNegate = negate;\n }\n // Add \"propagate\" property effects to templateInfo\n let index = templateInfo.nodeInfoList.length;\n for (let i=0; i part.source.length) &&\n (binding.kind == 'property') && !binding.isCompound &&\n node.__isPropertyEffectsClient &&\n node.__dataHasAccessor && node.__dataHasAccessor[binding.target]) {\n let value = props[path];\n path = translate(part.source, binding.target, path);\n if (node._setPendingPropertyOrPath(path, value, false, true)) {\n inst._enqueueClient(node);\n }\n } else {\n let value = info.evaluator._evaluateBinding(inst, part, path, props, oldProps, hasPaths);\n // Propagate value to child\n applyBindingValue(inst, node, binding, part, value);\n }\n}\n\n/**\n * Sets the value for an \"binding\" (binding) effect to a node,\n * either as a property or attribute.\n *\n * @param {!PropertyEffectsType} inst The instance owning the binding effect\n * @param {Node} node Target node for binding\n * @param {!Binding} binding Binding metadata\n * @param {!BindingPart} part Binding part metadata\n * @param {*} value Value to set\n * @return {void}\n * @private\n */\nfunction applyBindingValue(inst, node, binding, part, value) {\n value = computeBindingValue(node, value, binding, part);\n if (sanitizeDOMValue) {\n value = sanitizeDOMValue(value, binding.target, binding.kind, node);\n }\n if (binding.kind == 'attribute') {\n // Attribute binding\n inst._valueToNodeAttribute(/** @type {Element} */(node), value, binding.target);\n } else {\n // Property binding\n let prop = binding.target;\n if (node.__isPropertyEffectsClient &&\n node.__dataHasAccessor && node.__dataHasAccessor[prop]) {\n if (!node[TYPES.READ_ONLY] || !node[TYPES.READ_ONLY][prop]) {\n if (node._setPendingProperty(prop, value)) {\n inst._enqueueClient(node);\n }\n }\n } else {\n inst._setUnmanagedPropertyToNode(node, prop, value);\n }\n }\n}\n\n/**\n * Transforms an \"binding\" effect value based on compound & negation\n * effect metadata, as well as handling for special-case properties\n *\n * @param {Node} node Node the value will be set to\n * @param {*} value Value to set\n * @param {!Binding} binding Binding metadata\n * @param {!BindingPart} part Binding part metadata\n * @return {*} Transformed value to set\n * @private\n */\nfunction computeBindingValue(node, value, binding, part) {\n if (binding.isCompound) {\n let storage = node.__dataCompoundStorage[binding.target];\n storage[part.compoundIndex] = value;\n value = storage.join('');\n }\n if (binding.kind !== 'attribute') {\n // Some browsers serialize `undefined` to `\"undefined\"`\n if (binding.target === 'textContent' ||\n (binding.target === 'value' &&\n (node.localName === 'input' || node.localName === 'textarea'))) {\n value = value == undefined ? '' : value;\n }\n }\n return value;\n}\n\n/**\n * Returns true if a binding's metadata meets all the requirements to allow\n * 2-way binding, and therefore a `-changed` event listener should be\n * added:\n * - used curly braces\n * - is a property (not attribute) binding\n * - is not a textContent binding\n * - is not compound\n *\n * @param {!Binding} binding Binding metadata\n * @return {boolean} True if 2-way listener should be added\n * @private\n */\nfunction shouldAddListener(binding) {\n return Boolean(binding.target) &&\n binding.kind != 'attribute' &&\n binding.kind != 'text' &&\n !binding.isCompound &&\n binding.parts[0].mode === '{';\n}\n\n/**\n * Setup compound binding storage structures, notify listeners, and dataHost\n * references onto the bound nodeList.\n *\n * @param {!PropertyEffectsType} inst Instance that bas been previously bound\n * @param {TemplateInfo} templateInfo Template metadata\n * @return {void}\n * @private\n */\nfunction setupBindings(inst, templateInfo) {\n // Setup compound storage, dataHost, and notify listeners\n let {nodeList, nodeInfoList} = templateInfo;\n if (nodeInfoList.length) {\n for (let i=0; i < nodeInfoList.length; i++) {\n let info = nodeInfoList[i];\n let node = nodeList[i];\n let bindings = info.bindings;\n if (bindings) {\n for (let i=0; i} parts All parts to stringify\n * @return {string} String made from the literal parts\n */\nfunction literalFromParts(parts) {\n let s = '';\n for (let i=0; i} argList Array of argument names\n * @param {!MethodSignature} sig Method signature metadata object\n * @return {!MethodSignature} The updated signature metadata object\n * @private\n */\nfunction parseArgs(argList, sig) {\n sig.args = argList.map(function(rawArg) {\n let arg = parseArg(rawArg);\n if (!arg.literal) {\n sig.static = false;\n }\n return arg;\n }, this);\n return sig;\n}\n\n/**\n * Parses an individual argument, and returns an argument metadata object\n * with the following fields:\n *\n * {\n * value: 'prop', // property/path or literal value\n * literal: false, // whether argument is a literal\n * structured: false, // whether the property is a path\n * rootProperty: 'prop', // the root property of the path\n * wildcard: false // whether the argument was a wildcard '.*' path\n * }\n *\n * @param {string} rawArg The string value of the argument\n * @return {!MethodArg} Argument metadata object\n * @private\n */\nfunction parseArg(rawArg) {\n // clean up whitespace\n let arg = rawArg.trim()\n // replace comma entity with comma\n .replace(/,/g, ',')\n // repair extra escape sequences; note only commas strictly need\n // escaping, but we allow any other char to be escaped since its\n // likely users will do this\n .replace(/\\\\(.)/g, '\\$1')\n ;\n // basic argument descriptor\n let a = {\n name: arg,\n value: '',\n literal: false\n };\n // detect literal value (must be String or Number)\n let fc = arg[0];\n if (fc === '-') {\n fc = arg[1];\n }\n if (fc >= '0' && fc <= '9') {\n fc = '#';\n }\n switch(fc) {\n case \"'\":\n case '\"':\n a.value = arg.slice(1, -1);\n a.literal = true;\n break;\n case '#':\n a.value = Number(arg);\n a.literal = true;\n break;\n }\n // if not literal, look for structured path\n if (!a.literal) {\n a.rootProperty = root(arg);\n // detect structured path (has dots)\n a.structured = isPath(arg);\n if (a.structured) {\n a.wildcard = (arg.slice(-2) == '.*');\n if (a.wildcard) {\n a.name = arg.slice(0, -2);\n }\n }\n }\n return a;\n}\n\n// data api\n\n/**\n * Sends array splice notifications (`.splices` and `.length`)\n *\n * Note: this implementation only accepts normalized paths\n *\n * @param {!PropertyEffectsType} inst Instance to send notifications to\n * @param {Array} array The array the mutations occurred on\n * @param {string} path The path to the array that was mutated\n * @param {Array} splices Array of splice records\n * @return {void}\n * @private\n */\nfunction notifySplices(inst, array, path, splices) {\n let splicesPath = path + '.splices';\n inst.notifyPath(splicesPath, { indexSplices: splices });\n inst.notifyPath(path + '.length', array.length);\n // Null here to allow potentially large splice records to be GC'ed.\n inst.__data[splicesPath] = {indexSplices: null};\n}\n\n/**\n * Creates a splice record and sends an array splice notification for\n * the described mutation\n *\n * Note: this implementation only accepts normalized paths\n *\n * @param {!PropertyEffectsType} inst Instance to send notifications to\n * @param {Array} array The array the mutations occurred on\n * @param {string} path The path to the array that was mutated\n * @param {number} index Index at which the array mutation occurred\n * @param {number} addedCount Number of added items\n * @param {Array} removed Array of removed items\n * @return {void}\n * @private\n */\nfunction notifySplice(inst, array, path, index, addedCount, removed) {\n notifySplices(inst, array, path, [{\n index: index,\n addedCount: addedCount,\n removed: removed,\n object: array,\n type: 'splice'\n }]);\n}\n\n/**\n * Returns an upper-cased version of the string.\n *\n * @param {string} name String to uppercase\n * @return {string} Uppercased string\n * @private\n */\nfunction upper(name) {\n return name[0].toUpperCase() + name.substring(1);\n}\n\n/**\n * Element class mixin that provides meta-programming for Polymer's template\n * binding and data observation (collectively, \"property effects\") system.\n *\n * This mixin uses provides the following key static methods for adding\n * property effects to an element class:\n * - `addPropertyEffect`\n * - `createPropertyObserver`\n * - `createMethodObserver`\n * - `createNotifyingProperty`\n * - `createReadOnlyProperty`\n * - `createReflectedProperty`\n * - `createComputedProperty`\n * - `bindTemplate`\n *\n * Each method creates one or more property accessors, along with metadata\n * used by this mixin's implementation of `_propertiesChanged` to perform\n * the property effects.\n *\n * Underscored versions of the above methods also exist on the element\n * prototype for adding property effects on instances at runtime.\n *\n * Note that this mixin overrides several `PropertyAccessors` methods, in\n * many cases to maintain guarantees provided by the Polymer 1.x features;\n * notably it changes property accessors to be synchronous by default\n * whereas the default when using `PropertyAccessors` standalone is to be\n * async by default.\n *\n * @mixinFunction\n * @polymer\n * @appliesMixin TemplateStamp\n * @appliesMixin PropertyAccessors\n * @summary Element class mixin that provides meta-programming for Polymer's\n * template binding and data observation system.\n */\nexport const PropertyEffects = dedupingMixin(superClass => {\n\n /**\n * @constructor\n * @extends {superClass}\n * @implements {Polymer_PropertyAccessors}\n * @implements {Polymer_TemplateStamp}\n * @unrestricted\n * @private\n */\n const propertyEffectsBase = TemplateStamp(PropertyAccessors(superClass));\n\n /**\n * @polymer\n * @mixinClass\n * @implements {Polymer_PropertyEffects}\n * @extends {propertyEffectsBase}\n * @unrestricted\n */\n class PropertyEffects extends propertyEffectsBase {\n\n constructor() {\n super();\n /** @type {boolean} */\n // Used to identify users of this mixin, ala instanceof\n this.__isPropertyEffectsClient = true;\n /** @type {number} */\n // NOTE: used to track re-entrant calls to `_flushProperties`\n // path changes dirty check against `__dataTemp` only during one \"turn\"\n // and are cleared when `__dataCounter` returns to 0.\n this.__dataCounter = 0;\n /** @type {boolean} */\n this.__dataClientsReady;\n /** @type {Array} */\n this.__dataPendingClients;\n /** @type {Object} */\n this.__dataToNotify;\n /** @type {Object} */\n this.__dataLinkedPaths;\n /** @type {boolean} */\n this.__dataHasPaths;\n /** @type {Object} */\n this.__dataCompoundStorage;\n /** @type {Polymer_PropertyEffects} */\n this.__dataHost;\n /** @type {!Object} */\n this.__dataTemp;\n /** @type {boolean} */\n this.__dataClientsInitialized;\n /** @type {!Object} */\n this.__data;\n /** @type {!Object} */\n this.__dataPending;\n /** @type {!Object} */\n this.__dataOld;\n /** @type {Object} */\n this.__computeEffects;\n /** @type {Object} */\n this.__reflectEffects;\n /** @type {Object} */\n this.__notifyEffects;\n /** @type {Object} */\n this.__propagateEffects;\n /** @type {Object} */\n this.__observeEffects;\n /** @type {Object} */\n this.__readOnly;\n /** @type {!TemplateInfo} */\n this.__templateInfo;\n }\n\n get PROPERTY_EFFECT_TYPES() {\n return TYPES;\n }\n\n /**\n * @return {void}\n */\n _initializeProperties() {\n super._initializeProperties();\n hostStack.registerHost(this);\n this.__dataClientsReady = false;\n this.__dataPendingClients = null;\n this.__dataToNotify = null;\n this.__dataLinkedPaths = null;\n this.__dataHasPaths = false;\n // May be set on instance prior to upgrade\n this.__dataCompoundStorage = this.__dataCompoundStorage || null;\n this.__dataHost = this.__dataHost || null;\n this.__dataTemp = {};\n this.__dataClientsInitialized = false;\n }\n\n /**\n * Overrides `PropertyAccessors` implementation to provide a\n * more efficient implementation of initializing properties from\n * the prototype on the instance.\n *\n * @override\n * @param {Object} props Properties to initialize on the prototype\n * @return {void}\n */\n _initializeProtoProperties(props) {\n this.__data = Object.create(props);\n this.__dataPending = Object.create(props);\n this.__dataOld = {};\n }\n\n /**\n * Overrides `PropertyAccessors` implementation to avoid setting\n * `_setProperty`'s `shouldNotify: true`.\n *\n * @override\n * @param {Object} props Properties to initialize on the instance\n * @return {void}\n */\n _initializeInstanceProperties(props) {\n let readOnly = this[TYPES.READ_ONLY];\n for (let prop in props) {\n if (!readOnly || !readOnly[prop]) {\n this.__dataPending = this.__dataPending || {};\n this.__dataOld = this.__dataOld || {};\n this.__data[prop] = this.__dataPending[prop] = props[prop];\n }\n }\n }\n\n // Prototype setup ----------------------------------------\n\n /**\n * Equivalent to static `addPropertyEffect` API but can be called on\n * an instance to add effects at runtime. See that method for\n * full API docs.\n *\n * @param {string} property Property that should trigger the effect\n * @param {string} type Effect type, from this.PROPERTY_EFFECT_TYPES\n * @param {Object=} effect Effect metadata object\n * @return {void}\n * @protected\n */\n _addPropertyEffect(property, type, effect) {\n this._createPropertyAccessor(property, type == TYPES.READ_ONLY);\n // effects are accumulated into arrays per property based on type\n let effects = ensureOwnEffectMap(this, type)[property];\n if (!effects) {\n effects = this[type][property] = [];\n }\n effects.push(effect);\n }\n\n /**\n * Removes the given property effect.\n *\n * @param {string} property Property the effect was associated with\n * @param {string} type Effect type, from this.PROPERTY_EFFECT_TYPES\n * @param {Object=} effect Effect metadata object to remove\n * @return {void}\n */\n _removePropertyEffect(property, type, effect) {\n let effects = ensureOwnEffectMap(this, type)[property];\n let idx = effects.indexOf(effect);\n if (idx >= 0) {\n effects.splice(idx, 1);\n }\n }\n\n /**\n * Returns whether the current prototype/instance has a property effect\n * of a certain type.\n *\n * @param {string} property Property name\n * @param {string=} type Effect type, from this.PROPERTY_EFFECT_TYPES\n * @return {boolean} True if the prototype/instance has an effect of this type\n * @protected\n */\n _hasPropertyEffect(property, type) {\n let effects = this[type];\n return Boolean(effects && effects[property]);\n }\n\n /**\n * Returns whether the current prototype/instance has a \"read only\"\n * accessor for the given property.\n *\n * @param {string} property Property name\n * @return {boolean} True if the prototype/instance has an effect of this type\n * @protected\n */\n _hasReadOnlyEffect(property) {\n return this._hasPropertyEffect(property, TYPES.READ_ONLY);\n }\n\n /**\n * Returns whether the current prototype/instance has a \"notify\"\n * property effect for the given property.\n *\n * @param {string} property Property name\n * @return {boolean} True if the prototype/instance has an effect of this type\n * @protected\n */\n _hasNotifyEffect(property) {\n return this._hasPropertyEffect(property, TYPES.NOTIFY);\n }\n\n /**\n * Returns whether the current prototype/instance has a \"reflect to attribute\"\n * property effect for the given property.\n *\n * @param {string} property Property name\n * @return {boolean} True if the prototype/instance has an effect of this type\n * @protected\n */\n _hasReflectEffect(property) {\n return this._hasPropertyEffect(property, TYPES.REFLECT);\n }\n\n /**\n * Returns whether the current prototype/instance has a \"computed\"\n * property effect for the given property.\n *\n * @param {string} property Property name\n * @return {boolean} True if the prototype/instance has an effect of this type\n * @protected\n */\n _hasComputedEffect(property) {\n return this._hasPropertyEffect(property, TYPES.COMPUTE);\n }\n\n // Runtime ----------------------------------------\n\n /**\n * Sets a pending property or path. If the root property of the path in\n * question had no accessor, the path is set, otherwise it is enqueued\n * via `_setPendingProperty`.\n *\n * This function isolates relatively expensive functionality necessary\n * for the public API (`set`, `setProperties`, `notifyPath`, and property\n * change listeners via {{...}} bindings), such that it is only done\n * when paths enter the system, and not at every propagation step. It\n * also sets a `__dataHasPaths` flag on the instance which is used to\n * fast-path slower path-matching code in the property effects host paths.\n *\n * `path` can be a path string or array of path parts as accepted by the\n * public API.\n *\n * @param {string | !Array} path Path to set\n * @param {*} value Value to set\n * @param {boolean=} shouldNotify Set to true if this change should\n * cause a property notification event dispatch\n * @param {boolean=} isPathNotification If the path being set is a path\n * notification of an already changed value, as opposed to a request\n * to set and notify the change. In the latter `false` case, a dirty\n * check is performed and then the value is set to the path before\n * enqueuing the pending property change.\n * @return {boolean} Returns true if the property/path was enqueued in\n * the pending changes bag.\n * @protected\n */\n _setPendingPropertyOrPath(path, value, shouldNotify, isPathNotification) {\n if (isPathNotification ||\n root(Array.isArray(path) ? path[0] : path) !== path) {\n // Dirty check changes being set to a path against the actual object,\n // since this is the entry point for paths into the system; from here\n // the only dirty checks are against the `__dataTemp` cache to prevent\n // duplicate work in the same turn only. Note, if this was a notification\n // of a change already set to a path (isPathNotification: true),\n // we always let the change through and skip the `set` since it was\n // already dirty checked at the point of entry and the underlying\n // object has already been updated\n if (!isPathNotification) {\n let old = get(this, path);\n path = /** @type {string} */ (set(this, path, value));\n // Use property-accessor's simpler dirty check\n if (!path || !super._shouldPropertyChange(path, value, old)) {\n return false;\n }\n }\n this.__dataHasPaths = true;\n if (this._setPendingProperty(/**@type{string}*/(path), value, shouldNotify)) {\n computeLinkedPaths(this, path, value);\n return true;\n }\n } else {\n if (this.__dataHasAccessor && this.__dataHasAccessor[path]) {\n return this._setPendingProperty(/**@type{string}*/(path), value, shouldNotify);\n } else {\n this[path] = value;\n }\n }\n return false;\n }\n\n /**\n * Applies a value to a non-Polymer element/node's property.\n *\n * The implementation makes a best-effort at binding interop:\n * Some native element properties have side-effects when\n * re-setting the same value (e.g. setting `.value` resets the\n * cursor position), so we do a dirty-check before setting the value.\n * However, for better interop with non-Polymer custom elements that\n * accept objects, we explicitly re-set object changes coming from the\n * Polymer world (which may include deep object changes without the\n * top reference changing), erring on the side of providing more\n * information.\n *\n * Users may override this method to provide alternate approaches.\n *\n * @param {!Node} node The node to set a property on\n * @param {string} prop The property to set\n * @param {*} value The value to set\n * @return {void}\n * @protected\n */\n _setUnmanagedPropertyToNode(node, prop, value) {\n // It is a judgment call that resetting primitives is\n // \"bad\" and resettings objects is also \"good\"; alternatively we could\n // implement a whitelist of tag & property values that should never\n // be reset (e.g. .value &&