snapdrop

A Progressive Web App for local file sharing
git clone http://git.hanabi.in/repos/snapdrop.git
Log | Files | Refs | README | LICENSE

commit 0551df6c401aad6e6cbf6f697b37e43a00269890
parent dce88a309d7cd2fee3d90a15ff4ce73d3220dc2f
Author: RobinLinus <robin_woll@capira.de>
Date:   Wed,  8 Feb 2017 01:41:04 +0100

Commit a dist folder

Diffstat:
M.gitignore | 1-
Adist/index.js | 23+++++++++++++++++++++++
Adist/package.json | 14++++++++++++++
Adist/public/elements/elements.html | 22672+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adist/public/index.html | 18++++++++++++++++++
Adist/public/manifest.json | 29+++++++++++++++++++++++++++++
Adist/public/scripts/app.js | 2++
Adist/public/sounds/blop.mp3 | 0
Adist/public/sounds/blop.ogg | 0
Adist/public/styles/main.css | 2++
Adist/readme.md | 6++++++
Adist/server/ws-server.js | 154+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
12 files changed, 22920 insertions(+), 1 deletion(-)

diff --git a/.gitignore b/.gitignore @@ -1,5 +1,4 @@ node_modules -dist bower_components .tmp .publish/ diff --git a/dist/index.js b/dist/index.js @@ -0,0 +1,23 @@ +'use strict'; +var express = require('express'); +var compression = require('compression'); +var app = express(); +var http = require('http'); +var ExpressPeerServer = require('peer').ExpressPeerServer; +var wsServer = require('./server/ws-server.js'); + +var server = http.createServer(app); + +// Serve up content from public directory +app.use(compression()); +app.use(express.static(__dirname + '/public')); + +var port = process.env.PORT || 3002; +server.listen(port); +wsServer.create(server); +app.use('/peerjs', ExpressPeerServer(server, { + debug: true +})); + + +console.log('listening on port ' + port); diff --git a/dist/package.json b/dist/package.json @@ -0,0 +1,14 @@ +{ + "private": true, + "engines": { + "node": ">=0.10.0" + }, + "dependencies": { + "binaryjs": "^0.2.1", + "compression": "^1.6.0", + "express": "^4.13.3", + "peer": "^0.2.8", + "ua-parser-js": "^0.7.10", + "ws": "^1.1.1" + } +} diff --git a/dist/public/elements/elements.html b/dist/public/elements/elements.html @@ -0,0 +1,22671 @@ +<html><head> + +<meta charset=UTF-8><script>(function () { +function resolve() { +document.body.removeAttribute('unresolved'); +} +if (window.WebComponents) { +addEventListener('WebComponentsReady', resolve); +} else { +if (document.readyState === 'interactive' || document.readyState === 'complete') { +resolve(); +} else { +addEventListener('DOMContentLoaded', resolve); +} +} +}()); +window.Polymer = { +Settings: function () { +var user = window.Polymer || {}; +var parts = location.search.slice(1).split('&'); +for (var i = 0, o; i < parts.length && (o = parts[i]); i++) { +o = o.split('='); +o[0] && (user[o[0]] = o[1] || true); +} +var wantShadow = user.dom === 'shadow'; +var hasShadow = Boolean(Element.prototype.createShadowRoot); +var nativeShadow = hasShadow && !window.ShadowDOMPolyfill; +var useShadow = wantShadow && hasShadow; +var hasNativeImports = Boolean('import' in document.createElement('link')); +var useNativeImports = hasNativeImports; +var useNativeCustomElements = !window.CustomElements || window.CustomElements.useNative; +return { +wantShadow: wantShadow, +hasShadow: hasShadow, +nativeShadow: nativeShadow, +useShadow: useShadow, +useNativeShadow: useShadow && nativeShadow, +useNativeImports: useNativeImports, +useNativeCustomElements: useNativeCustomElements +}; +}() +}; +(function () { +var userPolymer = window.Polymer; +window.Polymer = function (prototype) { +if (typeof prototype === 'function') { +prototype = prototype.prototype; +} +if (!prototype) { +prototype = {}; +} +var factory = desugar(prototype); +prototype = factory.prototype; +var options = { prototype: prototype }; +if (prototype.extends) { +options.extends = prototype.extends; +} +Polymer.telemetry._registrate(prototype); +document.registerElement(prototype.is, options); +return factory; +}; +var desugar = function (prototype) { +var base = Polymer.Base; +if (prototype.extends) { +base = Polymer.Base._getExtendedPrototype(prototype.extends); +} +prototype = Polymer.Base.chainObject(prototype, base); +prototype.registerCallback(); +return prototype.constructor; +}; +window.Polymer = Polymer; +if (userPolymer) { +for (var i in userPolymer) { +Polymer[i] = userPolymer[i]; +} +} +Polymer.Class = desugar; +}()); +Polymer.telemetry = { +registrations: [], +_regLog: function (prototype) { +console.log('[' + prototype.is + ']: registered'); +}, +_registrate: function (prototype) { +this.registrations.push(prototype); +Polymer.log && this._regLog(prototype); +}, +dumpRegistrations: function () { +this.registrations.forEach(this._regLog); +} +}; +Object.defineProperty(window, 'currentImport', { +enumerable: true, +configurable: true, +get: function () { +return (document._currentScript || document.currentScript).ownerDocument; +} +}); +Polymer.RenderStatus = { +_ready: false, +_callbacks: [], +whenReady: function (cb) { +if (this._ready) { +cb(); +} else { +this._callbacks.push(cb); +} +}, +_makeReady: function () { +this._ready = true; +for (var i = 0; i < this._callbacks.length; i++) { +this._callbacks[i](); +} +this._callbacks = []; +}, +_catchFirstRender: function () { +requestAnimationFrame(function () { +Polymer.RenderStatus._makeReady(); +}); +}, +_afterNextRenderQueue: [], +_waitingNextRender: false, +afterNextRender: function (element, fn, args) { +this._watchNextRender(); +this._afterNextRenderQueue.push([ +element, +fn, +args +]); +}, +_watchNextRender: function () { +if (!this._waitingNextRender) { +this._waitingNextRender = true; +var fn = function () { +Polymer.RenderStatus._flushNextRender(); +}; +if (!this._ready) { +this.whenReady(fn); +} else { +requestAnimationFrame(fn); +} +} +}, +_flushNextRender: function () { +var self = this; +setTimeout(function () { +self._flushRenderCallbacks(self._afterNextRenderQueue); +self._afterNextRenderQueue = []; +self._waitingNextRender = false; +}); +}, +_flushRenderCallbacks: function (callbacks) { +for (var i = 0, h; i < callbacks.length; i++) { +h = callbacks[i]; +h[1].apply(h[0], h[2] || Polymer.nar); +} +; +} +}; +if (window.HTMLImports) { +HTMLImports.whenReady(function () { +Polymer.RenderStatus._catchFirstRender(); +}); +} else { +Polymer.RenderStatus._catchFirstRender(); +} +Polymer.ImportStatus = Polymer.RenderStatus; +Polymer.ImportStatus.whenLoaded = Polymer.ImportStatus.whenReady; +Polymer.Base = { +__isPolymerInstance__: true, +_addFeature: function (feature) { +this.extend(this, feature); +}, +registerCallback: function () { +this._desugarBehaviors(); +this._doBehavior('beforeRegister'); +this._registerFeatures(); +this._doBehavior('registered'); +}, +createdCallback: function () { +Polymer.telemetry.instanceCount++; +this.root = this; +this._doBehavior('created'); +this._initFeatures(); +}, +attachedCallback: function () { +var self = this; +Polymer.RenderStatus.whenReady(function () { +self.isAttached = true; +self._doBehavior('attached'); +}); +}, +detachedCallback: function () { +this.isAttached = false; +this._doBehavior('detached'); +}, +attributeChangedCallback: function (name, oldValue, newValue) { +this._attributeChangedImpl(name); +this._doBehavior('attributeChanged', [ +name, +oldValue, +newValue +]); +}, +_attributeChangedImpl: function (name) { +this._setAttributeToProperty(this, name); +}, +extend: function (prototype, api) { +if (prototype && api) { +var n$ = Object.getOwnPropertyNames(api); +for (var i = 0, n; i < n$.length && (n = n$[i]); i++) { +this.copyOwnProperty(n, api, prototype); +} +} +return prototype || api; +}, +mixin: function (target, source) { +for (var i in source) { +target[i] = source[i]; +} +return target; +}, +copyOwnProperty: function (name, source, target) { +var pd = Object.getOwnPropertyDescriptor(source, name); +if (pd) { +Object.defineProperty(target, name, pd); +} +}, +_log: console.log.apply.bind(console.log, console), +_warn: console.warn.apply.bind(console.warn, console), +_error: console.error.apply.bind(console.error, console), +_logf: function () { +return this._logPrefix.concat([this.is]).concat(Array.prototype.slice.call(arguments, 0)); +} +}; +Polymer.Base._logPrefix = function () { +var color = window.chrome || /firefox/i.test(navigator.userAgent); +return color ? [ +'%c[%s::%s]:', +'font-weight: bold; background-color:#EEEE00;' +] : ['[%s::%s]:']; +}(); +Polymer.Base.chainObject = function (object, inherited) { +if (object && inherited && object !== inherited) { +if (!Object.__proto__) { +object = Polymer.Base.extend(Object.create(inherited), object); +} +object.__proto__ = inherited; +} +return object; +}; +Polymer.Base = Polymer.Base.chainObject(Polymer.Base, HTMLElement.prototype); +if (window.CustomElements) { +Polymer.instanceof = CustomElements.instanceof; +} else { +Polymer.instanceof = function (obj, ctor) { +return obj instanceof ctor; +}; +} +Polymer.isInstance = function (obj) { +return Boolean(obj && obj.__isPolymerInstance__); +}; +Polymer.telemetry.instanceCount = 0; +(function () { +var modules = {}; +var lcModules = {}; +var findModule = function (id) { +return modules[id] || lcModules[id.toLowerCase()]; +}; +var DomModule = function () { +return document.createElement('dom-module'); +}; +DomModule.prototype = Object.create(HTMLElement.prototype); +Polymer.Base.extend(DomModule.prototype, { +constructor: DomModule, +createdCallback: function () { +this.register(); +}, +register: function (id) { +var id = id || this.id || this.getAttribute('name') || this.getAttribute('is'); +if (id) { +this.id = id; +modules[id] = this; +lcModules[id.toLowerCase()] = this; +} +}, +import: function (id, selector) { +if (id) { +var m = findModule(id); +if (!m) { +forceDomModulesUpgrade(); +m = findModule(id); +} +if (m && selector) { +m = m.querySelector(selector); +} +return m; +} +} +}); +var cePolyfill = window.CustomElements && !CustomElements.useNative; +document.registerElement('dom-module', DomModule); +function forceDomModulesUpgrade() { +if (cePolyfill) { +var script = document._currentScript || document.currentScript; +var doc = script && script.ownerDocument || document; +var modules = doc.querySelectorAll('dom-module'); +for (var i = modules.length - 1, m; i >= 0 && (m = modules[i]); i--) { +if (m.__upgraded__) { +return; +} else { +CustomElements.upgrade(m); +} +} +} +} +}()); +Polymer.Base._addFeature({ +_prepIs: function () { +if (!this.is) { +var module = (document._currentScript || document.currentScript).parentNode; +if (module.localName === 'dom-module') { +var id = module.id || module.getAttribute('name') || module.getAttribute('is'); +this.is = id; +} +} +if (this.is) { +this.is = this.is.toLowerCase(); +} +} +}); +Polymer.Base._addFeature({ +behaviors: [], +_desugarBehaviors: function () { +if (this.behaviors.length) { +this.behaviors = this._desugarSomeBehaviors(this.behaviors); +} +}, +_desugarSomeBehaviors: function (behaviors) { +behaviors = this._flattenBehaviorsList(behaviors); +for (var i = behaviors.length - 1; i >= 0; i--) { +this._mixinBehavior(behaviors[i]); +} +return behaviors; +}, +_flattenBehaviorsList: function (behaviors) { +var flat = []; +for (var i = 0; i < behaviors.length; i++) { +var b = behaviors[i]; +if (b instanceof Array) { +flat = flat.concat(this._flattenBehaviorsList(b)); +} else if (b) { +flat.push(b); +} else { +this._warn(this._logf('_flattenBehaviorsList', 'behavior is null, check for missing or 404 import')); +} +} +return flat; +}, +_mixinBehavior: function (b) { +var n$ = Object.getOwnPropertyNames(b); +for (var i = 0, n; i < n$.length && (n = n$[i]); i++) { +if (!Polymer.Base._behaviorProperties[n] && !this.hasOwnProperty(n)) { +this.copyOwnProperty(n, b, this); +} +} +}, +_prepBehaviors: function () { +this._prepFlattenedBehaviors(this.behaviors); +}, +_prepFlattenedBehaviors: function (behaviors) { +for (var i = 0, l = behaviors.length; i < l; i++) { +this._prepBehavior(behaviors[i]); +} +this._prepBehavior(this); +}, +_doBehavior: function (name, args) { +for (var i = 0; i < this.behaviors.length; i++) { +this._invokeBehavior(this.behaviors[i], name, args); +} +this._invokeBehavior(this, name, args); +}, +_invokeBehavior: function (b, name, args) { +var fn = b[name]; +if (fn) { +fn.apply(this, args || Polymer.nar); +} +}, +_marshalBehaviors: function () { +for (var i = 0; i < this.behaviors.length; i++) { +this._marshalBehavior(this.behaviors[i]); +} +this._marshalBehavior(this); +} +}); +Polymer.Base._behaviorProperties = { +hostAttributes: true, +registered: true, +properties: true, +observers: true, +listeners: true, +created: true, +attached: true, +detached: true, +attributeChanged: true, +ready: true +}; +Polymer.Base._addFeature({ +_getExtendedPrototype: function (tag) { +return this._getExtendedNativePrototype(tag); +}, +_nativePrototypes: {}, +_getExtendedNativePrototype: function (tag) { +var p = this._nativePrototypes[tag]; +if (!p) { +var np = this.getNativePrototype(tag); +p = this.extend(Object.create(np), Polymer.Base); +this._nativePrototypes[tag] = p; +} +return p; +}, +getNativePrototype: function (tag) { +return Object.getPrototypeOf(document.createElement(tag)); +} +}); +Polymer.Base._addFeature({ +_prepConstructor: function () { +this._factoryArgs = this.extends ? [ +this.extends, +this.is +] : [this.is]; +var ctor = function () { +return this._factory(arguments); +}; +if (this.hasOwnProperty('extends')) { +ctor.extends = this.extends; +} +Object.defineProperty(this, 'constructor', { +value: ctor, +writable: true, +configurable: true +}); +ctor.prototype = this; +}, +_factory: function (args) { +var elt = document.createElement.apply(document, this._factoryArgs); +if (this.factoryImpl) { +this.factoryImpl.apply(elt, args); +} +return elt; +} +}); +Polymer.nob = Object.create(null); +Polymer.Base._addFeature({ +properties: {}, +getPropertyInfo: function (property) { +var info = this._getPropertyInfo(property, this.properties); +if (!info) { +for (var i = 0; i < this.behaviors.length; i++) { +info = this._getPropertyInfo(property, this.behaviors[i].properties); +if (info) { +return info; +} +} +; +} +return info || Polymer.nob; +}, +_getPropertyInfo: function (property, properties) { +var p = properties && properties[property]; +if (typeof p === 'function') { +p = properties[property] = { type: p }; +} +if (p) { +p.defined = true; +} +return p; +}, +_prepPropertyInfo: function () { +this._propertyInfo = {}; +for (var i = 0, p; i < this.behaviors.length; i++) { +this._addPropertyInfo(this._propertyInfo, this.behaviors[i].properties); +} +this._addPropertyInfo(this._propertyInfo, this.properties); +this._addPropertyInfo(this._propertyInfo, this._propertyEffects); +}, +_addPropertyInfo: function (target, source) { +if (source) { +var t, s; +for (var i in source) { +t = target[i]; +s = source[i]; +if (i[0] === '_' && !s.readOnly) { +continue; +} +if (!target[i]) { +target[i] = { +type: typeof s === 'function' ? s : s.type, +readOnly: s.readOnly, +attribute: Polymer.CaseMap.camelToDashCase(i) +}; +} else { +if (!t.type) { +t.type = s.type; +} +if (!t.readOnly) { +t.readOnly = s.readOnly; +} +} +} +} +} +}); +Polymer.CaseMap = { +_caseMap: {}, +dashToCamelCase: function (dash) { +var mapped = Polymer.CaseMap._caseMap[dash]; +if (mapped) { +return mapped; +} +if (dash.indexOf('-') < 0) { +return Polymer.CaseMap._caseMap[dash] = dash; +} +return Polymer.CaseMap._caseMap[dash] = dash.replace(/-([a-z])/g, function (m) { +return m[1].toUpperCase(); +}); +}, +camelToDashCase: function (camel) { +var mapped = Polymer.CaseMap._caseMap[camel]; +if (mapped) { +return mapped; +} +return Polymer.CaseMap._caseMap[camel] = camel.replace(/([a-z][A-Z])/g, function (g) { +return g[0] + '-' + g[1].toLowerCase(); +}); +} +}; +Polymer.Base._addFeature({ +_addHostAttributes: function (attributes) { +if (!this._aggregatedAttributes) { +this._aggregatedAttributes = {}; +} +if (attributes) { +this.mixin(this._aggregatedAttributes, attributes); +} +}, +_marshalHostAttributes: function () { +if (this._aggregatedAttributes) { +this._applyAttributes(this, this._aggregatedAttributes); +} +}, +_applyAttributes: function (node, attr$) { +for (var n in attr$) { +if (!this.hasAttribute(n) && n !== 'class') { +var v = attr$[n]; +this.serializeValueToAttribute(v, n, this); +} +} +}, +_marshalAttributes: function () { +this._takeAttributesToModel(this); +}, +_takeAttributesToModel: function (model) { +if (this.hasAttributes()) { +for (var i in this._propertyInfo) { +var info = this._propertyInfo[i]; +if (this.hasAttribute(info.attribute)) { +this._setAttributeToProperty(model, info.attribute, i, info); +} +} +} +}, +_setAttributeToProperty: function (model, attribute, property, info) { +if (!this._serializing) { +var property = property || Polymer.CaseMap.dashToCamelCase(attribute); +info = info || this._propertyInfo && this._propertyInfo[property]; +if (info && !info.readOnly) { +var v = this.getAttribute(attribute); +model[property] = this.deserialize(v, info.type); +} +} +}, +_serializing: false, +reflectPropertyToAttribute: function (property, attribute, value) { +this._serializing = true; +value = value === undefined ? this[property] : value; +this.serializeValueToAttribute(value, attribute || Polymer.CaseMap.camelToDashCase(property)); +this._serializing = false; +}, +serializeValueToAttribute: function (value, attribute, node) { +var str = this.serialize(value); +node = node || this; +if (str === undefined) { +node.removeAttribute(attribute); +} else { +node.setAttribute(attribute, str); +} +}, +deserialize: function (value, type) { +switch (type) { +case Number: +value = Number(value); +break; +case Boolean: +value = value !== null; +break; +case Object: +try { +value = JSON.parse(value); +} catch (x) { +} +break; +case Array: +try { +value = JSON.parse(value); +} catch (x) { +value = null; +console.warn('Polymer::Attributes: couldn`t decode Array as JSON'); +} +break; +case Date: +value = new Date(value); +break; +case String: +default: +break; +} +return value; +}, +serialize: function (value) { +switch (typeof value) { +case 'boolean': +return value ? '' : undefined; +case 'object': +if (value instanceof Date) { +return value; +} else if (value) { +try { +return JSON.stringify(value); +} catch (x) { +return ''; +} +} +default: +return value != null ? value : undefined; +} +} +}); +Polymer.Base._addFeature({ +_setupDebouncers: function () { +this._debouncers = {}; +}, +debounce: function (jobName, callback, wait) { +return this._debouncers[jobName] = Polymer.Debounce.call(this, this._debouncers[jobName], callback, wait); +}, +isDebouncerActive: function (jobName) { +var debouncer = this._debouncers[jobName]; +return debouncer && debouncer.finish; +}, +flushDebouncer: function (jobName) { +var debouncer = this._debouncers[jobName]; +if (debouncer) { +debouncer.complete(); +} +}, +cancelDebouncer: function (jobName) { +var debouncer = this._debouncers[jobName]; +if (debouncer) { +debouncer.stop(); +} +} +}); +Polymer.version = '1.2.3'; +Polymer.Base._addFeature({ +_registerFeatures: function () { +this._prepIs(); +this._prepBehaviors(); +this._prepConstructor(); +this._prepPropertyInfo(); +}, +_prepBehavior: function (b) { +this._addHostAttributes(b.hostAttributes); +}, +_marshalBehavior: function (b) { +}, +_initFeatures: function () { +this._marshalHostAttributes(); +this._setupDebouncers(); +this._marshalBehaviors(); +} +});</script><script>Polymer.Base._addFeature({ +_prepTemplate: function () { +if (this._template === undefined) { +this._template = Polymer.DomModule.import(this.is, 'template'); +} +if (this._template && this._template.hasAttribute('is')) { +this._warn(this._logf('_prepTemplate', 'top-level Polymer template ' + 'must not be a type-extension, found', this._template, 'Move inside simple <template>.')); +} +if (this._template && !this._template.content && window.HTMLTemplateElement && HTMLTemplateElement.decorate) { +HTMLTemplateElement.decorate(this._template); +} +}, +_stampTemplate: function () { +if (this._template) { +this.root = this.instanceTemplate(this._template); +} +}, +instanceTemplate: function (template) { +var dom = document.importNode(template._content || template.content, true); +return dom; +} +}); +(function () { +var baseAttachedCallback = Polymer.Base.attachedCallback; +Polymer.Base._addFeature({ +_hostStack: [], +ready: function () { +}, +_registerHost: function (host) { +this.dataHost = host = host || Polymer.Base._hostStack[Polymer.Base._hostStack.length - 1]; +if (host && host._clients) { +host._clients.push(this); +} +}, +_beginHosting: function () { +Polymer.Base._hostStack.push(this); +if (!this._clients) { +this._clients = []; +} +}, +_endHosting: function () { +Polymer.Base._hostStack.pop(); +}, +_tryReady: function () { +if (this._canReady()) { +this._ready(); +} +}, +_canReady: function () { +return !this.dataHost || this.dataHost._clientsReadied; +}, +_ready: function () { +this._beforeClientsReady(); +if (this._template) { +this._setupRoot(); +this._readyClients(); +} +this._clientsReadied = true; +this._clients = null; +this._afterClientsReady(); +this._readySelf(); +}, +_readyClients: function () { +this._beginDistribute(); +var c$ = this._clients; +if (c$) { +for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) { +c._ready(); +} +} +this._finishDistribute(); +}, +_readySelf: function () { +this._doBehavior('ready'); +this._readied = true; +if (this._attachedPending) { +this._attachedPending = false; +this.attachedCallback(); +} +}, +_beforeClientsReady: function () { +}, +_afterClientsReady: function () { +}, +_beforeAttached: function () { +}, +attachedCallback: function () { +if (this._readied) { +this._beforeAttached(); +baseAttachedCallback.call(this); +} else { +this._attachedPending = true; +} +} +}); +}()); +Polymer.ArraySplice = function () { +function newSplice(index, removed, addedCount) { +return { +index: index, +removed: removed, +addedCount: addedCount +}; +} +var EDIT_LEAVE = 0; +var EDIT_UPDATE = 1; +var EDIT_ADD = 2; +var EDIT_DELETE = 3; +function ArraySplice() { +} +ArraySplice.prototype = { +calcEditDistances: function (current, currentStart, currentEnd, old, oldStart, oldEnd) { +var rowCount = oldEnd - oldStart + 1; +var columnCount = currentEnd - currentStart + 1; +var distances = new Array(rowCount); +for (var i = 0; i < rowCount; i++) { +distances[i] = new Array(columnCount); +distances[i][0] = i; +} +for (var j = 0; j < columnCount; j++) +distances[0][j] = j; +for (var i = 1; i < rowCount; i++) { +for (var j = 1; j < columnCount; j++) { +if (this.equals(current[currentStart + j - 1], old[oldStart + i - 1])) +distances[i][j] = distances[i - 1][j - 1]; +else { +var north = distances[i - 1][j] + 1; +var west = distances[i][j - 1] + 1; +distances[i][j] = north < west ? north : west; +} +} +} +return distances; +}, +spliceOperationsFromEditDistances: function (distances) { +var i = distances.length - 1; +var j = distances[0].length - 1; +var current = distances[i][j]; +var edits = []; +while (i > 0 || j > 0) { +if (i == 0) { +edits.push(EDIT_ADD); +j--; +continue; +} +if (j == 0) { +edits.push(EDIT_DELETE); +i--; +continue; +} +var northWest = distances[i - 1][j - 1]; +var west = distances[i - 1][j]; +var north = distances[i][j - 1]; +var min; +if (west < north) +min = west < northWest ? west : northWest; +else +min = north < northWest ? north : northWest; +if (min == northWest) { +if (northWest == current) { +edits.push(EDIT_LEAVE); +} else { +edits.push(EDIT_UPDATE); +current = northWest; +} +i--; +j--; +} else if (min == west) { +edits.push(EDIT_DELETE); +i--; +current = west; +} else { +edits.push(EDIT_ADD); +j--; +current = north; +} +} +edits.reverse(); +return edits; +}, +calcSplices: function (current, currentStart, currentEnd, old, oldStart, oldEnd) { +var prefixCount = 0; +var suffixCount = 0; +var minLength = Math.min(currentEnd - currentStart, oldEnd - oldStart); +if (currentStart == 0 && oldStart == 0) +prefixCount = this.sharedPrefix(current, old, minLength); +if (currentEnd == current.length && oldEnd == old.length) +suffixCount = this.sharedSuffix(current, old, minLength - prefixCount); +currentStart += prefixCount; +oldStart += prefixCount; +currentEnd -= suffixCount; +oldEnd -= suffixCount; +if (currentEnd - currentStart == 0 && oldEnd - oldStart == 0) +return []; +if (currentStart == currentEnd) { +var splice = newSplice(currentStart, [], 0); +while (oldStart < oldEnd) +splice.removed.push(old[oldStart++]); +return [splice]; +} else if (oldStart == oldEnd) +return [newSplice(currentStart, [], currentEnd - currentStart)]; +var ops = this.spliceOperationsFromEditDistances(this.calcEditDistances(current, currentStart, currentEnd, old, oldStart, oldEnd)); +var splice = undefined; +var splices = []; +var index = currentStart; +var oldIndex = oldStart; +for (var i = 0; i < ops.length; i++) { +switch (ops[i]) { +case EDIT_LEAVE: +if (splice) { +splices.push(splice); +splice = undefined; +} +index++; +oldIndex++; +break; +case EDIT_UPDATE: +if (!splice) +splice = newSplice(index, [], 0); +splice.addedCount++; +index++; +splice.removed.push(old[oldIndex]); +oldIndex++; +break; +case EDIT_ADD: +if (!splice) +splice = newSplice(index, [], 0); +splice.addedCount++; +index++; +break; +case EDIT_DELETE: +if (!splice) +splice = newSplice(index, [], 0); +splice.removed.push(old[oldIndex]); +oldIndex++; +break; +} +} +if (splice) { +splices.push(splice); +} +return splices; +}, +sharedPrefix: function (current, old, searchLength) { +for (var i = 0; i < searchLength; i++) +if (!this.equals(current[i], old[i])) +return i; +return searchLength; +}, +sharedSuffix: function (current, old, searchLength) { +var index1 = current.length; +var index2 = old.length; +var count = 0; +while (count < searchLength && this.equals(current[--index1], old[--index2])) +count++; +return count; +}, +calculateSplices: function (current, previous) { +return this.calcSplices(current, 0, current.length, previous, 0, previous.length); +}, +equals: function (currentValue, previousValue) { +return currentValue === previousValue; +} +}; +return new ArraySplice(); +}(); +Polymer.domInnerHTML = function () { +var escapeAttrRegExp = /[&\u00A0"]/g; +var escapeDataRegExp = /[&\u00A0<>]/g; +function escapeReplace(c) { +switch (c) { +case '&': +return '&amp;'; +case '<': +return '&lt;'; +case '>': +return '&gt;'; +case '"': +return '&quot;'; +case '\xA0': +return '&nbsp;'; +} +} +function escapeAttr(s) { +return s.replace(escapeAttrRegExp, escapeReplace); +} +function escapeData(s) { +return s.replace(escapeDataRegExp, escapeReplace); +} +function makeSet(arr) { +var set = {}; +for (var i = 0; i < arr.length; i++) { +set[arr[i]] = true; +} +return set; +} +var voidElements = makeSet([ +'area', +'base', +'br', +'col', +'command', +'embed', +'hr', +'img', +'input', +'keygen', +'link', +'meta', +'param', +'source', +'track', +'wbr' +]); +var plaintextParents = makeSet([ +'style', +'script', +'xmp', +'iframe', +'noembed', +'noframes', +'plaintext', +'noscript' +]); +function getOuterHTML(node, parentNode, composed) { +switch (node.nodeType) { +case Node.ELEMENT_NODE: +var tagName = node.localName; +var s = '<' + tagName; +var attrs = node.attributes; +for (var i = 0, attr; attr = attrs[i]; i++) { +s += ' ' + attr.name + '="' + escapeAttr(attr.value) + '"'; +} +s += '>'; +if (voidElements[tagName]) { +return s; +} +return s + getInnerHTML(node, composed) + '</' + tagName + '>'; +case Node.TEXT_NODE: +var data = node.data; +if (parentNode && plaintextParents[parentNode.localName]) { +return data; +} +return escapeData(data); +case Node.COMMENT_NODE: +return '<!--' + node.data + '-->'; +default: +console.error(node); +throw new Error('not implemented'); +} +} +function getInnerHTML(node, composed) { +if (node instanceof HTMLTemplateElement) +node = node.content; +var s = ''; +var c$ = Polymer.dom(node).childNodes; +c$ = composed ? node._composedChildren : c$; +for (var i = 0, l = c$.length, child; i < l && (child = c$[i]); i++) { +s += getOuterHTML(child, node, composed); +} +return s; +} +return { getInnerHTML: getInnerHTML }; +}(); +Polymer.DomApi = function () { +'use strict'; +var Settings = Polymer.Settings; +var getInnerHTML = Polymer.domInnerHTML.getInnerHTML; +var nativeInsertBefore = Element.prototype.insertBefore; +var nativeRemoveChild = Element.prototype.removeChild; +var nativeAppendChild = Element.prototype.appendChild; +var nativeCloneNode = Element.prototype.cloneNode; +var nativeImportNode = Document.prototype.importNode; +var needsToWrap = Settings.hasShadow && !Settings.nativeShadow; +var wrap = window.wrap ? window.wrap : function (node) { +return node; +}; +var DomApi = function (node) { +this.node = needsToWrap ? wrap(node) : node; +if (this.patch) { +this.patch(); +} +}; +DomApi.prototype = { +flush: function () { +Polymer.dom.flush(); +}, +deepContains: function (node) { +if (this.node.contains(node)) { +return true; +} +var n = node; +var wrappedDocument = wrap(document); +while (n && n !== wrappedDocument && n !== this.node) { +n = Polymer.dom(n).parentNode || n.host; +} +return n === this.node; +}, +_lazyDistribute: function (host) { +if (host.shadyRoot && host.shadyRoot._distributionClean) { +host.shadyRoot._distributionClean = false; +Polymer.dom.addDebouncer(host.debounce('_distribute', host._distributeContent)); +} +}, +appendChild: function (node) { +return this._addNode(node); +}, +insertBefore: function (node, ref_node) { +return this._addNode(node, ref_node); +}, +_addNode: function (node, ref_node) { +this._removeNodeFromParent(node); +var addedInsertionPoint; +var root = this.getOwnerRoot(); +if (root) { +addedInsertionPoint = this._maybeAddInsertionPoint(node, this.node); +} +if (this._nodeHasLogicalChildren(this.node)) { +if (ref_node) { +var children = this.childNodes; +var index = children.indexOf(ref_node); +if (index < 0) { +throw Error('The ref_node to be inserted before is not a child ' + 'of this node'); +} +} +this._addLogicalInfo(node, this.node, index); +} +this._addNodeToHost(node); +if (!this._maybeDistribute(node, this.node) && !this._tryRemoveUndistributedNode(node)) { +if (ref_node) { +ref_node = ref_node.localName === CONTENT ? this._firstComposedNode(ref_node) : ref_node; +} +var container = this.node._isShadyRoot ? this.node.host : this.node; +addToComposedParent(container, node, ref_node); +if (ref_node) { +nativeInsertBefore.call(container, node, ref_node); +} else { +nativeAppendChild.call(container, node); +} +} +if (addedInsertionPoint) { +this._updateInsertionPoints(root.host); +} +this.notifyObserver(); +return node; +}, +removeChild: function (node) { +if (factory(node).parentNode !== this.node) { +console.warn('The node to be removed is not a child of this node', node); +} +this._removeNodeFromHost(node); +if (!this._maybeDistribute(node, this.node)) { +var container = this.node._isShadyRoot ? this.node.host : this.node; +if (container === node.parentNode) { +removeFromComposedParent(container, node); +nativeRemoveChild.call(container, node); +} +} +this.notifyObserver(); +return node; +}, +replaceChild: function (node, ref_node) { +this.insertBefore(node, ref_node); +this.removeChild(ref_node); +return node; +}, +_hasCachedOwnerRoot: function (node) { +return Boolean(node._ownerShadyRoot !== undefined); +}, +getOwnerRoot: function () { +return this._ownerShadyRootForNode(this.node); +}, +_ownerShadyRootForNode: function (node) { +if (!node) { +return; +} +if (node._ownerShadyRoot === undefined) { +var root; +if (node._isShadyRoot) { +root = node; +} else { +var parent = Polymer.dom(node).parentNode; +if (parent) { +root = parent._isShadyRoot ? parent : this._ownerShadyRootForNode(parent); +} else { +root = null; +} +} +node._ownerShadyRoot = root; +} +return node._ownerShadyRoot; +}, +_maybeDistribute: function (node, parent) { +var fragContent = node.nodeType === Node.DOCUMENT_FRAGMENT_NODE && !node.__noContent && Polymer.dom(node).querySelector(CONTENT); +var wrappedContent = fragContent && Polymer.dom(fragContent).parentNode.nodeType !== Node.DOCUMENT_FRAGMENT_NODE; +var hasContent = fragContent || node.localName === CONTENT; +if (hasContent) { +var root = this._ownerShadyRootForNode(parent); +if (root) { +var host = root.host; +this._lazyDistribute(host); +} +} +var parentNeedsDist = this._parentNeedsDistribution(parent); +if (parentNeedsDist) { +this._lazyDistribute(parent); +} +return parentNeedsDist || hasContent && !wrappedContent; +}, +_maybeAddInsertionPoint: function (node, parent) { +var added; +if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE && !node.__noContent) { +var c$ = factory(node).querySelectorAll(CONTENT); +for (var i = 0, n, np, na; i < c$.length && (n = c$[i]); i++) { +np = factory(n).parentNode; +if (np === node) { +np = parent; +} +na = this._maybeAddInsertionPoint(n, np); +added = added || na; +} +} else if (node.localName === CONTENT) { +saveLightChildrenIfNeeded(parent); +saveLightChildrenIfNeeded(node); +added = true; +} +return added; +}, +_tryRemoveUndistributedNode: function (node) { +if (this.node.shadyRoot) { +var parent = getComposedParent(node); +if (parent) { +nativeRemoveChild.call(parent, node); +} +return true; +} +}, +_updateInsertionPoints: function (host) { +var i$ = host.shadyRoot._insertionPoints = factory(host.shadyRoot).querySelectorAll(CONTENT); +for (var i = 0, c; i < i$.length; i++) { +c = i$[i]; +saveLightChildrenIfNeeded(c); +saveLightChildrenIfNeeded(factory(c).parentNode); +} +}, +_nodeHasLogicalChildren: function (node) { +return Boolean(node._lightChildren !== undefined); +}, +_parentNeedsDistribution: function (parent) { +return parent && parent.shadyRoot && hasInsertionPoint(parent.shadyRoot); +}, +_removeNodeFromParent: function (node) { +var parent = node._lightParent || node.parentNode; +if (parent && hasDomApi(parent)) { +factory(parent).notifyObserver(); +} +this._removeNodeFromHost(node, true); +}, +_removeNodeFromHost: function (node, ensureComposedRemoval) { +var hostNeedsDist; +var root; +var parent = node._lightParent; +if (parent) { +factory(node)._distributeParent(); +root = this._ownerShadyRootForNode(node); +if (root) { +root.host._elementRemove(node); +hostNeedsDist = this._removeDistributedChildren(root, node); +} +this._removeLogicalInfo(node, parent); +} +this._removeOwnerShadyRoot(node); +if (root && hostNeedsDist) { +this._updateInsertionPoints(root.host); +this._lazyDistribute(root.host); +} else if (ensureComposedRemoval) { +removeFromComposedParent(getComposedParent(node), node); +} +}, +_removeDistributedChildren: function (root, container) { +var hostNeedsDist; +var ip$ = root._insertionPoints; +for (var i = 0; i < ip$.length; i++) { +var content = ip$[i]; +if (this._contains(container, content)) { +var dc$ = factory(content).getDistributedNodes(); +for (var j = 0; j < dc$.length; j++) { +hostNeedsDist = true; +var node = dc$[j]; +var parent = node.parentNode; +if (parent) { +removeFromComposedParent(parent, node); +nativeRemoveChild.call(parent, node); +} +} +} +} +return hostNeedsDist; +}, +_contains: function (container, node) { +while (node) { +if (node == container) { +return true; +} +node = factory(node).parentNode; +} +}, +_addNodeToHost: function (node) { +var root = this.getOwnerRoot(); +if (root) { +root.host._elementAdd(node); +} +}, +_addLogicalInfo: function (node, container, index) { +var children = factory(container).childNodes; +index = index === undefined ? children.length : index; +if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { +var c$ = arrayCopyChildNodes(node); +for (var i = 0, n; i < c$.length && (n = c$[i]); i++) { +children.splice(index++, 0, n); +n._lightParent = container; +} +} else { +children.splice(index, 0, node); +node._lightParent = container; +} +}, +_removeLogicalInfo: function (node, container) { +var children = factory(container).childNodes; +var index = children.indexOf(node); +if (index < 0 || container !== node._lightParent) { +throw Error('The node to be removed is not a child of this node'); +} +children.splice(index, 1); +node._lightParent = null; +}, +_removeOwnerShadyRoot: function (node) { +if (this._hasCachedOwnerRoot(node)) { +var c$ = factory(node).childNodes; +for (var i = 0, l = c$.length, n; i < l && (n = c$[i]); i++) { +this._removeOwnerShadyRoot(n); +} +} +node._ownerShadyRoot = undefined; +}, +_firstComposedNode: function (content) { +var n$ = factory(content).getDistributedNodes(); +for (var i = 0, l = n$.length, n, p$; i < l && (n = n$[i]); i++) { +p$ = factory(n).getDestinationInsertionPoints(); +if (p$[p$.length - 1] === content) { +return n; +} +} +}, +querySelector: function (selector) { +return this.querySelectorAll(selector)[0]; +}, +querySelectorAll: function (selector) { +return this._query(function (n) { +return matchesSelector.call(n, selector); +}, this.node); +}, +_query: function (matcher, node) { +node = node || this.node; +var list = []; +this._queryElements(factory(node).childNodes, matcher, list); +return list; +}, +_queryElements: function (elements, matcher, list) { +for (var i = 0, l = elements.length, c; i < l && (c = elements[i]); i++) { +if (c.nodeType === Node.ELEMENT_NODE) { +this._queryElement(c, matcher, list); +} +} +}, +_queryElement: function (node, matcher, list) { +if (matcher(node)) { +list.push(node); +} +this._queryElements(factory(node).childNodes, matcher, list); +}, +getDestinationInsertionPoints: function () { +return this.node._destinationInsertionPoints || []; +}, +getDistributedNodes: function () { +return this.node._distributedNodes || []; +}, +queryDistributedElements: function (selector) { +var c$ = this.getEffectiveChildNodes(); +var list = []; +for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) { +if (c.nodeType === Node.ELEMENT_NODE && matchesSelector.call(c, selector)) { +list.push(c); +} +} +return list; +}, +getEffectiveChildNodes: function () { +var list = []; +var c$ = this.childNodes; +for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) { +if (c.localName === CONTENT) { +var d$ = factory(c).getDistributedNodes(); +for (var j = 0; j < d$.length; j++) { +list.push(d$[j]); +} +} else { +list.push(c); +} +} +return list; +}, +_clear: function () { +while (this.childNodes.length) { +this.removeChild(this.childNodes[0]); +} +}, +setAttribute: function (name, value) { +this.node.setAttribute(name, value); +this._distributeParent(); +}, +removeAttribute: function (name) { +this.node.removeAttribute(name); +this._distributeParent(); +}, +_distributeParent: function () { +if (this._parentNeedsDistribution(this.parentNode)) { +this._lazyDistribute(this.parentNode); +} +}, +cloneNode: function (deep) { +var n = nativeCloneNode.call(this.node, false); +if (deep) { +var c$ = this.childNodes; +var d = factory(n); +for (var i = 0, nc; i < c$.length; i++) { +nc = factory(c$[i]).cloneNode(true); +d.appendChild(nc); +} +} +return n; +}, +importNode: function (externalNode, deep) { +var doc = this.node instanceof Document ? this.node : this.node.ownerDocument; +var n = nativeImportNode.call(doc, externalNode, false); +if (deep) { +var c$ = factory(externalNode).childNodes; +var d = factory(n); +for (var i = 0, nc; i < c$.length; i++) { +nc = factory(doc).importNode(c$[i], true); +d.appendChild(nc); +} +} +return n; +}, +observeNodes: function (callback) { +if (callback) { +if (!this.observer) { +this.observer = this.node.localName === CONTENT ? new DomApi.DistributedNodesObserver(this) : new DomApi.EffectiveNodesObserver(this); +} +return this.observer.addListener(callback); +} +}, +unobserveNodes: function (handle) { +if (this.observer) { +this.observer.removeListener(handle); +} +}, +notifyObserver: function () { +if (this.observer) { +this.observer.notify(); +} +} +}; +if (!Settings.useShadow) { +Object.defineProperties(DomApi.prototype, { +childNodes: { +get: function () { +var c$ = getLightChildren(this.node); +return Array.isArray(c$) ? c$ : arrayCopyChildNodes(this.node); +}, +configurable: true +}, +children: { +get: function () { +return Array.prototype.filter.call(this.childNodes, function (n) { +return n.nodeType === Node.ELEMENT_NODE; +}); +}, +configurable: true +}, +parentNode: { +get: function () { +return this.node._lightParent || getComposedParent(this.node); +}, +configurable: true +}, +firstChild: { +get: function () { +return this.childNodes[0]; +}, +configurable: true +}, +lastChild: { +get: function () { +var c$ = this.childNodes; +return c$[c$.length - 1]; +}, +configurable: true +}, +nextSibling: { +get: function () { +var c$ = this.parentNode && factory(this.parentNode).childNodes; +if (c$) { +return c$[Array.prototype.indexOf.call(c$, this.node) + 1]; +} +}, +configurable: true +}, +previousSibling: { +get: function () { +var c$ = this.parentNode && factory(this.parentNode).childNodes; +if (c$) { +return c$[Array.prototype.indexOf.call(c$, this.node) - 1]; +} +}, +configurable: true +}, +firstElementChild: { +get: function () { +return this.children[0]; +}, +configurable: true +}, +lastElementChild: { +get: function () { +var c$ = this.children; +return c$[c$.length - 1]; +}, +configurable: true +}, +nextElementSibling: { +get: function () { +var c$ = this.parentNode && factory(this.parentNode).children; +if (c$) { +return c$[Array.prototype.indexOf.call(c$, this.node) + 1]; +} +}, +configurable: true +}, +previousElementSibling: { +get: function () { +var c$ = this.parentNode && factory(this.parentNode).children; +if (c$) { +return c$[Array.prototype.indexOf.call(c$, this.node) - 1]; +} +}, +configurable: true +}, +textContent: { +get: function () { +var nt = this.node.nodeType; +if (nt === Node.TEXT_NODE || nt === Node.COMMENT_NODE) { +return this.node.textContent; +} else { +var tc = []; +for (var i = 0, cn = this.childNodes, c; c = cn[i]; i++) { +if (c.nodeType !== Node.COMMENT_NODE) { +tc.push(c.textContent); +} +} +return tc.join(''); +} +}, +set: function (text) { +var nt = this.node.nodeType; +if (nt === Node.TEXT_NODE || nt === Node.COMMENT_NODE) { +this.node.textContent = text; +} else { +this._clear(); +if (text) { +this.appendChild(document.createTextNode(text)); +} +} +}, +configurable: true +}, +innerHTML: { +get: function () { +var nt = this.node.nodeType; +if (nt === Node.TEXT_NODE || nt === Node.COMMENT_NODE) { +return null; +} else { +return getInnerHTML(this.node); +} +}, +set: function (text) { +var nt = this.node.nodeType; +if (nt !== Node.TEXT_NODE || nt !== Node.COMMENT_NODE) { +this._clear(); +var d = document.createElement('div'); +d.innerHTML = text; +var c$ = arrayCopyChildNodes(d); +for (var i = 0; i < c$.length; i++) { +this.appendChild(c$[i]); +} +} +}, +configurable: true +} +}); +DomApi.prototype._getComposedInnerHTML = function () { +return getInnerHTML(this.node, true); +}; +} else { +var forwardMethods = function (m$) { +for (var i = 0; i < m$.length; i++) { +forwardMethod(m$[i]); +} +}; +var forwardMethod = function (method) { +DomApi.prototype[method] = function () { +return this.node[method].apply(this.node, arguments); +}; +}; +forwardMethods([ +'cloneNode', +'appendChild', +'insertBefore', +'removeChild', +'replaceChild' +]); +DomApi.prototype.querySelectorAll = function (selector) { +return arrayCopy(this.node.querySelectorAll(selector)); +}; +DomApi.prototype.getOwnerRoot = function () { +var n = this.node; +while (n) { +if (n.nodeType === Node.DOCUMENT_FRAGMENT_NODE && n.host) { +return n; +} +n = n.parentNode; +} +}; +DomApi.prototype.importNode = function (externalNode, deep) { +var doc = this.node instanceof Document ? this.node : this.node.ownerDocument; +return doc.importNode(externalNode, deep); +}; +DomApi.prototype.getDestinationInsertionPoints = function () { +var n$ = this.node.getDestinationInsertionPoints && this.node.getDestinationInsertionPoints(); +return n$ ? arrayCopy(n$) : []; +}; +DomApi.prototype.getDistributedNodes = function () { +var n$ = this.node.getDistributedNodes && this.node.getDistributedNodes(); +return n$ ? arrayCopy(n$) : []; +}; +DomApi.prototype._distributeParent = function () { +}; +Object.defineProperties(DomApi.prototype, { +childNodes: { +get: function () { +return arrayCopyChildNodes(this.node); +}, +configurable: true +}, +children: { +get: function () { +return arrayCopyChildren(this.node); +}, +configurable: true +}, +textContent: { +get: function () { +return this.node.textContent; +}, +set: function (value) { +return this.node.textContent = value; +}, +configurable: true +}, +innerHTML: { +get: function () { +return this.node.innerHTML; +}, +set: function (value) { +return this.node.innerHTML = value; +}, +configurable: true +} +}); +var forwardProperties = function (f$) { +for (var i = 0; i < f$.length; i++) { +forwardProperty(f$[i]); +} +}; +var forwardProperty = function (name) { +Object.defineProperty(DomApi.prototype, name, { +get: function () { +return this.node[name]; +}, +configurable: true +}); +}; +forwardProperties([ +'parentNode', +'firstChild', +'lastChild', +'nextSibling', +'previousSibling', +'firstElementChild', +'lastElementChild', +'nextElementSibling', +'previousElementSibling' +]); +} +var CONTENT = 'content'; +function factory(node, patch) { +node = node || document; +if (!node.__domApi) { +node.__domApi = new DomApi(node, patch); +} +return node.__domApi; +} +; +function hasDomApi(node) { +return Boolean(node.__domApi); +} +; +Polymer.dom = function (obj, patch) { +if (obj instanceof Event) { +return Polymer.EventApi.factory(obj); +} else { +return factory(obj, patch); +} +}; +function getLightChildren(node) { +var children = node._lightChildren; +return children ? children : node.childNodes; +} +function getComposedChildren(node) { +if (!node._composedChildren) { +node._composedChildren = arrayCopyChildNodes(node); +} +return node._composedChildren; +} +function addToComposedParent(parent, node, ref_node) { +var children = getComposedChildren(parent); +var i = ref_node ? children.indexOf(ref_node) : -1; +if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { +var fragChildren = getComposedChildren(node); +for (var j = 0; j < fragChildren.length; j++) { +addNodeToComposedChildren(fragChildren[j], parent, children, i + j); +} +node._composedChildren = null; +} else { +addNodeToComposedChildren(node, parent, children, i); +} +} +function getComposedParent(node) { +return node.__patched ? node._composedParent : node.parentNode; +} +function addNodeToComposedChildren(node, parent, children, i) { +node._composedParent = parent; +children.splice(i >= 0 ? i : children.length, 0, node); +} +function removeFromComposedParent(parent, node) { +node._composedParent = null; +if (parent) { +var children = getComposedChildren(parent); +var i = children.indexOf(node); +if (i >= 0) { +children.splice(i, 1); +} +} +} +function saveLightChildrenIfNeeded(node) { +if (!node._lightChildren) { +var c$ = arrayCopyChildNodes(node); +for (var i = 0, l = c$.length, child; i < l && (child = c$[i]); i++) { +child._lightParent = child._lightParent || node; +} +node._lightChildren = c$; +} +} +function arrayCopyChildNodes(parent) { +var copy = [], i = 0; +for (var n = parent.firstChild; n; n = n.nextSibling) { +copy[i++] = n; +} +return copy; +} +function arrayCopyChildren(parent) { +var copy = [], i = 0; +for (var n = parent.firstElementChild; n; n = n.nextElementSibling) { +copy[i++] = n; +} +return copy; +} +function arrayCopy(a$) { +var l = a$.length; +var copy = new Array(l); +for (var i = 0; i < l; i++) { +copy[i] = a$[i]; +} +return copy; +} +function hasInsertionPoint(root) { +return Boolean(root && root._insertionPoints.length); +} +var p = Element.prototype; +var matchesSelector = p.matches || p.matchesSelector || p.mozMatchesSelector || p.msMatchesSelector || p.oMatchesSelector || p.webkitMatchesSelector; +return { +getLightChildren: getLightChildren, +getComposedParent: getComposedParent, +getComposedChildren: getComposedChildren, +removeFromComposedParent: removeFromComposedParent, +saveLightChildrenIfNeeded: saveLightChildrenIfNeeded, +matchesSelector: matchesSelector, +hasInsertionPoint: hasInsertionPoint, +ctor: DomApi, +factory: factory, +hasDomApi: hasDomApi, +arrayCopy: arrayCopy, +arrayCopyChildNodes: arrayCopyChildNodes, +arrayCopyChildren: arrayCopyChildren, +wrap: wrap +}; +}(); +Polymer.Base.extend(Polymer.dom, { +_flushGuard: 0, +_FLUSH_MAX: 100, +_needsTakeRecords: !Polymer.Settings.useNativeCustomElements, +_debouncers: [], +_staticFlushList: [], +_finishDebouncer: null, +flush: function () { +this._flushGuard = 0; +this._prepareFlush(); +while (this._debouncers.length && this._flushGuard < this._FLUSH_MAX) { +for (var i = 0; i < this._debouncers.length; i++) { +this._debouncers[i].complete(); +} +if (this._finishDebouncer) { +this._finishDebouncer.complete(); +} +this._prepareFlush(); +this._flushGuard++; +} +if (this._flushGuard >= this._FLUSH_MAX) { +console.warn('Polymer.dom.flush aborted. Flush may not be complete.'); +} +}, +_prepareFlush: function () { +if (this._needsTakeRecords) { +CustomElements.takeRecords(); +} +for (var i = 0; i < this._staticFlushList.length; i++) { +this._staticFlushList[i](); +} +}, +addStaticFlush: function (fn) { +this._staticFlushList.push(fn); +}, +removeStaticFlush: function (fn) { +var i = this._staticFlushList.indexOf(fn); +if (i >= 0) { +this._staticFlushList.splice(i, 1); +} +}, +addDebouncer: function (debouncer) { +this._debouncers.push(debouncer); +this._finishDebouncer = Polymer.Debounce(this._finishDebouncer, this._finishFlush); +}, +_finishFlush: function () { +Polymer.dom._debouncers = []; +} +}); +Polymer.EventApi = function () { +'use strict'; +var DomApi = Polymer.DomApi.ctor; +var Settings = Polymer.Settings; +DomApi.Event = function (event) { +this.event = event; +}; +if (Settings.useShadow) { +DomApi.Event.prototype = { +get rootTarget() { +return this.event.path[0]; +}, +get localTarget() { +return this.event.target; +}, +get path() { +return this.event.path; +} +}; +} else { +DomApi.Event.prototype = { +get rootTarget() { +return this.event.target; +}, +get localTarget() { +var current = this.event.currentTarget; +var currentRoot = current && Polymer.dom(current).getOwnerRoot(); +var p$ = this.path; +for (var i = 0; i < p$.length; i++) { +if (Polymer.dom(p$[i]).getOwnerRoot() === currentRoot) { +return p$[i]; +} +} +}, +get path() { +if (!this.event._path) { +var path = []; +var o = this.rootTarget; +while (o) { +path.push(o); +o = Polymer.dom(o).parentNode || o.host; +} +path.push(window); +this.event._path = path; +} +return this.event._path; +} +}; +} +var factory = function (event) { +if (!event.__eventApi) { +event.__eventApi = new DomApi.Event(event); +} +return event.__eventApi; +}; +return { factory: factory }; +}(); +(function () { +'use strict'; +var DomApi = Polymer.DomApi.ctor; +Object.defineProperty(DomApi.prototype, 'classList', { +get: function () { +if (!this._classList) { +this._classList = new DomApi.ClassList(this); +} +return this._classList; +}, +configurable: true +}); +DomApi.ClassList = function (host) { +this.domApi = host; +this.node = host.node; +}; +DomApi.ClassList.prototype = { +add: function () { +this.node.classList.add.apply(this.node.classList, arguments); +this.domApi._distributeParent(); +}, +remove: function () { +this.node.classList.remove.apply(this.node.classList, arguments); +this.domApi._distributeParent(); +}, +toggle: function () { +this.node.classList.toggle.apply(this.node.classList, arguments); +this.domApi._distributeParent(); +}, +contains: function () { +return this.node.classList.contains.apply(this.node.classList, arguments); +} +}; +}()); +(function () { +'use strict'; +var DomApi = Polymer.DomApi.ctor; +var Settings = Polymer.Settings; +var hasDomApi = Polymer.DomApi.hasDomApi; +DomApi.EffectiveNodesObserver = function (domApi) { +this.domApi = domApi; +this.node = this.domApi.node; +this._listeners = []; +}; +DomApi.EffectiveNodesObserver.prototype = { +addListener: function (callback) { +if (!this._isSetup) { +this._setup(); +this._isSetup = true; +} +var listener = { +fn: callback, +_nodes: [] +}; +this._listeners.push(listener); +this._scheduleNotify(); +return listener; +}, +removeListener: function (handle) { +var i = this._listeners.indexOf(handle); +if (i >= 0) { +this._listeners.splice(i, 1); +handle._nodes = []; +} +if (!this._hasListeners()) { +this._cleanup(); +this._isSetup = false; +} +}, +_setup: function () { +this._observeContentElements(this.domApi.childNodes); +}, +_cleanup: function () { +this._unobserveContentElements(this.domApi.childNodes); +}, +_hasListeners: function () { +return Boolean(this._listeners.length); +}, +_scheduleNotify: function () { +if (this._debouncer) { +this._debouncer.stop(); +} +this._debouncer = Polymer.Debounce(this._debouncer, this._notify); +this._debouncer.context = this; +Polymer.dom.addDebouncer(this._debouncer); +}, +notify: function () { +if (this._hasListeners()) { +this._scheduleNotify(); +} +}, +_notify: function (mxns) { +this._beforeCallListeners(); +this._callListeners(); +}, +_beforeCallListeners: function () { +this._updateContentElements(); +}, +_updateContentElements: function () { +this._observeContentElements(this.domApi.childNodes); +}, +_observeContentElements: function (elements) { +for (var i = 0, n; i < elements.length && (n = elements[i]); i++) { +if (this._isContent(n)) { +n.__observeNodesMap = n.__observeNodesMap || new WeakMap(); +if (!n.__observeNodesMap.has(this)) { +n.__observeNodesMap.set(this, this._observeContent(n)); +} +} +} +}, +_observeContent: function (content) { +var self = this; +var h = Polymer.dom(content).observeNodes(function () { +self._scheduleNotify(); +}); +h._avoidChangeCalculation = true; +return h; +}, +_unobserveContentElements: function (elements) { +for (var i = 0, n, h; i < elements.length && (n = elements[i]); i++) { +if (this._isContent(n)) { +h = n.__observeNodesMap.get(this); +if (h) { +Polymer.dom(n).unobserveNodes(h); +n.__observeNodesMap.delete(this); +} +} +} +}, +_isContent: function (node) { +return node.localName === 'content'; +}, +_callListeners: function () { +var o$ = this._listeners; +var nodes = this._getEffectiveNodes(); +for (var i = 0, o; i < o$.length && (o = o$[i]); i++) { +var info = this._generateListenerInfo(o, nodes); +if (info || o._alwaysNotify) { +this._callListener(o, info); +} +} +}, +_getEffectiveNodes: function () { +return this.domApi.getEffectiveChildNodes(); +}, +_generateListenerInfo: function (listener, newNodes) { +if (listener._avoidChangeCalculation) { +return true; +} +var oldNodes = listener._nodes; +var info = { +target: this.node, +addedNodes: [], +removedNodes: [] +}; +var splices = Polymer.ArraySplice.calculateSplices(newNodes, oldNodes); +for (var i = 0, s; i < splices.length && (s = splices[i]); i++) { +for (var j = 0, n; j < s.removed.length && (n = s.removed[j]); j++) { +info.removedNodes.push(n); +} +} +for (var i = 0, s; i < splices.length && (s = splices[i]); i++) { +for (var j = s.index; j < s.index + s.addedCount; j++) { +info.addedNodes.push(newNodes[j]); +} +} +listener._nodes = newNodes; +if (info.addedNodes.length || info.removedNodes.length) { +return info; +} +}, +_callListener: function (listener, info) { +return listener.fn.call(this.node, info); +}, +enableShadowAttributeTracking: function () { +} +}; +if (Settings.useShadow) { +var baseSetup = DomApi.EffectiveNodesObserver.prototype._setup; +var baseCleanup = DomApi.EffectiveNodesObserver.prototype._cleanup; +var beforeCallListeners = DomApi.EffectiveNodesObserver.prototype._beforeCallListeners; +Polymer.Base.extend(DomApi.EffectiveNodesObserver.prototype, { +_setup: function () { +if (!this._observer) { +var self = this; +this._mutationHandler = function (mxns) { +if (mxns && mxns.length) { +self._scheduleNotify(); +} +}; +this._observer = new MutationObserver(this._mutationHandler); +this._boundFlush = function () { +self._flush(); +}; +Polymer.dom.addStaticFlush(this._boundFlush); +this._observer.observe(this.node, { childList: true }); +} +baseSetup.call(this); +}, +_cleanup: function () { +this._observer.disconnect(); +this._observer = null; +this._mutationHandler = null; +Polymer.dom.removeStaticFlush(this._boundFlush); +baseCleanup.call(this); +}, +_flush: function () { +if (this._observer) { +this._mutationHandler(this._observer.takeRecords()); +} +}, +enableShadowAttributeTracking: function () { +if (this._observer) { +this._makeContentListenersAlwaysNotify(); +this._observer.disconnect(); +this._observer.observe(this.node, { +childList: true, +attributes: true, +subtree: true +}); +var root = this.domApi.getOwnerRoot(); +var host = root && root.host; +if (host && Polymer.dom(host).observer) { +Polymer.dom(host).observer.enableShadowAttributeTracking(); +} +} +}, +_makeContentListenersAlwaysNotify: function () { +for (var i = 0, h; i < this._listeners.length; i++) { +h = this._listeners[i]; +h._alwaysNotify = h._isContentListener; +} +} +}); +} +}()); +(function () { +'use strict'; +var DomApi = Polymer.DomApi.ctor; +var Settings = Polymer.Settings; +DomApi.DistributedNodesObserver = function (domApi) { +DomApi.EffectiveNodesObserver.call(this, domApi); +}; +DomApi.DistributedNodesObserver.prototype = Object.create(DomApi.EffectiveNodesObserver.prototype); +Polymer.Base.extend(DomApi.DistributedNodesObserver.prototype, { +_setup: function () { +}, +_cleanup: function () { +}, +_beforeCallListeners: function () { +}, +_getEffectiveNodes: function () { +return this.domApi.getDistributedNodes(); +} +}); +if (Settings.useShadow) { +Polymer.Base.extend(DomApi.DistributedNodesObserver.prototype, { +_setup: function () { +if (!this._observer) { +var root = this.domApi.getOwnerRoot(); +var host = root && root.host; +if (host) { +var self = this; +this._observer = Polymer.dom(host).observeNodes(function () { +self._scheduleNotify(); +}); +this._observer._isContentListener = true; +if (this._hasAttrSelect()) { +Polymer.dom(host).observer.enableShadowAttributeTracking(); +} +} +} +}, +_hasAttrSelect: function () { +var select = this.node.getAttribute('select'); +return select && select.match(/[[.]+/); +}, +_cleanup: function () { +var root = this.domApi.getOwnerRoot(); +var host = root && root.host; +if (host) { +Polymer.dom(host).unobserveNodes(this._observer); +} +this._observer = null; +} +}); +} +}()); +(function () { +var hasDomApi = Polymer.DomApi.hasDomApi; +Polymer.Base._addFeature({ +_prepShady: function () { +this._useContent = this._useContent || Boolean(this._template); +}, +_poolContent: function () { +if (this._useContent) { +saveLightChildrenIfNeeded(this); +} +}, +_setupRoot: function () { +if (this._useContent) { +this._createLocalRoot(); +if (!this.dataHost) { +upgradeLightChildren(this._lightChildren); +} +} +}, +_createLocalRoot: function () { +this.shadyRoot = this.root; +this.shadyRoot._distributionClean = false; +this.shadyRoot._hasDistributed = false; +this.shadyRoot._isShadyRoot = true; +this.shadyRoot._dirtyRoots = []; +var i$ = this.shadyRoot._insertionPoints = !this._notes || this._notes._hasContent ? this.shadyRoot.querySelectorAll('content') : []; +saveLightChildrenIfNeeded(this.shadyRoot); +for (var i = 0, c; i < i$.length; i++) { +c = i$[i]; +saveLightChildrenIfNeeded(c); +saveLightChildrenIfNeeded(c.parentNode); +} +this.shadyRoot.host = this; +}, +get domHost() { +var root = Polymer.dom(this).getOwnerRoot(); +return root && root.host; +}, +distributeContent: function (updateInsertionPoints) { +if (this.shadyRoot) { +var dom = Polymer.dom(this); +if (updateInsertionPoints) { +dom._updateInsertionPoints(this); +} +var host = getTopDistributingHost(this); +dom._lazyDistribute(host); +} +}, +_distributeContent: function () { +if (this._useContent && !this.shadyRoot._distributionClean) { +this._beginDistribute(); +this._distributeDirtyRoots(); +this._finishDistribute(); +} +}, +_beginDistribute: function () { +if (this._useContent && hasInsertionPoint(this.shadyRoot)) { +this._resetDistribution(); +this._distributePool(this.shadyRoot, this._collectPool()); +} +}, +_distributeDirtyRoots: function () { +var c$ = this.shadyRoot._dirtyRoots; +for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) { +c._distributeContent(); +} +this.shadyRoot._dirtyRoots = []; +}, +_finishDistribute: function () { +if (this._useContent) { +this.shadyRoot._distributionClean = true; +if (hasInsertionPoint(this.shadyRoot)) { +this._composeTree(); +notifyContentObservers(this.shadyRoot); +} else { +if (!this.shadyRoot._hasDistributed) { +this.textContent = ''; +this._composedChildren = null; +this.appendChild(this.shadyRoot); +} else { +var children = this._composeNode(this); +this._updateChildNodes(this, children); +} +} +if (!this.shadyRoot._hasDistributed) { +notifyInitialDistribution(this); +} +this.shadyRoot._hasDistributed = true; +} +}, +elementMatches: function (selector, node) { +node = node || this; +return matchesSelector.call(node, selector); +}, +_resetDistribution: function () { +var children = getLightChildren(this); +for (var i = 0; i < children.length; i++) { +var child = children[i]; +if (child._destinationInsertionPoints) { +child._destinationInsertionPoints = undefined; +} +if (isInsertionPoint(child)) { +clearDistributedDestinationInsertionPoints(child); +} +} +var root = this.shadyRoot; +var p$ = root._insertionPoints; +for (var j = 0; j < p$.length; j++) { +p$[j]._distributedNodes = []; +} +}, +_collectPool: function () { +var pool = []; +var children = getLightChildren(this); +for (var i = 0; i < children.length; i++) { +var child = children[i]; +if (isInsertionPoint(child)) { +pool.push.apply(pool, child._distributedNodes); +} else { +pool.push(child); +} +} +return pool; +}, +_distributePool: function (node, pool) { +var p$ = node._insertionPoints; +for (var i = 0, l = p$.length, p; i < l && (p = p$[i]); i++) { +this._distributeInsertionPoint(p, pool); +maybeRedistributeParent(p, this); +} +}, +_distributeInsertionPoint: function (content, pool) { +var anyDistributed = false; +for (var i = 0, l = pool.length, node; i < l; i++) { +node = pool[i]; +if (!node) { +continue; +} +if (this._matchesContentSelect(node, content)) { +distributeNodeInto(node, content); +pool[i] = undefined; +anyDistributed = true; +} +} +if (!anyDistributed) { +var children = getLightChildren(content); +for (var j = 0; j < children.length; j++) { +distributeNodeInto(children[j], content); +} +} +}, +_composeTree: function () { +this._updateChildNodes(this, this._composeNode(this)); +var p$ = this.shadyRoot._insertionPoints; +for (var i = 0, l = p$.length, p, parent; i < l && (p = p$[i]); i++) { +parent = p._lightParent || p.parentNode; +if (!parent._useContent && parent !== this && parent !== this.shadyRoot) { +this._updateChildNodes(parent, this._composeNode(parent)); +} +} +}, +_composeNode: function (node) { +var children = []; +var c$ = getLightChildren(node.shadyRoot || node); +for (var i = 0; i < c$.length; i++) { +var child = c$[i]; +if (isInsertionPoint(child)) { +var distributedNodes = child._distributedNodes; +for (var j = 0; j < distributedNodes.length; j++) { +var distributedNode = distributedNodes[j]; +if (isFinalDestination(child, distributedNode)) { +children.push(distributedNode); +} +} +} else { +children.push(child); +} +} +return children; +}, +_updateChildNodes: function (container, children) { +var composed = getComposedChildren(container); +var splices = Polymer.ArraySplice.calculateSplices(children, composed); +for (var i = 0, d = 0, s; i < splices.length && (s = splices[i]); i++) { +for (var j = 0, n; j < s.removed.length && (n = s.removed[j]); j++) { +if (getComposedParent(n) === container) { +remove(n); +} +composed.splice(s.index + d, 1); +} +d -= s.addedCount; +} +for (var i = 0, s, next; i < splices.length && (s = splices[i]); i++) { +next = composed[s.index]; +for (var j = s.index, n; j < s.index + s.addedCount; j++) { +n = children[j]; +insertBefore(container, n, next); +composed.splice(j, 0, n); +} +} +ensureComposedParent(container, children); +}, +_matchesContentSelect: function (node, contentElement) { +var select = contentElement.getAttribute('select'); +if (!select) { +return true; +} +select = select.trim(); +if (!select) { +return true; +} +if (!(node instanceof Element)) { +return false; +} +var validSelectors = /^(:not\()?[*.#[a-zA-Z_|]/; +if (!validSelectors.test(select)) { +return false; +} +return this.elementMatches(select, node); +}, +_elementAdd: function () { +}, +_elementRemove: function () { +} +}); +var saveLightChildrenIfNeeded = Polymer.DomApi.saveLightChildrenIfNeeded; +var getLightChildren = Polymer.DomApi.getLightChildren; +var matchesSelector = Polymer.DomApi.matchesSelector; +var hasInsertionPoint = Polymer.DomApi.hasInsertionPoint; +var getComposedChildren = Polymer.DomApi.getComposedChildren; +var getComposedParent = Polymer.DomApi.getComposedParent; +var removeFromComposedParent = Polymer.DomApi.removeFromComposedParent; +function distributeNodeInto(child, insertionPoint) { +insertionPoint._distributedNodes.push(child); +var points = child._destinationInsertionPoints; +if (!points) { +child._destinationInsertionPoints = [insertionPoint]; +} else { +points.push(insertionPoint); +} +} +function clearDistributedDestinationInsertionPoints(content) { +var e$ = content._distributedNodes; +if (e$) { +for (var i = 0; i < e$.length; i++) { +var d = e$[i]._destinationInsertionPoints; +if (d) { +d.splice(d.indexOf(content) + 1, d.length); +} +} +} +} +function maybeRedistributeParent(content, host) { +var parent = content._lightParent; +if (parent && parent.shadyRoot && hasInsertionPoint(parent.shadyRoot) && parent.shadyRoot._distributionClean) { +parent.shadyRoot._distributionClean = false; +host.shadyRoot._dirtyRoots.push(parent); +} +} +function isFinalDestination(insertionPoint, node) { +var points = node._destinationInsertionPoints; +return points && points[points.length - 1] === insertionPoint; +} +function isInsertionPoint(node) { +return node.localName == 'content'; +} +var nativeInsertBefore = Element.prototype.insertBefore; +var nativeRemoveChild = Element.prototype.removeChild; +function insertBefore(parentNode, newChild, refChild) { +var newChildParent = getComposedParent(newChild); +if (newChildParent !== parentNode) { +removeFromComposedParent(newChildParent, newChild); +} +remove(newChild); +nativeInsertBefore.call(parentNode, newChild, refChild || null); +newChild._composedParent = parentNode; +} +function remove(node) { +var parentNode = getComposedParent(node); +if (parentNode) { +node._composedParent = null; +nativeRemoveChild.call(parentNode, node); +} +} +function ensureComposedParent(parent, children) { +for (var i = 0, n; i < children.length; i++) { +children[i]._composedParent = parent; +} +} +function getTopDistributingHost(host) { +while (host && hostNeedsRedistribution(host)) { +host = host.domHost; +} +return host; +} +function hostNeedsRedistribution(host) { +var c$ = Polymer.dom(host).children; +for (var i = 0, c; i < c$.length; i++) { +c = c$[i]; +if (c.localName === 'content') { +return host.domHost; +} +} +} +function notifyContentObservers(root) { +for (var i = 0, c; i < root._insertionPoints.length; i++) { +c = root._insertionPoints[i]; +if (hasDomApi(c)) { +Polymer.dom(c).notifyObserver(); +} +} +} +function notifyInitialDistribution(host) { +if (hasDomApi(host)) { +Polymer.dom(host).notifyObserver(); +} +} +var needsUpgrade = window.CustomElements && !CustomElements.useNative; +function upgradeLightChildren(children) { +if (needsUpgrade && children) { +for (var i = 0; i < children.length; i++) { +CustomElements.upgrade(children[i]); +} +} +} +}()); +if (Polymer.Settings.useShadow) { +Polymer.Base._addFeature({ +_poolContent: function () { +}, +_beginDistribute: function () { +}, +distributeContent: function () { +}, +_distributeContent: function () { +}, +_finishDistribute: function () { +}, +_createLocalRoot: function () { +this.createShadowRoot(); +this.shadowRoot.appendChild(this.root); +this.root = this.shadowRoot; +} +}); +} +Polymer.DomModule = document.createElement('dom-module'); +Polymer.Base._addFeature({ +_registerFeatures: function () { +this._prepIs(); +this._prepBehaviors(); +this._prepConstructor(); +this._prepTemplate(); +this._prepShady(); +this._prepPropertyInfo(); +}, +_prepBehavior: function (b) { +this._addHostAttributes(b.hostAttributes); +}, +_initFeatures: function () { +this._registerHost(); +if (this._template) { +this._poolContent(); +this._beginHosting(); +this._stampTemplate(); +this._endHosting(); +} +this._marshalHostAttributes(); +this._setupDebouncers(); +this._marshalBehaviors(); +this._tryReady(); +}, +_marshalBehavior: function (b) { +} +});</script><script>Polymer.nar = []; +Polymer.Annotations = { +parseAnnotations: function (template) { +var list = []; +var content = template._content || template.content; +this._parseNodeAnnotations(content, list, template.hasAttribute('strip-whitespace')); +return list; +}, +_parseNodeAnnotations: function (node, list, stripWhiteSpace) { +return node.nodeType === Node.TEXT_NODE ? this._parseTextNodeAnnotation(node, list) : this._parseElementAnnotations(node, list, stripWhiteSpace); +}, +_bindingRegex: /([^{[]*)(\{\{|\[\[)(?!\}\}|\]\])(.+?)(?:\]\]|\}\})/g, +_parseBindings: function (text) { +var re = this._bindingRegex; +var parts = []; +var m, lastIndex; +while ((m = re.exec(text)) !== null) { +if (m[1]) { +parts.push({ literal: m[1] }); +} +var mode = m[2][0]; +var value = m[3].trim(); +var negate = false; +if (value[0] == '!') { +negate = true; +value = value.substring(1).trim(); +} +var customEvent, notifyEvent, colon; +if (mode == '{' && (colon = value.indexOf('::')) > 0) { +notifyEvent = value.substring(colon + 2); +value = value.substring(0, colon); +customEvent = true; +} +parts.push({ +compoundIndex: parts.length, +value: value, +mode: mode, +negate: negate, +event: notifyEvent, +customEvent: customEvent +}); +lastIndex = re.lastIndex; +} +if (lastIndex && lastIndex < text.length) { +var literal = text.substring(lastIndex); +if (literal) { +parts.push({ literal: literal }); +} +} +if (parts.length) { +return parts; +} +}, +_literalFromParts: function (parts) { +var s = ''; +for (var i = 0; i < parts.length; i++) { +var literal = parts[i].literal; +s += literal || ''; +} +return s; +}, +_parseTextNodeAnnotation: function (node, list) { +var parts = this._parseBindings(node.textContent); +if (parts) { +node.textContent = this._literalFromParts(parts) || ' '; +var annote = { +bindings: [{ +kind: 'text', +name: 'textContent', +parts: parts, +isCompound: parts.length !== 1 +}] +}; +list.push(annote); +return annote; +} +}, +_parseElementAnnotations: function (element, list, stripWhiteSpace) { +var annote = { +bindings: [], +events: [] +}; +if (element.localName === 'content') { +list._hasContent = true; +} +this._parseChildNodesAnnotations(element, annote, list, stripWhiteSpace); +if (element.attributes) { +this._parseNodeAttributeAnnotations(element, annote, list); +if (this.prepElement) { +this.prepElement(element); +} +} +if (annote.bindings.length || annote.events.length || annote.id) { +list.push(annote); +} +return annote; +}, +_parseChildNodesAnnotations: function (root, annote, list, stripWhiteSpace) { +if (root.firstChild) { +var node = root.firstChild; +var i = 0; +while (node) { +var next = node.nextSibling; +if (node.localName === 'template' && !node.hasAttribute('preserve-content')) { +this._parseTemplate(node, i, list, annote); +} +if (node.nodeType === Node.TEXT_NODE) { +var n = next; +while (n && n.nodeType === Node.TEXT_NODE) { +node.textContent += n.textContent; +next = n.nextSibling; +root.removeChild(n); +n = next; +} +if (stripWhiteSpace && !node.textContent.trim()) { +root.removeChild(node); +i--; +} +} +if (node.parentNode) { +var childAnnotation = this._parseNodeAnnotations(node, list, stripWhiteSpace); +if (childAnnotation) { +childAnnotation.parent = annote; +childAnnotation.index = i; +} +} +node = next; +i++; +} +} +}, +_parseTemplate: function (node, index, list, parent) { +var content = document.createDocumentFragment(); +content._notes = this.parseAnnotations(node); +content.appendChild(node.content); +list.push({ +bindings: Polymer.nar, +events: Polymer.nar, +templateContent: content, +parent: parent, +index: index +}); +}, +_parseNodeAttributeAnnotations: function (node, annotation) { +var attrs = Array.prototype.slice.call(node.attributes); +for (var i = attrs.length - 1, a; a = attrs[i]; i--) { +var n = a.name; +var v = a.value; +var b; +if (n.slice(0, 3) === 'on-') { +node.removeAttribute(n); +annotation.events.push({ +name: n.slice(3), +value: v +}); +} else if (b = this._parseNodeAttributeAnnotation(node, n, v)) { +annotation.bindings.push(b); +} else if (n === 'id') { +annotation.id = v; +} +} +}, +_parseNodeAttributeAnnotation: function (node, name, value) { +var parts = this._parseBindings(value); +if (parts) { +var origName = name; +var kind = 'property'; +if (name[name.length - 1] == '$') { +name = name.slice(0, -1); +kind = 'attribute'; +} +var literal = this._literalFromParts(parts); +if (literal && kind == 'attribute') { +node.setAttribute(name, literal); +} +if (node.localName == 'input' && name == 'value') { +node.setAttribute(origName, ''); +} +node.removeAttribute(origName); +if (kind === 'property') { +name = Polymer.CaseMap.dashToCamelCase(name); +} +return { +kind: kind, +name: name, +parts: parts, +literal: literal, +isCompound: parts.length !== 1 +}; +} +}, +_localSubTree: function (node, host) { +return node === host ? node.childNodes : node._lightChildren || node.childNodes; +}, +findAnnotatedNode: function (root, annote) { +var parent = annote.parent && Polymer.Annotations.findAnnotatedNode(root, annote.parent); +return !parent ? root : Polymer.Annotations._localSubTree(parent, root)[annote.index]; +} +}; +(function () { +function resolveCss(cssText, ownerDocument) { +return cssText.replace(CSS_URL_RX, function (m, pre, url, post) { +return pre + '\'' + resolve(url.replace(/["']/g, ''), ownerDocument) + '\'' + post; +}); +} +function resolveAttrs(element, ownerDocument) { +for (var name in URL_ATTRS) { +var a$ = URL_ATTRS[name]; +for (var i = 0, l = a$.length, a, at, v; i < l && (a = a$[i]); i++) { +if (name === '*' || element.localName === name) { +at = element.attributes[a]; +v = at && at.value; +if (v && v.search(BINDING_RX) < 0) { +at.value = a === 'style' ? resolveCss(v, ownerDocument) : resolve(v, ownerDocument); +} +} +} +} +} +function resolve(url, ownerDocument) { +if (url && url[0] === '#') { +return url; +} +var resolver = getUrlResolver(ownerDocument); +resolver.href = url; +return resolver.href || url; +} +var tempDoc; +var tempDocBase; +function resolveUrl(url, baseUri) { +if (!tempDoc) { +tempDoc = document.implementation.createHTMLDocument('temp'); +tempDocBase = tempDoc.createElement('base'); +tempDoc.head.appendChild(tempDocBase); +} +tempDocBase.href = baseUri; +return resolve(url, tempDoc); +} +function getUrlResolver(ownerDocument) { +return ownerDocument.__urlResolver || (ownerDocument.__urlResolver = ownerDocument.createElement('a')); +} +var CSS_URL_RX = /(url\()([^)]*)(\))/g; +var URL_ATTRS = { +'*': [ +'href', +'src', +'style', +'url' +], +form: ['action'] +}; +var BINDING_RX = /\{\{|\[\[/; +Polymer.ResolveUrl = { +resolveCss: resolveCss, +resolveAttrs: resolveAttrs, +resolveUrl: resolveUrl +}; +}()); +Polymer.Base._addFeature({ +_prepAnnotations: function () { +if (!this._template) { +this._notes = []; +} else { +var self = this; +Polymer.Annotations.prepElement = function (element) { +self._prepElement(element); +}; +if (this._template._content && this._template._content._notes) { +this._notes = this._template._content._notes; +} else { +this._notes = Polymer.Annotations.parseAnnotations(this._template); +} +this._processAnnotations(this._notes); +Polymer.Annotations.prepElement = null; +} +}, +_processAnnotations: function (notes) { +for (var i = 0; i < notes.length; i++) { +var note = notes[i]; +for (var j = 0; j < note.bindings.length; j++) { +var b = note.bindings[j]; +for (var k = 0; k < b.parts.length; k++) { +var p = b.parts[k]; +if (!p.literal) { +p.signature = this._parseMethod(p.value); +if (!p.signature) { +p.model = this._modelForPath(p.value); +} +} +} +} +if (note.templateContent) { +this._processAnnotations(note.templateContent._notes); +var pp = note.templateContent._parentProps = this._discoverTemplateParentProps(note.templateContent._notes); +var bindings = []; +for (var prop in pp) { +bindings.push({ +index: note.index, +kind: 'property', +name: '_parent_' + prop, +parts: [{ +mode: '{', +model: prop, +value: prop +}] +}); +} +note.bindings = note.bindings.concat(bindings); +} +} +}, +_discoverTemplateParentProps: function (notes) { +var pp = {}; +for (var i = 0, n; i < notes.length && (n = notes[i]); i++) { +for (var j = 0, b$ = n.bindings, b; j < b$.length && (b = b$[j]); j++) { +for (var k = 0, p$ = b.parts, p; k < p$.length && (p = p$[k]); k++) { +if (p.signature) { +var args = p.signature.args; +for (var kk = 0; kk < args.length; kk++) { +pp[args[kk].model] = true; +} +} else { +pp[p.model] = true; +} +} +} +if (n.templateContent) { +var tpp = n.templateContent._parentProps; +Polymer.Base.mixin(pp, tpp); +} +} +return pp; +}, +_prepElement: function (element) { +Polymer.ResolveUrl.resolveAttrs(element, this._template.ownerDocument); +}, +_findAnnotatedNode: Polymer.Annotations.findAnnotatedNode, +_marshalAnnotationReferences: function () { +if (this._template) { +this._marshalIdNodes(); +this._marshalAnnotatedNodes(); +this._marshalAnnotatedListeners(); +} +}, +_configureAnnotationReferences: function (config) { +var notes = this._notes; +var nodes = this._nodes; +for (var i = 0; i < notes.length; i++) { +var note = notes[i]; +var node = nodes[i]; +this._configureTemplateContent(note, node); +this._configureCompoundBindings(note, node); +} +}, +_configureTemplateContent: function (note, node) { +if (note.templateContent) { +node._content = note.templateContent; +} +}, +_configureCompoundBindings: function (note, node) { +var bindings = note.bindings; +for (var i = 0; i < bindings.length; i++) { +var binding = bindings[i]; +if (binding.isCompound) { +var storage = node.__compoundStorage__ || (node.__compoundStorage__ = {}); +var parts = binding.parts; +var literals = new Array(parts.length); +for (var j = 0; j < parts.length; j++) { +literals[j] = parts[j].literal; +} +var name = binding.name; +storage[name] = literals; +if (binding.literal && binding.kind == 'property') { +if (node._configValue) { +node._configValue(name, binding.literal); +} else { +node[name] = binding.literal; +} +} +} +} +}, +_marshalIdNodes: function () { +this.$ = {}; +for (var i = 0, l = this._notes.length, a; i < l && (a = this._notes[i]); i++) { +if (a.id) { +this.$[a.id] = this._findAnnotatedNode(this.root, a); +} +} +}, +_marshalAnnotatedNodes: function () { +if (this._notes && this._notes.length) { +var r = new Array(this._notes.length); +for (var i = 0; i < this._notes.length; i++) { +r[i] = this._findAnnotatedNode(this.root, this._notes[i]); +} +this._nodes = r; +} +}, +_marshalAnnotatedListeners: function () { +for (var i = 0, l = this._notes.length, a; i < l && (a = this._notes[i]); i++) { +if (a.events && a.events.length) { +var node = this._findAnnotatedNode(this.root, a); +for (var j = 0, e$ = a.events, e; j < e$.length && (e = e$[j]); j++) { +this.listen(node, e.name, e.value); +} +} +} +} +}); +Polymer.Base._addFeature({ +listeners: {}, +_listenListeners: function (listeners) { +var node, name, eventName; +for (eventName in listeners) { +if (eventName.indexOf('.') < 0) { +node = this; +name = eventName; +} else { +name = eventName.split('.'); +node = this.$[name[0]]; +name = name[1]; +} +this.listen(node, name, listeners[eventName]); +} +}, +listen: function (node, eventName, methodName) { +var handler = this._recallEventHandler(this, eventName, node, methodName); +if (!handler) { +handler = this._createEventHandler(node, eventName, methodName); +} +if (handler._listening) { +return; +} +this._listen(node, eventName, handler); +handler._listening = true; +}, +_boundListenerKey: function (eventName, methodName) { +return eventName + ':' + methodName; +}, +_recordEventHandler: function (host, eventName, target, methodName, handler) { +var hbl = host.__boundListeners; +if (!hbl) { +hbl = host.__boundListeners = new WeakMap(); +} +var bl = hbl.get(target); +if (!bl) { +bl = {}; +hbl.set(target, bl); +} +var key = this._boundListenerKey(eventName, methodName); +bl[key] = handler; +}, +_recallEventHandler: function (host, eventName, target, methodName) { +var hbl = host.__boundListeners; +if (!hbl) { +return; +} +var bl = hbl.get(target); +if (!bl) { +return; +} +var key = this._boundListenerKey(eventName, methodName); +return bl[key]; +}, +_createEventHandler: function (node, eventName, methodName) { +var host = this; +var handler = function (e) { +if (host[methodName]) { +host[methodName](e, e.detail); +} else { +host._warn(host._logf('_createEventHandler', 'listener method `' + methodName + '` not defined')); +} +}; +handler._listening = false; +this._recordEventHandler(host, eventName, node, methodName, handler); +return handler; +}, +unlisten: function (node, eventName, methodName) { +var handler = this._recallEventHandler(this, eventName, node, methodName); +if (handler) { +this._unlisten(node, eventName, handler); +handler._listening = false; +} +}, +_listen: function (node, eventName, handler) { +node.addEventListener(eventName, handler); +}, +_unlisten: function (node, eventName, handler) { +node.removeEventListener(eventName, handler); +} +}); +(function () { +'use strict'; +var wrap = Polymer.DomApi.wrap; +var HAS_NATIVE_TA = typeof document.head.style.touchAction === 'string'; +var GESTURE_KEY = '__polymerGestures'; +var HANDLED_OBJ = '__polymerGesturesHandled'; +var TOUCH_ACTION = '__polymerGesturesTouchAction'; +var TAP_DISTANCE = 25; +var TRACK_DISTANCE = 5; +var TRACK_LENGTH = 2; +var MOUSE_TIMEOUT = 2500; +var MOUSE_EVENTS = [ +'mousedown', +'mousemove', +'mouseup', +'click' +]; +var MOUSE_WHICH_TO_BUTTONS = [ +0, +1, +4, +2 +]; +var MOUSE_HAS_BUTTONS = function () { +try { +return new MouseEvent('test', { buttons: 1 }).buttons === 1; +} catch (e) { +return false; +} +}(); +var IS_TOUCH_ONLY = navigator.userAgent.match(/iP(?:[oa]d|hone)|Android/); +var mouseCanceller = function (mouseEvent) { +mouseEvent[HANDLED_OBJ] = { skip: true }; +if (mouseEvent.type === 'click') { +var path = Polymer.dom(mouseEvent).path; +for (var i = 0; i < path.length; i++) { +if (path[i] === POINTERSTATE.mouse.target) { +return; +} +} +mouseEvent.preventDefault(); +mouseEvent.stopPropagation(); +} +}; +function setupTeardownMouseCanceller(setup) { +for (var i = 0, en; i < MOUSE_EVENTS.length; i++) { +en = MOUSE_EVENTS[i]; +if (setup) { +document.addEventListener(en, mouseCanceller, true); +} else { +document.removeEventListener(en, mouseCanceller, true); +} +} +} +function ignoreMouse() { +if (IS_TOUCH_ONLY) { +return; +} +if (!POINTERSTATE.mouse.mouseIgnoreJob) { +setupTeardownMouseCanceller(true); +} +var unset = function () { +setupTeardownMouseCanceller(); +POINTERSTATE.mouse.target = null; +POINTERSTATE.mouse.mouseIgnoreJob = null; +}; +POINTERSTATE.mouse.mouseIgnoreJob = Polymer.Debounce(POINTERSTATE.mouse.mouseIgnoreJob, unset, MOUSE_TIMEOUT); +} +function hasLeftMouseButton(ev) { +var type = ev.type; +if (MOUSE_EVENTS.indexOf(type) === -1) { +return false; +} +if (type === 'mousemove') { +var buttons = ev.buttons === undefined ? 1 : ev.buttons; +if (ev instanceof window.MouseEvent && !MOUSE_HAS_BUTTONS) { +buttons = MOUSE_WHICH_TO_BUTTONS[ev.which] || 0; +} +return Boolean(buttons & 1); +} else { +var button = ev.button === undefined ? 0 : ev.button; +return button === 0; +} +} +function isSyntheticClick(ev) { +if (ev.type === 'click') { +if (ev.detail === 0) { +return true; +} +var t = Gestures.findOriginalTarget(ev); +var bcr = t.getBoundingClientRect(); +var x = ev.pageX, y = ev.pageY; +return !(x >= bcr.left && x <= bcr.right && (y >= bcr.top && y <= bcr.bottom)); +} +return false; +} +var POINTERSTATE = { +mouse: { +target: null, +mouseIgnoreJob: null +}, +touch: { +x: 0, +y: 0, +id: -1, +scrollDecided: false +} +}; +function firstTouchAction(ev) { +var path = Polymer.dom(ev).path; +var ta = 'auto'; +for (var i = 0, n; i < path.length; i++) { +n = path[i]; +if (n[TOUCH_ACTION]) { +ta = n[TOUCH_ACTION]; +break; +} +} +return ta; +} +function trackDocument(stateObj, movefn, upfn) { +stateObj.movefn = movefn; +stateObj.upfn = upfn; +document.addEventListener('mousemove', movefn); +document.addEventListener('mouseup', upfn); +} +function untrackDocument(stateObj) { +document.removeEventListener('mousemove', stateObj.movefn); +document.removeEventListener('mouseup', stateObj.upfn); +} +var Gestures = { +gestures: {}, +recognizers: [], +deepTargetFind: function (x, y) { +var node = document.elementFromPoint(x, y); +var next = node; +while (next && next.shadowRoot) { +next = next.shadowRoot.elementFromPoint(x, y); +if (next) { +node = next; +} +} +return node; +}, +findOriginalTarget: function (ev) { +if (ev.path) { +return ev.path[0]; +} +return ev.target; +}, +handleNative: function (ev) { +var handled; +var type = ev.type; +var node = wrap(ev.currentTarget); +var gobj = node[GESTURE_KEY]; +if (!gobj) { +return; +} +var gs = gobj[type]; +if (!gs) { +return; +} +if (!ev[HANDLED_OBJ]) { +ev[HANDLED_OBJ] = {}; +if (type.slice(0, 5) === 'touch') { +var t = ev.changedTouches[0]; +if (type === 'touchstart') { +if (ev.touches.length === 1) { +POINTERSTATE.touch.id = t.identifier; +} +} +if (POINTERSTATE.touch.id !== t.identifier) { +return; +} +if (!HAS_NATIVE_TA) { +if (type === 'touchstart' || type === 'touchmove') { +Gestures.handleTouchAction(ev); +} +} +if (type === 'touchend') { +POINTERSTATE.mouse.target = Polymer.dom(ev).rootTarget; +ignoreMouse(true); +} +} +} +handled = ev[HANDLED_OBJ]; +if (handled.skip) { +return; +} +var recognizers = Gestures.recognizers; +for (var i = 0, r; i < recognizers.length; i++) { +r = recognizers[i]; +if (gs[r.name] && !handled[r.name]) { +if (r.flow && r.flow.start.indexOf(ev.type) > -1) { +if (r.reset) { +r.reset(); +} +} +} +} +for (var i = 0, r; i < recognizers.length; i++) { +r = recognizers[i]; +if (gs[r.name] && !handled[r.name]) { +handled[r.name] = true; +r[type](ev); +} +} +}, +handleTouchAction: function (ev) { +var t = ev.changedTouches[0]; +var type = ev.type; +if (type === 'touchstart') { +POINTERSTATE.touch.x = t.clientX; +POINTERSTATE.touch.y = t.clientY; +POINTERSTATE.touch.scrollDecided = false; +} else if (type === 'touchmove') { +if (POINTERSTATE.touch.scrollDecided) { +return; +} +POINTERSTATE.touch.scrollDecided = true; +var ta = firstTouchAction(ev); +var prevent = false; +var dx = Math.abs(POINTERSTATE.touch.x - t.clientX); +var dy = Math.abs(POINTERSTATE.touch.y - t.clientY); +if (!ev.cancelable) { +} else if (ta === 'none') { +prevent = true; +} else if (ta === 'pan-x') { +prevent = dy > dx; +} else if (ta === 'pan-y') { +prevent = dx > dy; +} +if (prevent) { +ev.preventDefault(); +} else { +Gestures.prevent('track'); +} +} +}, +add: function (node, evType, handler) { +node = wrap(node); +var recognizer = this.gestures[evType]; +var deps = recognizer.deps; +var name = recognizer.name; +var gobj = node[GESTURE_KEY]; +if (!gobj) { +node[GESTURE_KEY] = gobj = {}; +} +for (var i = 0, dep, gd; i < deps.length; i++) { +dep = deps[i]; +if (IS_TOUCH_ONLY && MOUSE_EVENTS.indexOf(dep) > -1) { +continue; +} +gd = gobj[dep]; +if (!gd) { +gobj[dep] = gd = { _count: 0 }; +} +if (gd._count === 0) { +node.addEventListener(dep, this.handleNative); +} +gd[name] = (gd[name] || 0) + 1; +gd._count = (gd._count || 0) + 1; +} +node.addEventListener(evType, handler); +if (recognizer.touchAction) { +this.setTouchAction(node, recognizer.touchAction); +} +}, +remove: function (node, evType, handler) { +node = wrap(node); +var recognizer = this.gestures[evType]; +var deps = recognizer.deps; +var name = recognizer.name; +var gobj = node[GESTURE_KEY]; +if (gobj) { +for (var i = 0, dep, gd; i < deps.length; i++) { +dep = deps[i]; +gd = gobj[dep]; +if (gd && gd[name]) { +gd[name] = (gd[name] || 1) - 1; +gd._count = (gd._count || 1) - 1; +if (gd._count === 0) { +node.removeEventListener(dep, this.handleNative); +} +} +} +} +node.removeEventListener(evType, handler); +}, +register: function (recog) { +this.recognizers.push(recog); +for (var i = 0; i < recog.emits.length; i++) { +this.gestures[recog.emits[i]] = recog; +} +}, +findRecognizerByEvent: function (evName) { +for (var i = 0, r; i < this.recognizers.length; i++) { +r = this.recognizers[i]; +for (var j = 0, n; j < r.emits.length; j++) { +n = r.emits[j]; +if (n === evName) { +return r; +} +} +} +return null; +}, +setTouchAction: function (node, value) { +if (HAS_NATIVE_TA) { +node.style.touchAction = value; +} +node[TOUCH_ACTION] = value; +}, +fire: function (target, type, detail) { +var ev = Polymer.Base.fire(type, detail, { +node: target, +bubbles: true, +cancelable: true +}); +if (ev.defaultPrevented) { +var se = detail.sourceEvent; +if (se && se.preventDefault) { +se.preventDefault(); +} +} +}, +prevent: function (evName) { +var recognizer = this.findRecognizerByEvent(evName); +if (recognizer.info) { +recognizer.info.prevent = true; +} +} +}; +Gestures.register({ +name: 'downup', +deps: [ +'mousedown', +'touchstart', +'touchend' +], +flow: { +start: [ +'mousedown', +'touchstart' +], +end: [ +'mouseup', +'touchend' +] +}, +emits: [ +'down', +'up' +], +info: { +movefn: function () { +}, +upfn: function () { +} +}, +reset: function () { +untrackDocument(this.info); +}, +mousedown: function (e) { +if (!hasLeftMouseButton(e)) { +return; +} +var t = Gestures.findOriginalTarget(e); +var self = this; +var movefn = function movefn(e) { +if (!hasLeftMouseButton(e)) { +self.fire('up', t, e); +untrackDocument(self.info); +} +}; +var upfn = function upfn(e) { +if (hasLeftMouseButton(e)) { +self.fire('up', t, e); +} +untrackDocument(self.info); +}; +trackDocument(this.info, movefn, upfn); +this.fire('down', t, e); +}, +touchstart: function (e) { +this.fire('down', Gestures.findOriginalTarget(e), e.changedTouches[0]); +}, +touchend: function (e) { +this.fire('up', Gestures.findOriginalTarget(e), e.changedTouches[0]); +}, +fire: function (type, target, event) { +var self = this; +Gestures.fire(target, type, { +x: event.clientX, +y: event.clientY, +sourceEvent: event, +prevent: function (e) { +return Gestures.prevent(e); +} +}); +} +}); +Gestures.register({ +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: false, +moves: [], +addMove: function (move) { +if (this.moves.length > TRACK_LENGTH) { +this.moves.shift(); +} +this.moves.push(move); +}, +movefn: function () { +}, +upfn: function () { +}, +prevent: false +}, +reset: function () { +this.info.state = 'start'; +this.info.started = false; +this.info.moves = []; +this.info.x = 0; +this.info.y = 0; +this.info.prevent = false; +untrackDocument(this.info); +}, +hasMovedEnough: function (x, y) { +if (this.info.prevent) { +return false; +} +if (this.info.started) { +return true; +} +var dx = Math.abs(this.info.x - x); +var dy = Math.abs(this.info.y - y); +return dx >= TRACK_DISTANCE || dy >= TRACK_DISTANCE; +}, +mousedown: function (e) { +if (!hasLeftMouseButton(e)) { +return; +} +var t = Gestures.findOriginalTarget(e); +var self = this; +var movefn = function movefn(e) { +var x = e.clientX, y = e.clientY; +if (self.hasMovedEnough(x, y)) { +self.info.state = self.info.started ? e.type === 'mouseup' ? 'end' : 'track' : 'start'; +self.info.addMove({ +x: x, +y: y +}); +if (!hasLeftMouseButton(e)) { +self.info.state = 'end'; +untrackDocument(self.info); +} +self.fire(t, e); +self.info.started = true; +} +}; +var upfn = function upfn(e) { +if (self.info.started) { +Gestures.prevent('tap'); +movefn(e); +} +untrackDocument(self.info); +}; +trackDocument(this.info, movefn, upfn); +this.info.x = e.clientX; +this.info.y = e.clientY; +}, +touchstart: function (e) { +var ct = e.changedTouches[0]; +this.info.x = ct.clientX; +this.info.y = ct.clientY; +}, +touchmove: function (e) { +var t = Gestures.findOriginalTarget(e); +var ct = e.changedTouches[0]; +var x = ct.clientX, y = ct.clientY; +if (this.hasMovedEnough(x, y)) { +this.info.addMove({ +x: x, +y: y +}); +this.fire(t, ct); +this.info.state = 'track'; +this.info.started = true; +} +}, +touchend: function (e) { +var t = Gestures.findOriginalTarget(e); +var ct = e.changedTouches[0]; +if (this.info.started) { +Gestures.prevent('tap'); +this.info.state = 'end'; +this.info.addMove({ +x: ct.clientX, +y: ct.clientY +}); +this.fire(t, ct); +} +}, +fire: function (target, touch) { +var secondlast = this.info.moves[this.info.moves.length - 2]; +var lastmove = this.info.moves[this.info.moves.length - 1]; +var dx = lastmove.x - this.info.x; +var dy = lastmove.y - this.info.y; +var ddx, ddy = 0; +if (secondlast) { +ddx = lastmove.x - secondlast.x; +ddy = lastmove.y - secondlast.y; +} +return Gestures.fire(target, 'track', { +state: this.info.state, +x: touch.clientX, +y: touch.clientY, +dx: dx, +dy: dy, +ddx: ddx, +ddy: ddy, +sourceEvent: touch, +hover: function () { +return Gestures.deepTargetFind(touch.clientX, touch.clientY); +} +}); +} +}); +Gestures.register({ +name: 'tap', +deps: [ +'mousedown', +'click', +'touchstart', +'touchend' +], +flow: { +start: [ +'mousedown', +'touchstart' +], +end: [ +'click', +'touchend' +] +}, +emits: ['tap'], +info: { +x: NaN, +y: NaN, +prevent: false +}, +reset: function () { +this.info.x = NaN; +this.info.y = NaN; +this.info.prevent = false; +}, +save: function (e) { +this.info.x = e.clientX; +this.info.y = e.clientY; +}, +mousedown: function (e) { +if (hasLeftMouseButton(e)) { +this.save(e); +} +}, +click: function (e) { +if (hasLeftMouseButton(e)) { +this.forward(e); +} +}, +touchstart: function (e) { +this.save(e.changedTouches[0]); +}, +touchend: function (e) { +this.forward(e.changedTouches[0]); +}, +forward: function (e) { +var dx = Math.abs(e.clientX - this.info.x); +var dy = Math.abs(e.clientY - this.info.y); +var t = Gestures.findOriginalTarget(e); +if (isNaN(dx) || isNaN(dy) || dx <= TAP_DISTANCE && dy <= TAP_DISTANCE || isSyntheticClick(e)) { +if (!this.info.prevent) { +Gestures.fire(t, 'tap', { +x: e.clientX, +y: e.clientY, +sourceEvent: e +}); +} +} +} +}); +var DIRECTION_MAP = { +x: 'pan-x', +y: 'pan-y', +none: 'none', +all: 'auto' +}; +Polymer.Base._addFeature({ +_listen: function (node, eventName, handler) { +if (Gestures.gestures[eventName]) { +Gestures.add(node, eventName, handler); +} else { +node.addEventListener(eventName, handler); +} +}, +_unlisten: function (node, eventName, handler) { +if (Gestures.gestures[eventName]) { +Gestures.remove(node, eventName, handler); +} else { +node.removeEventListener(eventName, handler); +} +}, +setScrollDirection: function (direction, node) { +node = node || this; +Gestures.setTouchAction(node, DIRECTION_MAP[direction] || 'auto'); +} +}); +Polymer.Gestures = Gestures; +}()); +Polymer.Async = { +_currVal: 0, +_lastVal: 0, +_callbacks: [], +_twiddleContent: 0, +_twiddle: document.createTextNode(''), +run: function (callback, waitTime) { +if (waitTime > 0) { +return ~setTimeout(callback, waitTime); +} else { +this._twiddle.textContent = this._twiddleContent++; +this._callbacks.push(callback); +return this._currVal++; +} +}, +cancel: function (handle) { +if (handle < 0) { +clearTimeout(~handle); +} else { +var idx = handle - this._lastVal; +if (idx >= 0) { +if (!this._callbacks[idx]) { +throw 'invalid async handle: ' + handle; +} +this._callbacks[idx] = null; +} +} +}, +_atEndOfMicrotask: function () { +var len = this._callbacks.length; +for (var i = 0; i < len; i++) { +var cb = this._callbacks[i]; +if (cb) { +try { +cb(); +} catch (e) { +i++; +this._callbacks.splice(0, i); +this._lastVal += i; +this._twiddle.textContent = this._twiddleContent++; +throw e; +} +} +} +this._callbacks.splice(0, len); +this._lastVal += len; +} +}; +new window.MutationObserver(function () { +Polymer.Async._atEndOfMicrotask(); +}).observe(Polymer.Async._twiddle, { characterData: true }); +Polymer.Debounce = function () { +var Async = Polymer.Async; +var Debouncer = function (context) { +this.context = context; +var self = this; +this.boundComplete = function () { +self.complete(); +}; +}; +Debouncer.prototype = { +go: function (callback, wait) { +var h; +this.finish = function () { +Async.cancel(h); +}; +h = Async.run(this.boundComplete, wait); +this.callback = callback; +}, +stop: function () { +if (this.finish) { +this.finish(); +this.finish = null; +} +}, +complete: function () { +if (this.finish) { +this.stop(); +this.callback.call(this.context); +} +} +}; +function debounce(debouncer, callback, wait) { +if (debouncer) { +debouncer.stop(); +} else { +debouncer = new Debouncer(this); +} +debouncer.go(callback, wait); +return debouncer; +} +return debounce; +}(); +Polymer.Base._addFeature({ +$$: function (slctr) { +return Polymer.dom(this.root).querySelector(slctr); +}, +toggleClass: function (name, bool, node) { +node = node || this; +if (arguments.length == 1) { +bool = !node.classList.contains(name); +} +if (bool) { +Polymer.dom(node).classList.add(name); +} else { +Polymer.dom(node).classList.remove(name); +} +}, +toggleAttribute: function (name, bool, node) { +node = node || this; +if (arguments.length == 1) { +bool = !node.hasAttribute(name); +} +if (bool) { +Polymer.dom(node).setAttribute(name, ''); +} else { +Polymer.dom(node).removeAttribute(name); +} +}, +classFollows: function (name, toElement, fromElement) { +if (fromElement) { +Polymer.dom(fromElement).classList.remove(name); +} +if (toElement) { +Polymer.dom(toElement).classList.add(name); +} +}, +attributeFollows: function (name, toElement, fromElement) { +if (fromElement) { +Polymer.dom(fromElement).removeAttribute(name); +} +if (toElement) { +Polymer.dom(toElement).setAttribute(name, ''); +} +}, +getEffectiveChildNodes: function () { +return Polymer.dom(this).getEffectiveChildNodes(); +}, +getEffectiveChildren: function () { +var list = Polymer.dom(this).getEffectiveChildNodes(); +return list.filter(function (n) { +return n.nodeType === Node.ELEMENT_NODE; +}); +}, +getEffectiveTextContent: function () { +var cn = this.getEffectiveChildNodes(); +var tc = []; +for (var i = 0, c; c = cn[i]; i++) { +if (c.nodeType !== Node.COMMENT_NODE) { +tc.push(Polymer.dom(c).textContent); +} +} +return tc.join(''); +}, +queryEffectiveChildren: function (slctr) { +var e$ = Polymer.dom(this).queryDistributedElements(slctr); +return e$ && e$[0]; +}, +queryAllEffectiveChildren: function (slctr) { +return Polymer.dom(this).queryDistributedElements(slctr); +}, +getContentChildNodes: function (slctr) { +var content = Polymer.dom(this.root).querySelector(slctr || 'content'); +return content ? Polymer.dom(content).getDistributedNodes() : []; +}, +getContentChildren: function (slctr) { +return this.getContentChildNodes(slctr).filter(function (n) { +return n.nodeType === Node.ELEMENT_NODE; +}); +}, +fire: function (type, detail, options) { +options = options || Polymer.nob; +var node = options.node || this; +var detail = detail === null || detail === undefined ? {} : detail; +var bubbles = options.bubbles === undefined ? true : options.bubbles; +var cancelable = Boolean(options.cancelable); +var useCache = options._useCache; +var event = this._getEvent(type, bubbles, cancelable, useCache); +event.detail = detail; +if (useCache) { +this.__eventCache[type] = null; +} +node.dispatchEvent(event); +if (useCache) { +this.__eventCache[type] = event; +} +return event; +}, +__eventCache: {}, +_getEvent: function (type, bubbles, cancelable, useCache) { +var event = useCache && this.__eventCache[type]; +if (!event || (event.bubbles != bubbles || event.cancelable != cancelable)) { +event = new Event(type, { +bubbles: Boolean(bubbles), +cancelable: cancelable +}); +} +return event; +}, +async: function (callback, waitTime) { +var self = this; +return Polymer.Async.run(function () { +callback.call(self); +}, waitTime); +}, +cancelAsync: function (handle) { +Polymer.Async.cancel(handle); +}, +arrayDelete: function (path, item) { +var index; +if (Array.isArray(path)) { +index = path.indexOf(item); +if (index >= 0) { +return path.splice(index, 1); +} +} else { +var arr = this._get(path); +index = arr.indexOf(item); +if (index >= 0) { +return this.splice(path, index, 1); +} +} +}, +transform: function (transform, node) { +node = node || this; +node.style.webkitTransform = transform; +node.style.transform = transform; +}, +translate3d: function (x, y, z, node) { +node = node || this; +this.transform('translate3d(' + x + ',' + y + ',' + z + ')', node); +}, +importHref: function (href, onload, onerror) { +var l = document.createElement('link'); +l.rel = 'import'; +l.href = href; +var self = this; +if (onload) { +l.onload = function (e) { +return onload.call(self, e); +}; +} +if (onerror) { +l.onerror = function (e) { +return onerror.call(self, e); +}; +} +document.head.appendChild(l); +return l; +}, +create: function (tag, props) { +var elt = document.createElement(tag); +if (props) { +for (var n in props) { +elt[n] = props[n]; +} +} +return elt; +}, +isLightDescendant: function (node) { +return this !== node && this.contains(node) && Polymer.dom(this).getOwnerRoot() === Polymer.dom(node).getOwnerRoot(); +}, +isLocalDescendant: function (node) { +return this.root === Polymer.dom(node).getOwnerRoot(); +} +}); +Polymer.Bind = { +_dataEventCache: {}, +prepareModel: function (model) { +Polymer.Base.mixin(model, this._modelApi); +}, +_modelApi: { +_notifyChange: function (source, event, value) { +value = value === undefined ? this[source] : value; +event = event || Polymer.CaseMap.camelToDashCase(source) + '-changed'; +this.fire(event, { value: value }, { +bubbles: false, +cancelable: false, +_useCache: true +}); +}, +_propertySetter: function (property, value, effects, fromAbove) { +var old = this.__data__[property]; +if (old !== value && (old === old || value === value)) { +this.__data__[property] = value; +if (typeof value == 'object') { +this._clearPath(property); +} +if (this._propertyChanged) { +this._propertyChanged(property, value, old); +} +if (effects) { +this._effectEffects(property, value, effects, old, fromAbove); +} +} +return old; +}, +__setProperty: function (property, value, quiet, node) { +node = node || this; +var effects = node._propertyEffects && node._propertyEffects[property]; +if (effects) { +node._propertySetter(property, value, effects, quiet); +} else { +node[property] = value; +} +}, +_effectEffects: function (property, value, effects, old, fromAbove) { +for (var i = 0, l = effects.length, fx; i < l && (fx = effects[i]); i++) { +fx.fn.call(this, property, value, fx.effect, old, fromAbove); +} +}, +_clearPath: function (path) { +for (var prop in this.__data__) { +if (prop.indexOf(path + '.') === 0) { +this.__data__[prop] = undefined; +} +} +} +}, +ensurePropertyEffects: function (model, property) { +if (!model._propertyEffects) { +model._propertyEffects = {}; +} +var fx = model._propertyEffects[property]; +if (!fx) { +fx = model._propertyEffects[property] = []; +} +return fx; +}, +addPropertyEffect: function (model, property, kind, effect) { +var fx = this.ensurePropertyEffects(model, property); +var propEffect = { +kind: kind, +effect: effect, +fn: Polymer.Bind['_' + kind + 'Effect'] +}; +fx.push(propEffect); +return propEffect; +}, +createBindings: function (model) { +var fx$ = model._propertyEffects; +if (fx$) { +for (var n in fx$) { +var fx = fx$[n]; +fx.sort(this._sortPropertyEffects); +this._createAccessors(model, n, fx); +} +} +}, +_sortPropertyEffects: function () { +var EFFECT_ORDER = { +'compute': 0, +'annotation': 1, +'computedAnnotation': 2, +'reflect': 3, +'notify': 4, +'observer': 5, +'complexObserver': 6, +'function': 7 +}; +return function (a, b) { +return EFFECT_ORDER[a.kind] - EFFECT_ORDER[b.kind]; +}; +}(), +_createAccessors: function (model, property, effects) { +var defun = { +get: function () { +return this.__data__[property]; +} +}; +var setter = function (value) { +this._propertySetter(property, value, effects); +}; +var info = model.getPropertyInfo && model.getPropertyInfo(property); +if (info && info.readOnly) { +if (!info.computed) { +model['_set' + this.upper(property)] = setter; +} +} else { +defun.set = setter; +} +Object.defineProperty(model, property, defun); +}, +upper: function (name) { +return name[0].toUpperCase() + name.substring(1); +}, +_addAnnotatedListener: function (model, index, property, path, event) { +if (!model._bindListeners) { +model._bindListeners = []; +} +var fn = this._notedListenerFactory(property, path, this._isStructured(path)); +var eventName = event || Polymer.CaseMap.camelToDashCase(property) + '-changed'; +model._bindListeners.push({ +index: index, +property: property, +path: path, +changedFn: fn, +event: eventName +}); +}, +_isStructured: function (path) { +return path.indexOf('.') > 0; +}, +_isEventBogus: function (e, target) { +return e.path && e.path[0] !== target; +}, +_notedListenerFactory: function (property, path, isStructured) { +return function (target, value, targetPath) { +if (targetPath) { +this._notifyPath(this._fixPath(path, property, targetPath), value); +} else { +value = target[property]; +if (!isStructured) { +this[path] = value; +} else { +if (this.__data__[path] != value) { +this.set(path, value); +} +} +} +}; +}, +prepareInstance: function (inst) { +inst.__data__ = Object.create(null); +}, +setupBindListeners: function (inst) { +var b$ = inst._bindListeners; +for (var i = 0, l = b$.length, info; i < l && (info = b$[i]); i++) { +var node = inst._nodes[info.index]; +this._addNotifyListener(node, inst, info.event, info.changedFn); +} +; +}, +_addNotifyListener: function (element, context, event, changedFn) { +element.addEventListener(event, function (e) { +return context._notifyListener(changedFn, e); +}); +} +}; +Polymer.Base.extend(Polymer.Bind, { +_shouldAddListener: function (effect) { +return effect.name && effect.kind != 'attribute' && effect.kind != 'text' && !effect.isCompound && effect.parts[0].mode === '{' && !effect.parts[0].negate; +}, +_annotationEffect: function (source, value, effect) { +if (source != effect.value) { +value = this._get(effect.value); +this.__data__[effect.value] = value; +} +var calc = effect.negate ? !value : value; +if (!effect.customEvent || this._nodes[effect.index][effect.name] !== calc) { +return this._applyEffectValue(effect, calc); +} +}, +_reflectEffect: function (source, value, effect) { +this.reflectPropertyToAttribute(source, effect.attribute, value); +}, +_notifyEffect: function (source, value, effect, old, fromAbove) { +if (!fromAbove) { +this._notifyChange(source, effect.event, value); +} +}, +_functionEffect: function (source, value, fn, old, fromAbove) { +fn.call(this, source, value, old, fromAbove); +}, +_observerEffect: function (source, value, effect, old) { +var fn = this[effect.method]; +if (fn) { +fn.call(this, value, old); +} else { +this._warn(this._logf('_observerEffect', 'observer method `' + effect.method + '` not defined')); +} +}, +_complexObserverEffect: function (source, value, effect) { +var fn = this[effect.method]; +if (fn) { +var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value); +if (args) { +fn.apply(this, args); +} +} else { +this._warn(this._logf('_complexObserverEffect', 'observer method `' + effect.method + '` not defined')); +} +}, +_computeEffect: function (source, value, effect) { +var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value); +if (args) { +var fn = this[effect.method]; +if (fn) { +this.__setProperty(effect.name, fn.apply(this, args)); +} else { +this._warn(this._logf('_computeEffect', 'compute method `' + effect.method + '` not defined')); +} +} +}, +_annotatedComputationEffect: function (source, value, effect) { +var computedHost = this._rootDataHost || this; +var fn = computedHost[effect.method]; +if (fn) { +var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value); +if (args) { +var computedvalue = fn.apply(computedHost, args); +if (effect.negate) { +computedvalue = !computedvalue; +} +this._applyEffectValue(effect, computedvalue); +} +} else { +computedHost._warn(computedHost._logf('_annotatedComputationEffect', 'compute method `' + effect.method + '` not defined')); +} +}, +_marshalArgs: function (model, effect, path, value) { +var values = []; +var args = effect.args; +for (var i = 0, l = args.length; i < l; i++) { +var arg = args[i]; +var name = arg.name; +var v; +if (arg.literal) { +v = arg.value; +} else if (arg.structured) { +v = Polymer.Base._get(name, model); +} else { +v = model[name]; +} +if (args.length > 1 && v === undefined) { +return; +} +if (arg.wildcard) { +var baseChanged = name.indexOf(path + '.') === 0; +var matches = effect.trigger.name.indexOf(name) === 0 && !baseChanged; +values[i] = { +path: matches ? path : name, +value: matches ? value : v, +base: v +}; +} else { +values[i] = v; +} +} +return values; +} +}); +Polymer.Base._addFeature({ +_addPropertyEffect: function (property, kind, effect) { +var prop = Polymer.Bind.addPropertyEffect(this, property, kind, effect); +prop.pathFn = this['_' + prop.kind + 'PathEffect']; +}, +_prepEffects: function () { +Polymer.Bind.prepareModel(this); +this._addAnnotationEffects(this._notes); +}, +_prepBindings: function () { +Polymer.Bind.createBindings(this); +}, +_addPropertyEffects: function (properties) { +if (properties) { +for (var p in properties) { +var prop = properties[p]; +if (prop.observer) { +this._addObserverEffect(p, prop.observer); +} +if (prop.computed) { +prop.readOnly = true; +this._addComputedEffect(p, prop.computed); +} +if (prop.notify) { +this._addPropertyEffect(p, 'notify', { event: Polymer.CaseMap.camelToDashCase(p) + '-changed' }); +} +if (prop.reflectToAttribute) { +this._addPropertyEffect(p, 'reflect', { attribute: Polymer.CaseMap.camelToDashCase(p) }); +} +if (prop.readOnly) { +Polymer.Bind.ensurePropertyEffects(this, p); +} +} +} +}, +_addComputedEffect: function (name, expression) { +var sig = this._parseMethod(expression); +for (var i = 0, arg; i < sig.args.length && (arg = sig.args[i]); i++) { +this._addPropertyEffect(arg.model, 'compute', { +method: sig.method, +args: sig.args, +trigger: arg, +name: name +}); +} +}, +_addObserverEffect: function (property, observer) { +this._addPropertyEffect(property, 'observer', { +method: observer, +property: property +}); +}, +_addComplexObserverEffects: function (observers) { +if (observers) { +for (var i = 0, o; i < observers.length && (o = observers[i]); i++) { +this._addComplexObserverEffect(o); +} +} +}, +_addComplexObserverEffect: function (observer) { +var sig = this._parseMethod(observer); +for (var i = 0, arg; i < sig.args.length && (arg = sig.args[i]); i++) { +this._addPropertyEffect(arg.model, 'complexObserver', { +method: sig.method, +args: sig.args, +trigger: arg +}); +} +}, +_addAnnotationEffects: function (notes) { +for (var i = 0, note; i < notes.length && (note = notes[i]); i++) { +var b$ = note.bindings; +for (var j = 0, binding; j < b$.length && (binding = b$[j]); j++) { +this._addAnnotationEffect(binding, i); +} +} +}, +_addAnnotationEffect: function (note, index) { +if (Polymer.Bind._shouldAddListener(note)) { +Polymer.Bind._addAnnotatedListener(this, index, note.name, note.parts[0].value, note.parts[0].event); +} +for (var i = 0; i < note.parts.length; i++) { +var part = note.parts[i]; +if (part.signature) { +this._addAnnotatedComputationEffect(note, part, index); +} else if (!part.literal) { +this._addPropertyEffect(part.model, 'annotation', { +kind: note.kind, +index: index, +name: note.name, +value: part.value, +isCompound: note.isCompound, +compoundIndex: part.compoundIndex, +event: part.event, +customEvent: part.customEvent, +negate: part.negate +}); +} +} +}, +_addAnnotatedComputationEffect: function (note, part, index) { +var sig = part.signature; +if (sig.static) { +this.__addAnnotatedComputationEffect('__static__', index, note, part, null); +} else { +for (var i = 0, arg; i < sig.args.length && (arg = sig.args[i]); i++) { +if (!arg.literal) { +this.__addAnnotatedComputationEffect(arg.model, index, note, part, arg); +} +} +} +}, +__addAnnotatedComputationEffect: function (property, index, note, part, trigger) { +this._addPropertyEffect(property, 'annotatedComputation', { +index: index, +isCompound: note.isCompound, +compoundIndex: part.compoundIndex, +kind: note.kind, +name: note.name, +negate: part.negate, +method: part.signature.method, +args: part.signature.args, +trigger: trigger +}); +}, +_parseMethod: function (expression) { +var m = expression.match(/([^\s]+)\((.*)\)/); +if (m) { +var sig = { +method: m[1], +static: true +}; +if (m[2].trim()) { +var args = m[2].replace(/\\,/g, '&comma;').split(','); +return this._parseArgs(args, sig); +} else { +sig.args = Polymer.nar; +return sig; +} +} +}, +_parseArgs: function (argList, sig) { +sig.args = argList.map(function (rawArg) { +var arg = this._parseArg(rawArg); +if (!arg.literal) { +sig.static = false; +} +return arg; +}, this); +return sig; +}, +_parseArg: function (rawArg) { +var arg = rawArg.trim().replace(/&comma;/g, ',').replace(/\\(.)/g, '$1'); +var a = { +name: arg, +model: this._modelForPath(arg) +}; +var fc = arg[0]; +if (fc === '-') { +fc = arg[1]; +} +if (fc >= '0' && fc <= '9') { +fc = '#'; +} +switch (fc) { +case '\'': +case '"': +a.value = arg.slice(1, -1); +a.literal = true; +break; +case '#': +a.value = Number(arg); +a.literal = true; +break; +} +if (!a.literal) { +a.structured = arg.indexOf('.') > 0; +if (a.structured) { +a.wildcard = arg.slice(-2) == '.*'; +if (a.wildcard) { +a.name = arg.slice(0, -2); +} +} +} +return a; +}, +_marshalInstanceEffects: function () { +Polymer.Bind.prepareInstance(this); +if (this._bindListeners) { +Polymer.Bind.setupBindListeners(this); +} +}, +_applyEffectValue: function (info, value) { +var node = this._nodes[info.index]; +var property = info.name; +if (info.isCompound) { +var storage = node.__compoundStorage__[property]; +storage[info.compoundIndex] = value; +value = storage.join(''); +} +if (info.kind == 'attribute') { +this.serializeValueToAttribute(value, property, node); +} else { +if (property === 'className') { +value = this._scopeElementClass(node, value); +} +if (property === 'textContent' || node.localName == 'input' && property == 'value') { +value = value == undefined ? '' : value; +} +var pinfo; +if (!node._propertyInfo || !(pinfo = node._propertyInfo[property]) || !pinfo.readOnly) { +this.__setProperty(property, value, true, node); +} +} +}, +_executeStaticEffects: function () { +if (this._propertyEffects && this._propertyEffects.__static__) { +this._effectEffects('__static__', null, this._propertyEffects.__static__); +} +} +}); +Polymer.Base._addFeature({ +_setupConfigure: function (initialConfig) { +this._config = {}; +this._handlers = []; +if (initialConfig) { +for (var i in initialConfig) { +if (initialConfig[i] !== undefined) { +this._config[i] = initialConfig[i]; +} +} +} +}, +_marshalAttributes: function () { +this._takeAttributesToModel(this._config); +}, +_attributeChangedImpl: function (name) { +var model = this._clientsReadied ? this : this._config; +this._setAttributeToProperty(model, name); +}, +_configValue: function (name, value) { +var info = this._propertyInfo[name]; +if (!info || !info.readOnly) { +this._config[name] = value; +} +}, +_beforeClientsReady: function () { +this._configure(); +}, +_configure: function () { +this._configureAnnotationReferences(); +this._aboveConfig = this.mixin({}, this._config); +var config = {}; +for (var i = 0; i < this.behaviors.length; i++) { +this._configureProperties(this.behaviors[i].properties, config); +} +this._configureProperties(this.properties, config); +this.mixin(config, this._aboveConfig); +this._config = config; +if (this._clients && this._clients.length) { +this._distributeConfig(this._config); +} +}, +_configureProperties: function (properties, config) { +for (var i in properties) { +var c = properties[i]; +if (c.value !== undefined) { +var value = c.value; +if (typeof value == 'function') { +value = value.call(this, this._config); +} +config[i] = value; +} +} +}, +_distributeConfig: function (config) { +var fx$ = this._propertyEffects; +if (fx$) { +for (var p in config) { +var fx = fx$[p]; +if (fx) { +for (var i = 0, l = fx.length, x; i < l && (x = fx[i]); i++) { +if (x.kind === 'annotation' && !x.isCompound) { +var node = this._nodes[x.effect.index]; +if (node._configValue) { +var value = p === x.effect.value ? config[p] : this._get(x.effect.value, config); +node._configValue(x.effect.name, value); +} +} +} +} +} +} +}, +_afterClientsReady: function () { +this._executeStaticEffects(); +this._applyConfig(this._config, this._aboveConfig); +this._flushHandlers(); +}, +_applyConfig: function (config, aboveConfig) { +for (var n in config) { +if (this[n] === undefined) { +this.__setProperty(n, config[n], n in aboveConfig); +} +} +}, +_notifyListener: function (fn, e) { +if (!Polymer.Bind._isEventBogus(e, e.target)) { +var value, path; +if (e.detail) { +value = e.detail.value; +path = e.detail.path; +} +if (!this._clientsReadied) { +this._queueHandler([ +fn, +e.target, +value, +path +]); +} else { +return fn.call(this, e.target, value, path); +} +} +}, +_queueHandler: function (args) { +this._handlers.push(args); +}, +_flushHandlers: function () { +var h$ = this._handlers; +for (var i = 0, l = h$.length, h; i < l && (h = h$[i]); i++) { +h[0].call(this, h[1], h[2], h[3]); +} +this._handlers = []; +} +}); +(function () { +'use strict'; +Polymer.Base._addFeature({ +notifyPath: function (path, value, fromAbove) { +var info = {}; +this._get(path, this, info); +this._notifyPath(info.path, value, fromAbove); +}, +_notifyPath: function (path, value, fromAbove) { +var old = this._propertySetter(path, value); +if (old !== value && (old === old || value === value)) { +this._pathEffector(path, value); +if (!fromAbove) { +this._notifyPathUp(path, value); +} +return true; +} +}, +_getPathParts: function (path) { +if (Array.isArray(path)) { +var parts = []; +for (var i = 0; i < path.length; i++) { +var args = path[i].toString().split('.'); +for (var j = 0; j < args.length; j++) { +parts.push(args[j]); +} +} +return parts; +} else { +return path.toString().split('.'); +} +}, +set: function (path, value, root) { +var prop = root || this; +var parts = this._getPathParts(path); +var array; +var last = parts[parts.length - 1]; +if (parts.length > 1) { +for (var i = 0; i < parts.length - 1; i++) { +var part = parts[i]; +if (array && part[0] == '#') { +prop = Polymer.Collection.get(array).getItem(part); +} else { +prop = prop[part]; +if (array && parseInt(part, 10) == part) { +parts[i] = Polymer.Collection.get(array).getKey(prop); +} +} +if (!prop) { +return; +} +array = Array.isArray(prop) ? prop : null; +} +if (array) { +var coll = Polymer.Collection.get(array); +if (last[0] == '#') { +var key = last; +var old = coll.getItem(key); +last = array.indexOf(old); +coll.setItem(key, value); +} else if (parseInt(last, 10) == last) { +var old = prop[last]; +var key = coll.getKey(old); +parts[i] = key; +coll.setItem(key, value); +} +} +prop[last] = value; +if (!root) { +this._notifyPath(parts.join('.'), value); +} +} else { +prop[path] = value; +} +}, +get: function (path, root) { +return this._get(path, root); +}, +_get: function (path, root, info) { +var prop = root || this; +var parts = this._getPathParts(path); +var array; +for (var i = 0; i < parts.length; i++) { +if (!prop) { +return; +} +var part = parts[i]; +if (array && part[0] == '#') { +prop = Polymer.Collection.get(array).getItem(part); +} else { +prop = prop[part]; +if (info && array && parseInt(part, 10) == part) { +parts[i] = Polymer.Collection.get(array).getKey(prop); +} +} +array = Array.isArray(prop) ? prop : null; +} +if (info) { +info.path = parts.join('.'); +} +return prop; +}, +_pathEffector: function (path, value) { +var model = this._modelForPath(path); +var fx$ = this._propertyEffects && this._propertyEffects[model]; +if (fx$) { +for (var i = 0, fx; i < fx$.length && (fx = fx$[i]); i++) { +var fxFn = fx.pathFn; +if (fxFn) { +fxFn.call(this, path, value, fx.effect); +} +} +} +if (this._boundPaths) { +this._notifyBoundPaths(path, value); +} +}, +_annotationPathEffect: function (path, value, effect) { +if (effect.value === path || effect.value.indexOf(path + '.') === 0) { +Polymer.Bind._annotationEffect.call(this, path, value, effect); +} else if (path.indexOf(effect.value + '.') === 0 && !effect.negate) { +var node = this._nodes[effect.index]; +if (node && node._notifyPath) { +var p = this._fixPath(effect.name, effect.value, path); +node._notifyPath(p, value, true); +} +} +}, +_complexObserverPathEffect: function (path, value, effect) { +if (this._pathMatchesEffect(path, effect)) { +Polymer.Bind._complexObserverEffect.call(this, path, value, effect); +} +}, +_computePathEffect: function (path, value, effect) { +if (this._pathMatchesEffect(path, effect)) { +Polymer.Bind._computeEffect.call(this, path, value, effect); +} +}, +_annotatedComputationPathEffect: function (path, value, effect) { +if (this._pathMatchesEffect(path, effect)) { +Polymer.Bind._annotatedComputationEffect.call(this, path, value, effect); +} +}, +_pathMatchesEffect: function (path, effect) { +var effectArg = effect.trigger.name; +return effectArg == path || effectArg.indexOf(path + '.') === 0 || effect.trigger.wildcard && path.indexOf(effectArg) === 0; +}, +linkPaths: function (to, from) { +this._boundPaths = this._boundPaths || {}; +if (from) { +this._boundPaths[to] = from; +} else { +this.unlinkPaths(to); +} +}, +unlinkPaths: function (path) { +if (this._boundPaths) { +delete this._boundPaths[path]; +} +}, +_notifyBoundPaths: function (path, value) { +for (var a in this._boundPaths) { +var b = this._boundPaths[a]; +if (path.indexOf(a + '.') == 0) { +this._notifyPath(this._fixPath(b, a, path), value); +} else if (path.indexOf(b + '.') == 0) { +this._notifyPath(this._fixPath(a, b, path), value); +} +} +}, +_fixPath: function (property, root, path) { +return property + path.slice(root.length); +}, +_notifyPathUp: function (path, value) { +var rootName = this._modelForPath(path); +var dashCaseName = Polymer.CaseMap.camelToDashCase(rootName); +var eventName = dashCaseName + this._EVENT_CHANGED; +this.fire(eventName, { +path: path, +value: value +}, { +bubbles: false, +_useCache: true +}); +}, +_modelForPath: function (path) { +var dot = path.indexOf('.'); +return dot < 0 ? path : path.slice(0, dot); +}, +_EVENT_CHANGED: '-changed', +notifySplices: function (path, splices) { +var info = {}; +var array = this._get(path, this, info); +this._notifySplices(array, info.path, splices); +}, +_notifySplices: function (array, path, splices) { +var change = { +keySplices: Polymer.Collection.applySplices(array, splices), +indexSplices: splices +}; +if (!array.hasOwnProperty('splices')) { +Object.defineProperty(array, 'splices', { +configurable: true, +writable: true +}); +} +array.splices = change; +this._notifyPath(path + '.splices', change); +this._notifyPath(path + '.length', array.length); +change.keySplices = null; +change.indexSplices = null; +}, +_notifySplice: function (array, path, index, added, removed) { +this._notifySplices(array, path, [{ +index: index, +addedCount: added, +removed: removed, +object: array, +type: 'splice' +}]); +}, +push: function (path) { +var info = {}; +var array = this._get(path, this, info); +var args = Array.prototype.slice.call(arguments, 1); +var len = array.length; +var ret = array.push.apply(array, args); +if (args.length) { +this._notifySplice(array, info.path, len, args.length, []); +} +return ret; +}, +pop: function (path) { +var info = {}; +var array = this._get(path, this, info); +var hadLength = Boolean(array.length); +var args = Array.prototype.slice.call(arguments, 1); +var ret = array.pop.apply(array, args); +if (hadLength) { +this._notifySplice(array, info.path, array.length, 0, [ret]); +} +return ret; +}, +splice: function (path, start, deleteCount) { +var info = {}; +var array = this._get(path, this, info); +if (start < 0) { +start = array.length - Math.floor(-start); +} else { +start = Math.floor(start); +} +if (!start) { +start = 0; +} +var args = Array.prototype.slice.call(arguments, 1); +var ret = array.splice.apply(array, args); +var addedCount = Math.max(args.length - 2, 0); +if (addedCount || ret.length) { +this._notifySplice(array, info.path, start, addedCount, ret); +} +return ret; +}, +shift: function (path) { +var info = {}; +var array = this._get(path, this, info); +var hadLength = Boolean(array.length); +var args = Array.prototype.slice.call(arguments, 1); +var ret = array.shift.apply(array, args); +if (hadLength) { +this._notifySplice(array, info.path, 0, 0, [ret]); +} +return ret; +}, +unshift: function (path) { +var info = {}; +var array = this._get(path, this, info); +var args = Array.prototype.slice.call(arguments, 1); +var ret = array.unshift.apply(array, args); +if (args.length) { +this._notifySplice(array, info.path, 0, args.length, []); +} +return ret; +}, +prepareModelNotifyPath: function (model) { +this.mixin(model, { +fire: Polymer.Base.fire, +_getEvent: Polymer.Base._getEvent, +__eventCache: Polymer.Base.__eventCache, +notifyPath: Polymer.Base.notifyPath, +_get: Polymer.Base._get, +_EVENT_CHANGED: Polymer.Base._EVENT_CHANGED, +_notifyPath: Polymer.Base._notifyPath, +_notifyPathUp: Polymer.Base._notifyPathUp, +_pathEffector: Polymer.Base._pathEffector, +_annotationPathEffect: Polymer.Base._annotationPathEffect, +_complexObserverPathEffect: Polymer.Base._complexObserverPathEffect, +_annotatedComputationPathEffect: Polymer.Base._annotatedComputationPathEffect, +_computePathEffect: Polymer.Base._computePathEffect, +_modelForPath: Polymer.Base._modelForPath, +_pathMatchesEffect: Polymer.Base._pathMatchesEffect, +_notifyBoundPaths: Polymer.Base._notifyBoundPaths, +_getPathParts: Polymer.Base._getPathParts +}); +} +}); +}()); +Polymer.Base._addFeature({ +resolveUrl: function (url) { +var module = Polymer.DomModule.import(this.is); +var root = ''; +if (module) { +var assetPath = module.getAttribute('assetpath') || ''; +root = Polymer.ResolveUrl.resolveUrl(assetPath, module.ownerDocument.baseURI); +} +return Polymer.ResolveUrl.resolveUrl(url, root); +} +}); +Polymer.CssParse = function () { +var api = { +parse: function (text) { +text = this._clean(text); +return this._parseCss(this._lex(text), text); +}, +_clean: function (cssText) { +return cssText.replace(this._rx.comments, '').replace(this._rx.port, ''); +}, +_lex: function (text) { +var root = { +start: 0, +end: text.length +}; +var n = root; +for (var i = 0, s = 0, l = text.length; i < l; i++) { +switch (text[i]) { +case this.OPEN_BRACE: +if (!n.rules) { +n.rules = []; +} +var p = n; +var previous = p.rules[p.rules.length - 1]; +n = { +start: i + 1, +parent: p, +previous: previous +}; +p.rules.push(n); +break; +case this.CLOSE_BRACE: +n.end = i + 1; +n = n.parent || root; +break; +} +} +return root; +}, +_parseCss: function (node, text) { +var t = text.substring(node.start, node.end - 1); +node.parsedCssText = node.cssText = t.trim(); +if (node.parent) { +var ss = node.previous ? node.previous.end : node.parent.start; +t = text.substring(ss, node.start - 1); +t = this._expandUnicodeEscapes(t); +t = t.replace(this._rx.multipleSpaces, ' '); +t = t.substring(t.lastIndexOf(';') + 1); +var s = node.parsedSelector = node.selector = t.trim(); +node.atRule = s.indexOf(this.AT_START) === 0; +if (node.atRule) { +if (s.indexOf(this.MEDIA_START) === 0) { +node.type = this.types.MEDIA_RULE; +} else if (s.match(this._rx.keyframesRule)) { +node.type = this.types.KEYFRAMES_RULE; +} +} else { +if (s.indexOf(this.VAR_START) === 0) { +node.type = this.types.MIXIN_RULE; +} else { +node.type = this.types.STYLE_RULE; +} +} +} +var r$ = node.rules; +if (r$) { +for (var i = 0, l = r$.length, r; i < l && (r = r$[i]); i++) { +this._parseCss(r, text); +} +} +return node; +}, +_expandUnicodeEscapes: function (s) { +return s.replace(/\\([0-9a-f]{1,6})\s/gi, function () { +var code = arguments[1], repeat = 6 - code.length; +while (repeat--) { +code = '0' + code; +} +return '\\' + code; +}); +}, +stringify: function (node, preserveProperties, text) { +text = text || ''; +var cssText = ''; +if (node.cssText || node.rules) { +var r$ = node.rules; +if (r$ && (preserveProperties || !this._hasMixinRules(r$))) { +for (var i = 0, l = r$.length, r; i < l && (r = r$[i]); i++) { +cssText = this.stringify(r, preserveProperties, cssText); +} +} else { +cssText = preserveProperties ? node.cssText : this.removeCustomProps(node.cssText); +cssText = cssText.trim(); +if (cssText) { +cssText = ' ' + cssText + '\n'; +} +} +} +if (cssText) { +if (node.selector) { +text += node.selector + ' ' + this.OPEN_BRACE + '\n'; +} +text += cssText; +if (node.selector) { +text += this.CLOSE_BRACE + '\n\n'; +} +} +return text; +}, +_hasMixinRules: function (rules) { +return rules[0].selector.indexOf(this.VAR_START) === 0; +}, +removeCustomProps: function (cssText) { +cssText = this.removeCustomPropAssignment(cssText); +return this.removeCustomPropApply(cssText); +}, +removeCustomPropAssignment: function (cssText) { +return cssText.replace(this._rx.customProp, '').replace(this._rx.mixinProp, ''); +}, +removeCustomPropApply: function (cssText) { +return cssText.replace(this._rx.mixinApply, '').replace(this._rx.varApply, ''); +}, +types: { +STYLE_RULE: 1, +KEYFRAMES_RULE: 7, +MEDIA_RULE: 4, +MIXIN_RULE: 1000 +}, +OPEN_BRACE: '{', +CLOSE_BRACE: '}', +_rx: { +comments: /\/\*[^*]*\*+([^\/*][^*]*\*+)*\//gim, +port: /@import[^;]*;/gim, +customProp: /(?:^|[\s;])--[^;{]*?:[^{};]*?(?:[;\n]|$)/gim, +mixinProp: /(?:^|[\s;])?--[^;{]*?:[^{;]*?{[^}]*?}(?:[;\n]|$)?/gim, +mixinApply: /@apply[\s]*\([^)]*?\)[\s]*(?:[;\n]|$)?/gim, +varApply: /[^;:]*?:[^;]*?var\([^;]*\)(?:[;\n]|$)?/gim, +keyframesRule: /^@[^\s]*keyframes/, +multipleSpaces: /\s+/g +}, +VAR_START: '--', +MEDIA_START: '@media', +AT_START: '@' +}; +return api; +}(); +Polymer.StyleUtil = function () { +return { +MODULE_STYLES_SELECTOR: 'style, link[rel=import][type~=css], template', +INCLUDE_ATTR: 'include', +toCssText: function (rules, callback, preserveProperties) { +if (typeof rules === 'string') { +rules = this.parser.parse(rules); +} +if (callback) { +this.forEachStyleRule(rules, callback); +} +return this.parser.stringify(rules, preserveProperties); +}, +forRulesInStyles: function (styles, callback) { +if (styles) { +for (var i = 0, l = styles.length, s; i < l && (s = styles[i]); i++) { +this.forEachStyleRule(this.rulesForStyle(s), callback); +} +} +}, +rulesForStyle: function (style) { +if (!style.__cssRules && style.textContent) { +style.__cssRules = this.parser.parse(style.textContent); +} +return style.__cssRules; +}, +clearStyleRules: function (style) { +style.__cssRules = null; +}, +forEachStyleRule: function (node, callback) { +if (!node) { +return; +} +var s = node.parsedSelector; +var skipRules = false; +if (node.type === this.ruleTypes.STYLE_RULE) { +callback(node); +} else if (node.type === this.ruleTypes.KEYFRAMES_RULE || node.type === this.ruleTypes.MIXIN_RULE) { +skipRules = true; +} +var r$ = node.rules; +if (r$ && !skipRules) { +for (var i = 0, l = r$.length, r; i < l && (r = r$[i]); i++) { +this.forEachStyleRule(r, callback); +} +} +}, +applyCss: function (cssText, moniker, target, afterNode) { +var style = document.createElement('style'); +if (moniker) { +style.setAttribute('scope', moniker); +} +style.textContent = cssText; +target = target || document.head; +if (!afterNode) { +var n$ = target.querySelectorAll('style[scope]'); +afterNode = n$[n$.length - 1]; +} +target.insertBefore(style, afterNode && afterNode.nextSibling || target.firstChild); +return style; +}, +cssFromModules: function (moduleIds, warnIfNotFound) { +var modules = moduleIds.trim().split(' '); +var cssText = ''; +for (var i = 0; i < modules.length; i++) { +cssText += this.cssFromModule(modules[i], warnIfNotFound); +} +return cssText; +}, +cssFromModule: function (moduleId, warnIfNotFound) { +var m = Polymer.DomModule.import(moduleId); +if (m && !m._cssText) { +m._cssText = this.cssFromElement(m); +} +if (!m && warnIfNotFound) { +console.warn('Could not find style data in module named', moduleId); +} +return m && m._cssText || ''; +}, +cssFromElement: function (element) { +var cssText = ''; +var content = element.content || element; +var e$ = Polymer.DomApi.arrayCopy(content.querySelectorAll(this.MODULE_STYLES_SELECTOR)); +for (var i = 0, e; i < e$.length; i++) { +e = e$[i]; +if (e.localName === 'template') { +cssText += this.cssFromElement(e); +} else { +if (e.localName === 'style') { +var include = e.getAttribute(this.INCLUDE_ATTR); +if (include) { +cssText += this.cssFromModules(include, true); +} +e = e.__appliedElement || e; +e.parentNode.removeChild(e); +cssText += this.resolveCss(e.textContent, element.ownerDocument); +} else if (e.import && e.import.body) { +cssText += this.resolveCss(e.import.body.textContent, e.import); +} +} +} +return cssText; +}, +resolveCss: Polymer.ResolveUrl.resolveCss, +parser: Polymer.CssParse, +ruleTypes: Polymer.CssParse.types +}; +}(); +Polymer.StyleTransformer = function () { +var nativeShadow = Polymer.Settings.useNativeShadow; +var styleUtil = Polymer.StyleUtil; +var api = { +dom: function (node, scope, useAttr, shouldRemoveScope) { +this._transformDom(node, scope || '', useAttr, shouldRemoveScope); +}, +_transformDom: function (node, selector, useAttr, shouldRemoveScope) { +if (node.setAttribute) { +this.element(node, selector, useAttr, shouldRemoveScope); +} +var c$ = Polymer.dom(node).childNodes; +for (var i = 0; i < c$.length; i++) { +this._transformDom(c$[i], selector, useAttr, shouldRemoveScope); +} +}, +element: function (element, scope, useAttr, shouldRemoveScope) { +if (useAttr) { +if (shouldRemoveScope) { +element.removeAttribute(SCOPE_NAME); +} else { +element.setAttribute(SCOPE_NAME, scope); +} +} else { +if (scope) { +if (element.classList) { +if (shouldRemoveScope) { +element.classList.remove(SCOPE_NAME); +element.classList.remove(scope); +} else { +element.classList.add(SCOPE_NAME); +element.classList.add(scope); +} +} else if (element.getAttribute) { +var c = element.getAttribute(CLASS); +if (shouldRemoveScope) { +if (c) { +element.setAttribute(CLASS, c.replace(SCOPE_NAME, '').replace(scope, '')); +} +} else { +element.setAttribute(CLASS, c + (c ? ' ' : '') + SCOPE_NAME + ' ' + scope); +} +} +} +} +}, +elementStyles: function (element, callback) { +var styles = element._styles; +var cssText = ''; +for (var i = 0, l = styles.length, s, text; i < l && (s = styles[i]); i++) { +var rules = styleUtil.rulesForStyle(s); +cssText += nativeShadow ? styleUtil.toCssText(rules, callback) : this.css(rules, element.is, element.extends, callback, element._scopeCssViaAttr) + '\n\n'; +} +return cssText.trim(); +}, +css: function (rules, scope, ext, callback, useAttr) { +var hostScope = this._calcHostScope(scope, ext); +scope = this._calcElementScope(scope, useAttr); +var self = this; +return styleUtil.toCssText(rules, function (rule) { +if (!rule.isScoped) { +self.rule(rule, scope, hostScope); +rule.isScoped = true; +} +if (callback) { +callback(rule, scope, hostScope); +} +}); +}, +_calcElementScope: function (scope, useAttr) { +if (scope) { +return useAttr ? CSS_ATTR_PREFIX + scope + CSS_ATTR_SUFFIX : CSS_CLASS_PREFIX + scope; +} else { +return ''; +} +}, +_calcHostScope: function (scope, ext) { +return ext ? '[is=' + scope + ']' : scope; +}, +rule: function (rule, scope, hostScope) { +this._transformRule(rule, this._transformComplexSelector, scope, hostScope); +}, +_transformRule: function (rule, transformer, scope, hostScope) { +var p$ = rule.selector.split(COMPLEX_SELECTOR_SEP); +for (var i = 0, l = p$.length, p; i < l && (p = p$[i]); i++) { +p$[i] = transformer.call(this, p, scope, hostScope); +} +rule.selector = rule.transformedSelector = p$.join(COMPLEX_SELECTOR_SEP); +}, +_transformComplexSelector: function (selector, scope, hostScope) { +var stop = false; +var hostContext = false; +var self = this; +selector = selector.replace(SIMPLE_SELECTOR_SEP, function (m, c, s) { +if (!stop) { +var info = self._transformCompoundSelector(s, c, scope, hostScope); +stop = stop || info.stop; +hostContext = hostContext || info.hostContext; +c = info.combinator; +s = info.value; +} else { +s = s.replace(SCOPE_JUMP, ' '); +} +return c + s; +}); +if (hostContext) { +selector = selector.replace(HOST_CONTEXT_PAREN, function (m, pre, paren, post) { +return pre + paren + ' ' + hostScope + post + COMPLEX_SELECTOR_SEP + ' ' + pre + hostScope + paren + post; +}); +} +return selector; +}, +_transformCompoundSelector: function (selector, combinator, scope, hostScope) { +var jumpIndex = selector.search(SCOPE_JUMP); +var hostContext = false; +if (selector.indexOf(HOST_CONTEXT) >= 0) { +hostContext = true; +} else if (selector.indexOf(HOST) >= 0) { +selector = selector.replace(HOST_PAREN, function (m, host, paren) { +return hostScope + paren; +}); +selector = selector.replace(HOST, hostScope); +} else if (jumpIndex !== 0) { +selector = scope ? this._transformSimpleSelector(selector, scope) : selector; +} +if (selector.indexOf(CONTENT) >= 0) { +combinator = ''; +} +var stop; +if (jumpIndex >= 0) { +selector = selector.replace(SCOPE_JUMP, ' '); +stop = true; +} +return { +value: selector, +combinator: combinator, +stop: stop, +hostContext: hostContext +}; +}, +_transformSimpleSelector: function (selector, scope) { +var p$ = selector.split(PSEUDO_PREFIX); +p$[0] += scope; +return p$.join(PSEUDO_PREFIX); +}, +documentRule: function (rule) { +rule.selector = rule.parsedSelector; +this.normalizeRootSelector(rule); +if (!nativeShadow) { +this._transformRule(rule, this._transformDocumentSelector); +} +}, +normalizeRootSelector: function (rule) { +if (rule.selector === ROOT) { +rule.selector = 'body'; +} +}, +_transformDocumentSelector: function (selector) { +return selector.match(SCOPE_JUMP) ? this._transformComplexSelector(selector, SCOPE_DOC_SELECTOR) : this._transformSimpleSelector(selector.trim(), SCOPE_DOC_SELECTOR); +}, +SCOPE_NAME: 'style-scope' +}; +var SCOPE_NAME = api.SCOPE_NAME; +var SCOPE_DOC_SELECTOR = ':not([' + SCOPE_NAME + '])' + ':not(.' + SCOPE_NAME + ')'; +var COMPLEX_SELECTOR_SEP = ','; +var SIMPLE_SELECTOR_SEP = /(^|[\s>+~]+)([^\s>+~]+)/g; +var HOST = ':host'; +var ROOT = ':root'; +var HOST_PAREN = /(\:host)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/g; +var HOST_CONTEXT = ':host-context'; +var HOST_CONTEXT_PAREN = /(.*)(?:\:host-context)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))(.*)/; +var CONTENT = '::content'; +var SCOPE_JUMP = /\:\:content|\:\:shadow|\/deep\//; +var CSS_CLASS_PREFIX = '.'; +var CSS_ATTR_PREFIX = '[' + SCOPE_NAME + '~='; +var CSS_ATTR_SUFFIX = ']'; +var PSEUDO_PREFIX = ':'; +var CLASS = 'class'; +return api; +}(); +Polymer.StyleExtends = function () { +var styleUtil = Polymer.StyleUtil; +return { +hasExtends: function (cssText) { +return Boolean(cssText.match(this.rx.EXTEND)); +}, +transform: function (style) { +var rules = styleUtil.rulesForStyle(style); +var self = this; +styleUtil.forEachStyleRule(rules, function (rule) { +var map = self._mapRule(rule); +if (rule.parent) { +var m; +while (m = self.rx.EXTEND.exec(rule.cssText)) { +var extend = m[1]; +var extendor = self._findExtendor(extend, rule); +if (extendor) { +self._extendRule(rule, extendor); +} +} +} +rule.cssText = rule.cssText.replace(self.rx.EXTEND, ''); +}); +return styleUtil.toCssText(rules, function (rule) { +if (rule.selector.match(self.rx.STRIP)) { +rule.cssText = ''; +} +}, true); +}, +_mapRule: function (rule) { +if (rule.parent) { +var map = rule.parent.map || (rule.parent.map = {}); +var parts = rule.selector.split(','); +for (var i = 0, p; i < parts.length; i++) { +p = parts[i]; +map[p.trim()] = rule; +} +return map; +} +}, +_findExtendor: function (extend, rule) { +return rule.parent && rule.parent.map && rule.parent.map[extend] || this._findExtendor(extend, rule.parent); +}, +_extendRule: function (target, source) { +if (target.parent !== source.parent) { +this._cloneAndAddRuleToParent(source, target.parent); +} +target.extends = target.extends || []; +target.extends.push(source); +source.selector = source.selector.replace(this.rx.STRIP, ''); +source.selector = (source.selector && source.selector + ',\n') + target.selector; +if (source.extends) { +source.extends.forEach(function (e) { +this._extendRule(target, e); +}, this); +} +}, +_cloneAndAddRuleToParent: function (rule, parent) { +rule = Object.create(rule); +rule.parent = parent; +if (rule.extends) { +rule.extends = rule.extends.slice(); +} +parent.rules.push(rule); +}, +rx: { +EXTEND: /@extends\(([^)]*)\)\s*?;/gim, +STRIP: /%[^,]*$/ +} +}; +}(); +(function () { +var prepElement = Polymer.Base._prepElement; +var nativeShadow = Polymer.Settings.useNativeShadow; +var styleUtil = Polymer.StyleUtil; +var styleTransformer = Polymer.StyleTransformer; +var styleExtends = Polymer.StyleExtends; +Polymer.Base._addFeature({ +_prepElement: function (element) { +if (this._encapsulateStyle) { +styleTransformer.element(element, this.is, this._scopeCssViaAttr); +} +prepElement.call(this, element); +}, +_prepStyles: function () { +if (this._encapsulateStyle === undefined) { +this._encapsulateStyle = !nativeShadow && Boolean(this._template); +} +if (this._template) { +this._styles = this._collectStyles(); +var cssText = styleTransformer.elementStyles(this); +if (cssText) { +var style = styleUtil.applyCss(cssText, this.is, nativeShadow ? this._template.content : null); +if (!nativeShadow) { +this._scopeStyle = style; +} +} +} else { +this._styles = []; +} +}, +_collectStyles: function () { +var styles = []; +var cssText = '', m$ = this.styleModules; +if (m$) { +for (var i = 0, l = m$.length, m; i < l && (m = m$[i]); i++) { +cssText += styleUtil.cssFromModule(m); +} +} +cssText += styleUtil.cssFromModule(this.is); +var p = this._template && this._template.parentNode; +if (this._template && (!p || p.id.toLowerCase() !== this.is)) { +cssText += styleUtil.cssFromElement(this._template); +} +if (cssText) { +var style = document.createElement('style'); +style.textContent = cssText; +if (styleExtends.hasExtends(style.textContent)) { +cssText = styleExtends.transform(style); +} +styles.push(style); +} +return styles; +}, +_elementAdd: function (node) { +if (this._encapsulateStyle) { +if (node.__styleScoped) { +node.__styleScoped = false; +} else { +styleTransformer.dom(node, this.is, this._scopeCssViaAttr); +} +} +}, +_elementRemove: function (node) { +if (this._encapsulateStyle) { +styleTransformer.dom(node, this.is, this._scopeCssViaAttr, true); +} +}, +scopeSubtree: function (container, shouldObserve) { +if (nativeShadow) { +return; +} +var self = this; +var scopify = function (node) { +if (node.nodeType === Node.ELEMENT_NODE) { +node.className = self._scopeElementClass(node, node.className); +var n$ = node.querySelectorAll('*'); +for (var i = 0, n; i < n$.length && (n = n$[i]); i++) { +n.className = self._scopeElementClass(n, n.className); +} +} +}; +scopify(container); +if (shouldObserve) { +var mo = new MutationObserver(function (mxns) { +for (var i = 0, m; i < mxns.length && (m = mxns[i]); i++) { +if (m.addedNodes) { +for (var j = 0; j < m.addedNodes.length; j++) { +scopify(m.addedNodes[j]); +} +} +} +}); +mo.observe(container, { +childList: true, +subtree: true +}); +return mo; +} +} +}); +}()); +Polymer.StyleProperties = function () { +'use strict'; +var nativeShadow = Polymer.Settings.useNativeShadow; +var matchesSelector = Polymer.DomApi.matchesSelector; +var styleUtil = Polymer.StyleUtil; +var styleTransformer = Polymer.StyleTransformer; +return { +decorateStyles: function (styles) { +var self = this, props = {}; +styleUtil.forRulesInStyles(styles, function (rule) { +self.decorateRule(rule); +self.collectPropertiesInCssText(rule.propertyInfo.cssText, props); +}); +var names = []; +for (var i in props) { +names.push(i); +} +return names; +}, +decorateRule: function (rule) { +if (rule.propertyInfo) { +return rule.propertyInfo; +} +var info = {}, properties = {}; +var hasProperties = this.collectProperties(rule, properties); +if (hasProperties) { +info.properties = properties; +rule.rules = null; +} +info.cssText = this.collectCssText(rule); +rule.propertyInfo = info; +return info; +}, +collectProperties: function (rule, properties) { +var info = rule.propertyInfo; +if (info) { +if (info.properties) { +Polymer.Base.mixin(properties, info.properties); +return true; +} +} else { +var m, rx = this.rx.VAR_ASSIGN; +var cssText = rule.parsedCssText; +var any; +while (m = rx.exec(cssText)) { +properties[m[1]] = (m[2] || m[3]).trim(); +any = true; +} +return any; +} +}, +collectCssText: function (rule) { +var customCssText = ''; +var cssText = rule.parsedCssText; +cssText = cssText.replace(this.rx.BRACKETED, '').replace(this.rx.VAR_ASSIGN, ''); +var parts = cssText.split(';'); +for (var i = 0, p; i < parts.length; i++) { +p = parts[i]; +if (p.match(this.rx.MIXIN_MATCH) || p.match(this.rx.VAR_MATCH)) { +customCssText += p + ';\n'; +} +} +return customCssText; +}, +collectPropertiesInCssText: function (cssText, props) { +var m; +while (m = this.rx.VAR_CAPTURE.exec(cssText)) { +props[m[1]] = true; +var def = m[2]; +if (def && def.match(this.rx.IS_VAR)) { +props[def] = true; +} +} +}, +reify: function (props) { +var names = Object.getOwnPropertyNames(props); +for (var i = 0, n; i < names.length; i++) { +n = names[i]; +props[n] = this.valueForProperty(props[n], props); +} +}, +valueForProperty: function (property, props) { +if (property) { +if (property.indexOf(';') >= 0) { +property = this.valueForProperties(property, props); +} else { +var self = this; +var fn = function (all, prefix, value, fallback) { +var propertyValue = self.valueForProperty(props[value], props) || (props[fallback] ? self.valueForProperty(props[fallback], props) : fallback); +return prefix + (propertyValue || ''); +}; +property = property.replace(this.rx.VAR_MATCH, fn); +} +} +return property && property.trim() || ''; +}, +valueForProperties: function (property, props) { +var parts = property.split(';'); +for (var i = 0, p, m; i < parts.length; i++) { +if (p = parts[i]) { +m = p.match(this.rx.MIXIN_MATCH); +if (m) { +p = this.valueForProperty(props[m[1]], props); +} else { +var pp = p.split(':'); +if (pp[1]) { +pp[1] = pp[1].trim(); +pp[1] = this.valueForProperty(pp[1], props) || pp[1]; +} +p = pp.join(':'); +} +parts[i] = p && p.lastIndexOf(';') === p.length - 1 ? p.slice(0, -1) : p || ''; +} +} +return parts.filter(function (v) { +return v; +}).join(';'); +}, +applyProperties: function (rule, props) { +var output = ''; +if (!rule.propertyInfo) { +this.decorateRule(rule); +} +if (rule.propertyInfo.cssText) { +output = this.valueForProperties(rule.propertyInfo.cssText, props); +} +rule.cssText = output; +}, +propertyDataFromStyles: function (styles, element) { +var props = {}, self = this; +var o = [], i = 0; +styleUtil.forRulesInStyles(styles, function (rule) { +if (!rule.propertyInfo) { +self.decorateRule(rule); +} +if (element && rule.propertyInfo.properties && matchesSelector.call(element, rule.transformedSelector || rule.parsedSelector)) { +self.collectProperties(rule, props); +addToBitMask(i, o); +} +i++; +}); +return { +properties: props, +key: o +}; +}, +scopePropertiesFromStyles: function (styles) { +if (!styles._scopeStyleProperties) { +styles._scopeStyleProperties = this.selectedPropertiesFromStyles(styles, this.SCOPE_SELECTORS); +} +return styles._scopeStyleProperties; +}, +hostPropertiesFromStyles: function (styles) { +if (!styles._hostStyleProperties) { +styles._hostStyleProperties = this.selectedPropertiesFromStyles(styles, this.HOST_SELECTORS); +} +return styles._hostStyleProperties; +}, +selectedPropertiesFromStyles: function (styles, selectors) { +var props = {}, self = this; +styleUtil.forRulesInStyles(styles, function (rule) { +if (!rule.propertyInfo) { +self.decorateRule(rule); +} +for (var i = 0; i < selectors.length; i++) { +if (rule.parsedSelector === selectors[i]) { +self.collectProperties(rule, props); +return; +} +} +}); +return props; +}, +transformStyles: function (element, properties, scopeSelector) { +var self = this; +var hostSelector = styleTransformer._calcHostScope(element.is, element.extends); +var rxHostSelector = element.extends ? '\\' + hostSelector.slice(0, -1) + '\\]' : hostSelector; +var hostRx = new RegExp(this.rx.HOST_PREFIX + rxHostSelector + this.rx.HOST_SUFFIX); +return styleTransformer.elementStyles(element, function (rule) { +self.applyProperties(rule, properties); +if (rule.cssText && !nativeShadow) { +self._scopeSelector(rule, hostRx, hostSelector, element._scopeCssViaAttr, scopeSelector); +} +}); +}, +_scopeSelector: function (rule, hostRx, hostSelector, viaAttr, scopeId) { +rule.transformedSelector = rule.transformedSelector || rule.selector; +var selector = rule.transformedSelector; +var scope = viaAttr ? '[' + styleTransformer.SCOPE_NAME + '~=' + scopeId + ']' : '.' + scopeId; +var parts = selector.split(','); +for (var i = 0, l = parts.length, p; i < l && (p = parts[i]); i++) { +parts[i] = p.match(hostRx) ? p.replace(hostSelector, hostSelector + scope) : scope + ' ' + p; +} +rule.selector = parts.join(','); +}, +applyElementScopeSelector: function (element, selector, old, viaAttr) { +var c = viaAttr ? element.getAttribute(styleTransformer.SCOPE_NAME) : element.className; +var v = old ? c.replace(old, selector) : (c ? c + ' ' : '') + this.XSCOPE_NAME + ' ' + selector; +if (c !== v) { +if (viaAttr) { +element.setAttribute(styleTransformer.SCOPE_NAME, v); +} else { +element.className = v; +} +} +}, +applyElementStyle: function (element, properties, selector, style) { +var cssText = style ? style.textContent || '' : this.transformStyles(element, properties, selector); +var s = element._customStyle; +if (s && !nativeShadow && s !== style) { +s._useCount--; +if (s._useCount <= 0 && s.parentNode) { +s.parentNode.removeChild(s); +} +} +if (nativeShadow || (!style || !style.parentNode)) { +if (nativeShadow && element._customStyle) { +element._customStyle.textContent = cssText; +style = element._customStyle; +} else if (cssText) { +style = styleUtil.applyCss(cssText, selector, nativeShadow ? element.root : null, element._scopeStyle); +} +} +if (style) { +style._useCount = style._useCount || 0; +if (element._customStyle != style) { +style._useCount++; +} +element._customStyle = style; +} +return style; +}, +mixinCustomStyle: function (props, customStyle) { +var v; +for (var i in customStyle) { +v = customStyle[i]; +if (v || v === 0) { +props[i] = v; +} +} +}, +rx: { +VAR_ASSIGN: /(?:^|[;\s{]\s*)(--[\w-]*?)\s*:\s*(?:([^;{]*)|{([^}]*)})(?:(?=[;\s}])|$)/gi, +MIXIN_MATCH: /(?:^|\W+)@apply[\s]*\(([^)]*)\)/i, +VAR_MATCH: /(^|\W+)var\([\s]*([^,)]*)[\s]*,?[\s]*((?:[^,)]*)|(?:[^;]*\([^;)]*\)))[\s]*?\)/gi, +VAR_CAPTURE: /\([\s]*(--[^,\s)]*)(?:,[\s]*(--[^,\s)]*))?(?:\)|,)/gi, +IS_VAR: /^--/, +BRACKETED: /\{[^}]*\}/g, +HOST_PREFIX: '(?:^|[^.#[:])', +HOST_SUFFIX: '($|[.:[\\s>+~])' +}, +HOST_SELECTORS: [':host'], +SCOPE_SELECTORS: [':root'], +XSCOPE_NAME: 'x-scope' +}; +function addToBitMask(n, bits) { +var o = parseInt(n / 32); +var v = 1 << n % 32; +bits[o] = (bits[o] || 0) | v; +} +}(); +(function () { +Polymer.StyleCache = function () { +this.cache = {}; +}; +Polymer.StyleCache.prototype = { +MAX: 100, +store: function (is, data, keyValues, keyStyles) { +data.keyValues = keyValues; +data.styles = keyStyles; +var s$ = this.cache[is] = this.cache[is] || []; +s$.push(data); +if (s$.length > this.MAX) { +s$.shift(); +} +}, +retrieve: function (is, keyValues, keyStyles) { +var cache = this.cache[is]; +if (cache) { +for (var i = cache.length - 1, data; i >= 0; i--) { +data = cache[i]; +if (keyStyles === data.styles && this._objectsEqual(keyValues, data.keyValues)) { +return data; +} +} +} +}, +clear: function () { +this.cache = {}; +}, +_objectsEqual: function (target, source) { +var t, s; +for (var i in target) { +t = target[i], s = source[i]; +if (!(typeof t === 'object' && t ? this._objectsStrictlyEqual(t, s) : t === s)) { +return false; +} +} +if (Array.isArray(target)) { +return target.length === source.length; +} +return true; +}, +_objectsStrictlyEqual: function (target, source) { +return this._objectsEqual(target, source) && this._objectsEqual(source, target); +} +}; +}()); +Polymer.StyleDefaults = function () { +var styleProperties = Polymer.StyleProperties; +var styleUtil = Polymer.StyleUtil; +var StyleCache = Polymer.StyleCache; +var api = { +_styles: [], +_properties: null, +customStyle: {}, +_styleCache: new StyleCache(), +addStyle: function (style) { +this._styles.push(style); +this._properties = null; +}, +get _styleProperties() { +if (!this._properties) { +styleProperties.decorateStyles(this._styles); +this._styles._scopeStyleProperties = null; +this._properties = styleProperties.scopePropertiesFromStyles(this._styles); +styleProperties.mixinCustomStyle(this._properties, this.customStyle); +styleProperties.reify(this._properties); +} +return this._properties; +}, +_needsStyleProperties: function () { +}, +_computeStyleProperties: function () { +return this._styleProperties; +}, +updateStyles: function (properties) { +this._properties = null; +if (properties) { +Polymer.Base.mixin(this.customStyle, properties); +} +this._styleCache.clear(); +for (var i = 0, s; i < this._styles.length; i++) { +s = this._styles[i]; +s = s.__importElement || s; +s._apply(); +} +} +}; +return api; +}(); +(function () { +'use strict'; +var serializeValueToAttribute = Polymer.Base.serializeValueToAttribute; +var propertyUtils = Polymer.StyleProperties; +var styleTransformer = Polymer.StyleTransformer; +var styleUtil = Polymer.StyleUtil; +var styleDefaults = Polymer.StyleDefaults; +var nativeShadow = Polymer.Settings.useNativeShadow; +Polymer.Base._addFeature({ +_prepStyleProperties: function () { +this._ownStylePropertyNames = this._styles ? propertyUtils.decorateStyles(this._styles) : null; +}, +customStyle: null, +getComputedStyleValue: function (property) { +return this._styleProperties && this._styleProperties[property] || getComputedStyle(this).getPropertyValue(property); +}, +_setupStyleProperties: function () { +this.customStyle = {}; +}, +_needsStyleProperties: function () { +return Boolean(this._ownStylePropertyNames && this._ownStylePropertyNames.length); +}, +_beforeAttached: function () { +if (!this._scopeSelector && this._needsStyleProperties()) { +this._updateStyleProperties(); +} +}, +_findStyleHost: function () { +var e = this, root; +while (root = Polymer.dom(e).getOwnerRoot()) { +if (Polymer.isInstance(root.host)) { +return root.host; +} +e = root.host; +} +return styleDefaults; +}, +_updateStyleProperties: function () { +var info, scope = this._findStyleHost(); +if (!scope._styleCache) { +scope._styleCache = new Polymer.StyleCache(); +} +var scopeData = propertyUtils.propertyDataFromStyles(scope._styles, this); +scopeData.key.customStyle = this.customStyle; +info = scope._styleCache.retrieve(this.is, scopeData.key, this._styles); +var scopeCached = Boolean(info); +if (scopeCached) { +this._styleProperties = info._styleProperties; +} else { +this._computeStyleProperties(scopeData.properties); +} +this._computeOwnStyleProperties(); +if (!scopeCached) { +info = styleCache.retrieve(this.is, this._ownStyleProperties, this._styles); +} +var globalCached = Boolean(info) && !scopeCached; +var style = this._applyStyleProperties(info); +if (!scopeCached) { +style = style && nativeShadow ? style.cloneNode(true) : style; +info = { +style: style, +_scopeSelector: this._scopeSelector, +_styleProperties: this._styleProperties +}; +scopeData.key.customStyle = {}; +this.mixin(scopeData.key.customStyle, this.customStyle); +scope._styleCache.store(this.is, info, scopeData.key, this._styles); +if (!globalCached) { +styleCache.store(this.is, Object.create(info), this._ownStyleProperties, this._styles); +} +} +}, +_computeStyleProperties: function (scopeProps) { +var scope = this._findStyleHost(); +if (!scope._styleProperties) { +scope._computeStyleProperties(); +} +var props = Object.create(scope._styleProperties); +this.mixin(props, propertyUtils.hostPropertiesFromStyles(this._styles)); +scopeProps = scopeProps || propertyUtils.propertyDataFromStyles(scope._styles, this).properties; +this.mixin(props, scopeProps); +this.mixin(props, propertyUtils.scopePropertiesFromStyles(this._styles)); +propertyUtils.mixinCustomStyle(props, this.customStyle); +propertyUtils.reify(props); +this._styleProperties = props; +}, +_computeOwnStyleProperties: function () { +var props = {}; +for (var i = 0, n; i < this._ownStylePropertyNames.length; i++) { +n = this._ownStylePropertyNames[i]; +props[n] = this._styleProperties[n]; +} +this._ownStyleProperties = props; +}, +_scopeCount: 0, +_applyStyleProperties: function (info) { +var oldScopeSelector = this._scopeSelector; +this._scopeSelector = info ? info._scopeSelector : this.is + '-' + this.__proto__._scopeCount++; +var style = propertyUtils.applyElementStyle(this, this._styleProperties, this._scopeSelector, info && info.style); +if (!nativeShadow) { +propertyUtils.applyElementScopeSelector(this, this._scopeSelector, oldScopeSelector, this._scopeCssViaAttr); +} +return style; +}, +serializeValueToAttribute: function (value, attribute, node) { +node = node || this; +if (attribute === 'class' && !nativeShadow) { +var host = node === this ? this.domHost || this.dataHost : this; +if (host) { +value = host._scopeElementClass(node, value); +} +} +node = this.shadyRoot && this.shadyRoot._hasDistributed ? Polymer.dom(node) : node; +serializeValueToAttribute.call(this, value, attribute, node); +}, +_scopeElementClass: function (element, selector) { +if (!nativeShadow && !this._scopeCssViaAttr) { +selector += (selector ? ' ' : '') + SCOPE_NAME + ' ' + this.is + (element._scopeSelector ? ' ' + XSCOPE_NAME + ' ' + element._scopeSelector : ''); +} +return selector; +}, +updateStyles: function (properties) { +if (this.isAttached) { +if (properties) { +this.mixin(this.customStyle, properties); +} +if (this._needsStyleProperties()) { +this._updateStyleProperties(); +} else { +this._styleProperties = null; +} +if (this._styleCache) { +this._styleCache.clear(); +} +this._updateRootStyles(); +} +}, +_updateRootStyles: function (root) { +root = root || this.root; +var c$ = Polymer.dom(root)._query(function (e) { +return e.shadyRoot || e.shadowRoot; +}); +for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) { +if (c.updateStyles) { +c.updateStyles(); +} +} +} +}); +Polymer.updateStyles = function (properties) { +styleDefaults.updateStyles(properties); +Polymer.Base._updateRootStyles(document); +}; +var styleCache = new Polymer.StyleCache(); +Polymer.customStyleCache = styleCache; +var SCOPE_NAME = styleTransformer.SCOPE_NAME; +var XSCOPE_NAME = propertyUtils.XSCOPE_NAME; +}()); +Polymer.Base._addFeature({ +_registerFeatures: function () { +this._prepIs(); +this._prepConstructor(); +this._prepTemplate(); +this._prepStyles(); +this._prepStyleProperties(); +this._prepAnnotations(); +this._prepEffects(); +this._prepBehaviors(); +this._prepPropertyInfo(); +this._prepBindings(); +this._prepShady(); +}, +_prepBehavior: function (b) { +this._addPropertyEffects(b.properties); +this._addComplexObserverEffects(b.observers); +this._addHostAttributes(b.hostAttributes); +}, +_initFeatures: function () { +this._setupConfigure(); +this._setupStyleProperties(); +this._setupDebouncers(); +this._registerHost(); +if (this._template) { +this._poolContent(); +this._beginHosting(); +this._stampTemplate(); +this._endHosting(); +this._marshalAnnotationReferences(); +} +this._marshalInstanceEffects(); +this._marshalBehaviors(); +this._marshalHostAttributes(); +this._marshalAttributes(); +this._tryReady(); +}, +_marshalBehavior: function (b) { +if (b.listeners) { +this._listenListeners(b.listeners); +} +} +}); +(function () { +var nativeShadow = Polymer.Settings.useNativeShadow; +var propertyUtils = Polymer.StyleProperties; +var styleUtil = Polymer.StyleUtil; +var cssParse = Polymer.CssParse; +var styleDefaults = Polymer.StyleDefaults; +var styleTransformer = Polymer.StyleTransformer; +Polymer({ +is: 'custom-style', +extends: 'style', +_template: null, +properties: { include: String }, +ready: function () { +this._tryApply(); +}, +attached: function () { +this._tryApply(); +}, +_tryApply: function () { +if (!this._appliesToDocument) { +if (this.parentNode && this.parentNode.localName !== 'dom-module') { +this._appliesToDocument = true; +var e = this.__appliedElement || this; +styleDefaults.addStyle(e); +if (e.textContent || this.include) { +this._apply(true); +} else { +var self = this; +var observer = new MutationObserver(function () { +observer.disconnect(); +self._apply(true); +}); +observer.observe(e, { childList: true }); +} +} +} +}, +_apply: function (deferProperties) { +var e = this.__appliedElement || this; +if (this.include) { +e.textContent = styleUtil.cssFromModules(this.include, true) + e.textContent; +} +if (e.textContent) { +styleUtil.forEachStyleRule(styleUtil.rulesForStyle(e), function (rule) { +styleTransformer.documentRule(rule); +}); +var self = this; +function fn() { +self._applyCustomProperties(e); +} +if (this._pendingApplyProperties) { +cancelAnimationFrame(this._pendingApplyProperties); +this._pendingApplyProperties = null; +} +if (deferProperties) { +this._pendingApplyProperties = requestAnimationFrame(fn); +} else { +fn(); +} +} +}, +_applyCustomProperties: function (element) { +this._computeStyleProperties(); +var props = this._styleProperties; +var rules = styleUtil.rulesForStyle(element); +element.textContent = styleUtil.toCssText(rules, function (rule) { +var css = rule.cssText = rule.parsedCssText; +if (rule.propertyInfo && rule.propertyInfo.cssText) { +css = cssParse.removeCustomPropAssignment(css); +rule.cssText = propertyUtils.valueForProperties(css, props); +} +}); +} +}); +}()); +Polymer.Templatizer = { +properties: { __hideTemplateChildren__: { observer: '_showHideChildren' } }, +_instanceProps: Polymer.nob, +_parentPropPrefix: '_parent_', +templatize: function (template) { +this._templatized = template; +if (!template._content) { +template._content = template.content; +} +if (template._content._ctor) { +this.ctor = template._content._ctor; +this._prepParentProperties(this.ctor.prototype, template); +return; +} +var archetype = Object.create(Polymer.Base); +this._customPrepAnnotations(archetype, template); +this._prepParentProperties(archetype, template); +archetype._prepEffects(); +this._customPrepEffects(archetype); +archetype._prepBehaviors(); +archetype._prepPropertyInfo(); +archetype._prepBindings(); +archetype._notifyPathUp = this._notifyPathUpImpl; +archetype._scopeElementClass = this._scopeElementClassImpl; +archetype.listen = this._listenImpl; +archetype._showHideChildren = this._showHideChildrenImpl; +var _constructor = this._constructorImpl; +var ctor = function TemplateInstance(model, host) { +_constructor.call(this, model, host); +}; +ctor.prototype = archetype; +archetype.constructor = ctor; +template._content._ctor = ctor; +this.ctor = ctor; +}, +_getRootDataHost: function () { +return this.dataHost && this.dataHost._rootDataHost || this.dataHost; +}, +_showHideChildrenImpl: function (hide) { +var c = this._children; +for (var i = 0; i < c.length; i++) { +var n = c[i]; +if (Boolean(hide) != Boolean(n.__hideTemplateChildren__)) { +if (n.nodeType === Node.TEXT_NODE) { +if (hide) { +n.__polymerTextContent__ = n.textContent; +n.textContent = ''; +} else { +n.textContent = n.__polymerTextContent__; +} +} else if (n.style) { +if (hide) { +n.__polymerDisplay__ = n.style.display; +n.style.display = 'none'; +} else { +n.style.display = n.__polymerDisplay__; +} +} +} +n.__hideTemplateChildren__ = hide; +} +}, +_debounceTemplate: function (fn) { +Polymer.dom.addDebouncer(this.debounce('_debounceTemplate', fn)); +}, +_flushTemplates: function (debouncerExpired) { +Polymer.dom.flush(); +}, +_customPrepEffects: function (archetype) { +var parentProps = archetype._parentProps; +for (var prop in parentProps) { +archetype._addPropertyEffect(prop, 'function', this._createHostPropEffector(prop)); +} +for (var prop in this._instanceProps) { +archetype._addPropertyEffect(prop, 'function', this._createInstancePropEffector(prop)); +} +}, +_customPrepAnnotations: function (archetype, template) { +archetype._template = template; +var c = template._content; +if (!c._notes) { +var rootDataHost = archetype._rootDataHost; +if (rootDataHost) { +Polymer.Annotations.prepElement = function () { +rootDataHost._prepElement(); +}; +} +c._notes = Polymer.Annotations.parseAnnotations(template); +Polymer.Annotations.prepElement = null; +this._processAnnotations(c._notes); +} +archetype._notes = c._notes; +archetype._parentProps = c._parentProps; +}, +_prepParentProperties: function (archetype, template) { +var parentProps = this._parentProps = archetype._parentProps; +if (this._forwardParentProp && parentProps) { +var proto = archetype._parentPropProto; +var prop; +if (!proto) { +for (prop in this._instanceProps) { +delete parentProps[prop]; +} +proto = archetype._parentPropProto = Object.create(null); +if (template != this) { +Polymer.Bind.prepareModel(proto); +Polymer.Base.prepareModelNotifyPath(proto); +} +for (prop in parentProps) { +var parentProp = this._parentPropPrefix + prop; +var effects = [ +{ +kind: 'function', +effect: this._createForwardPropEffector(prop), +fn: Polymer.Bind._functionEffect +}, +{ +kind: 'notify', +fn: Polymer.Bind._notifyEffect, +effect: { event: Polymer.CaseMap.camelToDashCase(parentProp) + '-changed' } +} +]; +Polymer.Bind._createAccessors(proto, parentProp, effects); +} +} +var self = this; +if (template != this) { +Polymer.Bind.prepareInstance(template); +template._forwardParentProp = function (source, value) { +self._forwardParentProp(source, value); +}; +} +this._extendTemplate(template, proto); +template._pathEffector = function (path, value, fromAbove) { +return self._pathEffectorImpl(path, value, fromAbove); +}; +} +}, +_createForwardPropEffector: function (prop) { +return function (source, value) { +this._forwardParentProp(prop, value); +}; +}, +_createHostPropEffector: function (prop) { +var prefix = this._parentPropPrefix; +return function (source, value) { +this.dataHost._templatized[prefix + prop] = value; +}; +}, +_createInstancePropEffector: function (prop) { +return function (source, value, old, fromAbove) { +if (!fromAbove) { +this.dataHost._forwardInstanceProp(this, prop, value); +} +}; +}, +_extendTemplate: function (template, proto) { +var n$ = Object.getOwnPropertyNames(proto); +for (var i = 0, n; i < n$.length && (n = n$[i]); i++) { +var val = template[n]; +var pd = Object.getOwnPropertyDescriptor(proto, n); +Object.defineProperty(template, n, pd); +if (val !== undefined) { +template._propertySetter(n, val); +} +} +}, +_showHideChildren: function (hidden) { +}, +_forwardInstancePath: function (inst, path, value) { +}, +_forwardInstanceProp: function (inst, prop, value) { +}, +_notifyPathUpImpl: function (path, value) { +var dataHost = this.dataHost; +var dot = path.indexOf('.'); +var root = dot < 0 ? path : path.slice(0, dot); +dataHost._forwardInstancePath.call(dataHost, this, path, value); +if (root in dataHost._parentProps) { +dataHost._templatized.notifyPath(dataHost._parentPropPrefix + path, value); +} +}, +_pathEffectorImpl: function (path, value, fromAbove) { +if (this._forwardParentPath) { +if (path.indexOf(this._parentPropPrefix) === 0) { +var subPath = path.substring(this._parentPropPrefix.length); +var model = this._modelForPath(subPath); +if (model in this._parentProps) { +this._forwardParentPath(subPath, value); +} +} +} +Polymer.Base._pathEffector.call(this._templatized, path, value, fromAbove); +}, +_constructorImpl: function (model, host) { +this._rootDataHost = host._getRootDataHost(); +this._setupConfigure(model); +this._registerHost(host); +this._beginHosting(); +this.root = this.instanceTemplate(this._template); +this.root.__noContent = !this._notes._hasContent; +this.root.__styleScoped = true; +this._endHosting(); +this._marshalAnnotatedNodes(); +this._marshalInstanceEffects(); +this._marshalAnnotatedListeners(); +var children = []; +for (var n = this.root.firstChild; n; n = n.nextSibling) { +children.push(n); +n._templateInstance = this; +} +this._children = children; +if (host.__hideTemplateChildren__) { +this._showHideChildren(true); +} +this._tryReady(); +}, +_listenImpl: function (node, eventName, methodName) { +var model = this; +var host = this._rootDataHost; +var handler = host._createEventHandler(node, eventName, methodName); +var decorated = function (e) { +e.model = model; +handler(e); +}; +host._listen(node, eventName, decorated); +}, +_scopeElementClassImpl: function (node, value) { +var host = this._rootDataHost; +if (host) { +return host._scopeElementClass(node, value); +} +}, +stamp: function (model) { +model = model || {}; +if (this._parentProps) { +var templatized = this._templatized; +for (var prop in this._parentProps) { +model[prop] = templatized[this._parentPropPrefix + prop]; +} +} +return new this.ctor(model, this); +}, +modelForElement: function (el) { +var model; +while (el) { +if (model = el._templateInstance) { +if (model.dataHost != this) { +el = model.dataHost; +} else { +return model; +} +} else { +el = el.parentNode; +} +} +} +}; +Polymer({ +is: 'dom-template', +extends: 'template', +_template: null, +behaviors: [Polymer.Templatizer], +ready: function () { +this.templatize(this); +} +}); +Polymer._collections = new WeakMap(); +Polymer.Collection = function (userArray) { +Polymer._collections.set(userArray, this); +this.userArray = userArray; +this.store = userArray.slice(); +this.initMap(); +}; +Polymer.Collection.prototype = { +constructor: Polymer.Collection, +initMap: function () { +var omap = this.omap = new WeakMap(); +var pmap = this.pmap = {}; +var s = this.store; +for (var i = 0; i < s.length; i++) { +var item = s[i]; +if (item && typeof item == 'object') { +omap.set(item, i); +} else { +pmap[item] = i; +} +} +}, +add: function (item) { +var key = this.store.push(item) - 1; +if (item && typeof item == 'object') { +this.omap.set(item, key); +} else { +this.pmap[item] = key; +} +return '#' + key; +}, +removeKey: function (key) { +key = this._parseKey(key); +this._removeFromMap(this.store[key]); +delete this.store[key]; +}, +_removeFromMap: function (item) { +if (item && typeof item == 'object') { +this.omap.delete(item); +} else { +delete this.pmap[item]; +} +}, +remove: function (item) { +var key = this.getKey(item); +this.removeKey(key); +return key; +}, +getKey: function (item) { +var key; +if (item && typeof item == 'object') { +key = this.omap.get(item); +} else { +key = this.pmap[item]; +} +if (key != undefined) { +return '#' + key; +} +}, +getKeys: function () { +return Object.keys(this.store).map(function (key) { +return '#' + key; +}); +}, +_parseKey: function (key) { +if (key[0] == '#') { +return key.slice(1); +} +throw new Error('unexpected key ' + key); +}, +setItem: function (key, item) { +key = this._parseKey(key); +var old = this.store[key]; +if (old) { +this._removeFromMap(old); +} +if (item && typeof item == 'object') { +this.omap.set(item, key); +} else { +this.pmap[item] = key; +} +this.store[key] = item; +}, +getItem: function (key) { +key = this._parseKey(key); +return this.store[key]; +}, +getItems: function () { +var items = [], store = this.store; +for (var key in store) { +items.push(store[key]); +} +return items; +}, +_applySplices: function (splices) { +var keyMap = {}, key; +for (var i = 0, s; i < splices.length && (s = splices[i]); i++) { +s.addedKeys = []; +for (var j = 0; j < s.removed.length; j++) { +key = this.getKey(s.removed[j]); +keyMap[key] = keyMap[key] ? null : -1; +} +for (var j = 0; j < s.addedCount; j++) { +var item = this.userArray[s.index + j]; +key = this.getKey(item); +key = key === undefined ? this.add(item) : key; +keyMap[key] = keyMap[key] ? null : 1; +s.addedKeys.push(key); +} +} +var removed = []; +var added = []; +for (var key in keyMap) { +if (keyMap[key] < 0) { +this.removeKey(key); +removed.push(key); +} +if (keyMap[key] > 0) { +added.push(key); +} +} +return [{ +removed: removed, +added: added +}]; +} +}; +Polymer.Collection.get = function (userArray) { +return Polymer._collections.get(userArray) || new Polymer.Collection(userArray); +}; +Polymer.Collection.applySplices = function (userArray, splices) { +var coll = Polymer._collections.get(userArray); +return coll ? coll._applySplices(splices) : null; +}; +Polymer({ +is: 'dom-repeat', +extends: 'template', +_template: null, +properties: { +items: { type: Array }, +as: { +type: String, +value: 'item' +}, +indexAs: { +type: String, +value: 'index' +}, +sort: { +type: Function, +observer: '_sortChanged' +}, +filter: { +type: Function, +observer: '_filterChanged' +}, +observe: { +type: String, +observer: '_observeChanged' +}, +delay: Number, +initialCount: { +type: Number, +observer: '_initializeChunking' +}, +targetFramerate: { +type: Number, +value: 20 +}, +_targetFrameTime: { computed: '_computeFrameTime(targetFramerate)' } +}, +behaviors: [Polymer.Templatizer], +observers: ['_itemsChanged(items.*)'], +created: function () { +this._instances = []; +this._pool = []; +this._limit = Infinity; +var self = this; +this._boundRenderChunk = function () { +self._renderChunk(); +}; +}, +detached: function () { +for (var i = 0; i < this._instances.length; i++) { +this._detachInstance(i); +} +}, +attached: function () { +var parent = Polymer.dom(Polymer.dom(this).parentNode); +for (var i = 0; i < this._instances.length; i++) { +this._attachInstance(i, parent); +} +}, +ready: function () { +this._instanceProps = { __key__: true }; +this._instanceProps[this.as] = true; +this._instanceProps[this.indexAs] = true; +if (!this.ctor) { +this.templatize(this); +} +}, +_sortChanged: function (sort) { +var dataHost = this._getRootDataHost(); +this._sortFn = sort && (typeof sort == 'function' ? sort : function () { +return dataHost[sort].apply(dataHost, arguments); +}); +this._needFullRefresh = true; +if (this.items) { +this._debounceTemplate(this._render); +} +}, +_filterChanged: function (filter) { +var dataHost = this._getRootDataHost(); +this._filterFn = filter && (typeof filter == 'function' ? filter : function () { +return dataHost[filter].apply(dataHost, arguments); +}); +this._needFullRefresh = true; +if (this.items) { +this._debounceTemplate(this._render); +} +}, +_computeFrameTime: function (rate) { +return Math.ceil(1000 / rate); +}, +_initializeChunking: function () { +if (this.initialCount) { +this._limit = this.initialCount; +this._chunkCount = this.initialCount; +this._lastChunkTime = performance.now(); +} +}, +_tryRenderChunk: function () { +if (this.items && this._limit < this.items.length) { +this.debounce('renderChunk', this._requestRenderChunk); +} +}, +_requestRenderChunk: function () { +requestAnimationFrame(this._boundRenderChunk); +}, +_renderChunk: function () { +var currChunkTime = performance.now(); +var ratio = this._targetFrameTime / (currChunkTime - this._lastChunkTime); +this._chunkCount = Math.round(this._chunkCount * ratio) || 1; +this._limit += this._chunkCount; +this._lastChunkTime = currChunkTime; +this._debounceTemplate(this._render); +}, +_observeChanged: function () { +this._observePaths = this.observe && this.observe.replace('.*', '.').split(' '); +}, +_itemsChanged: function (change) { +if (change.path == 'items') { +if (Array.isArray(this.items)) { +this.collection = Polymer.Collection.get(this.items); +} else if (!this.items) { +this.collection = null; +} else { +this._error(this._logf('dom-repeat', 'expected array for `items`,' + ' found', this.items)); +} +this._keySplices = []; +this._indexSplices = []; +this._needFullRefresh = true; +this._initializeChunking(); +this._debounceTemplate(this._render); +} else if (change.path == 'items.splices') { +this._keySplices = this._keySplices.concat(change.value.keySplices); +this._indexSplices = this._indexSplices.concat(change.value.indexSplices); +this._debounceTemplate(this._render); +} else { +var subpath = change.path.slice(6); +this._forwardItemPath(subpath, change.value); +this._checkObservedPaths(subpath); +} +}, +_checkObservedPaths: function (path) { +if (this._observePaths) { +path = path.substring(path.indexOf('.') + 1); +var paths = this._observePaths; +for (var i = 0; i < paths.length; i++) { +if (path.indexOf(paths[i]) === 0) { +this._needFullRefresh = true; +if (this.delay) { +this.debounce('render', this._render, this.delay); +} else { +this._debounceTemplate(this._render); +} +return; +} +} +} +}, +render: function () { +this._needFullRefresh = true; +this._debounceTemplate(this._render); +this._flushTemplates(); +}, +_render: function () { +var c = this.collection; +if (this._needFullRefresh) { +this._applyFullRefresh(); +this._needFullRefresh = false; +} else if (this._keySplices.length) { +if (this._sortFn) { +this._applySplicesUserSort(this._keySplices); +} else { +if (this._filterFn) { +this._applyFullRefresh(); +} else { +this._applySplicesArrayOrder(this._indexSplices); +} +} +} else { +} +this._keySplices = []; +this._indexSplices = []; +var keyToIdx = this._keyToInstIdx = {}; +for (var i = this._instances.length - 1; i >= 0; i--) { +var inst = this._instances[i]; +if (inst.isPlaceholder && i < this._limit) { +inst = this._insertInstance(i, inst.__key__); +} else if (!inst.isPlaceholder && i >= this._limit) { +inst = this._downgradeInstance(i, inst.__key__); +} +keyToIdx[inst.__key__] = i; +if (!inst.isPlaceholder) { +inst.__setProperty(this.indexAs, i, true); +} +} +this._pool.length = 0; +this.fire('dom-change'); +this._tryRenderChunk(); +}, +_applyFullRefresh: function () { +var c = this.collection; +var keys; +if (this._sortFn) { +keys = c ? c.getKeys() : []; +} else { +keys = []; +var items = this.items; +if (items) { +for (var i = 0; i < items.length; i++) { +keys.push(c.getKey(items[i])); +} +} +} +var self = this; +if (this._filterFn) { +keys = keys.filter(function (a) { +return self._filterFn(c.getItem(a)); +}); +} +if (this._sortFn) { +keys.sort(function (a, b) { +return self._sortFn(c.getItem(a), c.getItem(b)); +}); +} +for (var i = 0; i < keys.length; i++) { +var key = keys[i]; +var inst = this._instances[i]; +if (inst) { +inst.__key__ = key; +if (!inst.isPlaceholder && i < this._limit) { +inst.__setProperty(this.as, c.getItem(key), true); +} +} else if (i < this._limit) { +this._insertInstance(i, key); +} else { +this._insertPlaceholder(i, key); +} +} +for (var j = this._instances.length - 1; j >= i; j--) { +this._detachAndRemoveInstance(j); +} +}, +_numericSort: function (a, b) { +return a - b; +}, +_applySplicesUserSort: function (splices) { +var c = this.collection; +var instances = this._instances; +var keyMap = {}; +for (var i = 0, s; i < splices.length && (s = splices[i]); i++) { +for (var j = 0; j < s.removed.length; j++) { +var key = s.removed[j]; +keyMap[key] = keyMap[key] ? null : -1; +} +for (var j = 0; j < s.added.length; j++) { +var key = s.added[j]; +keyMap[key] = keyMap[key] ? null : 1; +} +} +var removedIdxs = []; +var addedKeys = []; +for (var key in keyMap) { +if (keyMap[key] === -1) { +removedIdxs.push(this._keyToInstIdx[key]); +} +if (keyMap[key] === 1) { +addedKeys.push(key); +} +} +if (removedIdxs.length) { +removedIdxs.sort(this._numericSort); +for (var i = removedIdxs.length - 1; i >= 0; i--) { +var idx = removedIdxs[i]; +if (idx !== undefined) { +this._detachAndRemoveInstance(idx); +} +} +} +var self = this; +if (addedKeys.length) { +if (this._filterFn) { +addedKeys = addedKeys.filter(function (a) { +return self._filterFn(c.getItem(a)); +}); +} +addedKeys.sort(function (a, b) { +return self._sortFn(c.getItem(a), c.getItem(b)); +}); +var start = 0; +for (var i = 0; i < addedKeys.length; i++) { +start = this._insertRowUserSort(start, addedKeys[i]); +} +} +}, +_insertRowUserSort: function (start, key) { +var c = this.collection; +var item = c.getItem(key); +var end = this._instances.length - 1; +var idx = -1; +while (start <= end) { +var mid = start + end >> 1; +var midKey = this._instances[mid].__key__; +var cmp = this._sortFn(c.getItem(midKey), item); +if (cmp < 0) { +start = mid + 1; +} else if (cmp > 0) { +end = mid - 1; +} else { +idx = mid; +break; +} +} +if (idx < 0) { +idx = end + 1; +} +this._insertPlaceholder(idx, key); +return idx; +}, +_applySplicesArrayOrder: function (splices) { +var c = this.collection; +for (var i = 0, s; i < splices.length && (s = splices[i]); i++) { +for (var j = 0; j < s.removed.length; j++) { +this._detachAndRemoveInstance(s.index); +} +for (var j = 0; j < s.addedKeys.length; j++) { +this._insertPlaceholder(s.index + j, s.addedKeys[j]); +} +} +}, +_detachInstance: function (idx) { +var inst = this._instances[idx]; +if (!inst.isPlaceholder) { +for (var i = 0; i < inst._children.length; i++) { +var el = inst._children[i]; +Polymer.dom(inst.root).appendChild(el); +} +return inst; +} +}, +_attachInstance: function (idx, parent) { +var inst = this._instances[idx]; +if (!inst.isPlaceholder) { +parent.insertBefore(inst.root, this); +} +}, +_detachAndRemoveInstance: function (idx) { +var inst = this._detachInstance(idx); +if (inst) { +this._pool.push(inst); +} +this._instances.splice(idx, 1); +}, +_insertPlaceholder: function (idx, key) { +this._instances.splice(idx, 0, { +isPlaceholder: true, +__key__: key +}); +}, +_stampInstance: function (idx, key) { +var model = { __key__: key }; +model[this.as] = this.collection.getItem(key); +model[this.indexAs] = idx; +return this.stamp(model); +}, +_insertInstance: function (idx, key) { +var inst = this._pool.pop(); +if (inst) { +inst.__setProperty(this.as, this.collection.getItem(key), true); +inst.__setProperty('__key__', key, true); +} else { +inst = this._stampInstance(idx, key); +} +var beforeRow = this._instances[idx + 1]; +var beforeNode = beforeRow && !beforeRow.isPlaceholder ? beforeRow._children[0] : this; +var parentNode = Polymer.dom(this).parentNode; +Polymer.dom(parentNode).insertBefore(inst.root, beforeNode); +this._instances[idx] = inst; +return inst; +}, +_downgradeInstance: function (idx, key) { +var inst = this._detachInstance(idx); +if (inst) { +this._pool.push(inst); +} +inst = { +isPlaceholder: true, +__key__: key +}; +this._instances[idx] = inst; +return inst; +}, +_showHideChildren: function (hidden) { +for (var i = 0; i < this._instances.length; i++) { +this._instances[i]._showHideChildren(hidden); +} +}, +_forwardInstanceProp: function (inst, prop, value) { +if (prop == this.as) { +var idx; +if (this._sortFn || this._filterFn) { +idx = this.items.indexOf(this.collection.getItem(inst.__key__)); +} else { +idx = inst[this.indexAs]; +} +this.set('items.' + idx, value); +} +}, +_forwardInstancePath: function (inst, path, value) { +if (path.indexOf(this.as + '.') === 0) { +this._notifyPath('items.' + inst.__key__ + '.' + path.slice(this.as.length + 1), value); +} +}, +_forwardParentProp: function (prop, value) { +var i$ = this._instances; +for (var i = 0, inst; i < i$.length && (inst = i$[i]); i++) { +if (!inst.isPlaceholder) { +inst.__setProperty(prop, value, true); +} +} +}, +_forwardParentPath: function (path, value) { +var i$ = this._instances; +for (var i = 0, inst; i < i$.length && (inst = i$[i]); i++) { +if (!inst.isPlaceholder) { +inst._notifyPath(path, value, true); +} +} +}, +_forwardItemPath: function (path, value) { +if (this._keyToInstIdx) { +var dot = path.indexOf('.'); +var key = path.substring(0, dot < 0 ? path.length : dot); +var idx = this._keyToInstIdx[key]; +var inst = this._instances[idx]; +if (inst && !inst.isPlaceholder) { +if (dot >= 0) { +path = this.as + '.' + path.substring(dot + 1); +inst._notifyPath(path, value, true); +} else { +inst.__setProperty(this.as, value, true); +} +} +} +}, +itemForElement: function (el) { +var instance = this.modelForElement(el); +return instance && instance[this.as]; +}, +keyForElement: function (el) { +var instance = this.modelForElement(el); +return instance && instance.__key__; +}, +indexForElement: function (el) { +var instance = this.modelForElement(el); +return instance && instance[this.indexAs]; +} +}); +Polymer({ +is: 'array-selector', +_template: null, +properties: { +items: { +type: Array, +observer: 'clearSelection' +}, +multi: { +type: Boolean, +value: false, +observer: 'clearSelection' +}, +selected: { +type: Object, +notify: true +}, +selectedItem: { +type: Object, +notify: true +}, +toggle: { +type: Boolean, +value: false +} +}, +clearSelection: function () { +if (Array.isArray(this.selected)) { +for (var i = 0; i < this.selected.length; i++) { +this.unlinkPaths('selected.' + i); +} +} else { +this.unlinkPaths('selected'); +this.unlinkPaths('selectedItem'); +} +if (this.multi) { +if (!this.selected || this.selected.length) { +this.selected = []; +this._selectedColl = Polymer.Collection.get(this.selected); +} +} else { +this.selected = null; +this._selectedColl = null; +} +this.selectedItem = null; +}, +isSelected: function (item) { +if (this.multi) { +return this._selectedColl.getKey(item) !== undefined; +} else { +return this.selected == item; +} +}, +deselect: function (item) { +if (this.multi) { +if (this.isSelected(item)) { +var skey = this._selectedColl.getKey(item); +this.arrayDelete('selected', item); +this.unlinkPaths('selected.' + skey); +} +} else { +this.selected = null; +this.selectedItem = null; +this.unlinkPaths('selected'); +this.unlinkPaths('selectedItem'); +} +}, +select: function (item) { +var icol = Polymer.Collection.get(this.items); +var key = icol.getKey(item); +if (this.multi) { +if (this.isSelected(item)) { +if (this.toggle) { +this.deselect(item); +} +} else { +this.push('selected', item); +var skey = this._selectedColl.getKey(item); +this.linkPaths('selected.' + skey, 'items.' + key); +} +} else { +if (this.toggle && item == this.selected) { +this.deselect(); +} else { +this.selected = item; +this.selectedItem = item; +this.linkPaths('selected', 'items.' + key); +this.linkPaths('selectedItem', 'items.' + key); +} +} +} +}); +Polymer({ +is: 'dom-if', +extends: 'template', +_template: null, +properties: { +'if': { +type: Boolean, +value: false, +observer: '_queueRender' +}, +restamp: { +type: Boolean, +value: false, +observer: '_queueRender' +} +}, +behaviors: [Polymer.Templatizer], +_queueRender: function () { +this._debounceTemplate(this._render); +}, +detached: function () { +this._teardownInstance(); +}, +attached: function () { +if (this.if && this.ctor) { +this.async(this._ensureInstance); +} +}, +render: function () { +this._flushTemplates(); +}, +_render: function () { +if (this.if) { +if (!this.ctor) { +this.templatize(this); +} +this._ensureInstance(); +this._showHideChildren(); +} else if (this.restamp) { +this._teardownInstance(); +} +if (!this.restamp && this._instance) { +this._showHideChildren(); +} +if (this.if != this._lastIf) { +this.fire('dom-change'); +this._lastIf = this.if; +} +}, +_ensureInstance: function () { +if (!this._instance) { +var parentNode = Polymer.dom(this).parentNode; +if (parentNode) { +var parent = Polymer.dom(parentNode); +this._instance = this.stamp(); +var root = this._instance.root; +parent.insertBefore(root, this); +} +} +}, +_teardownInstance: function () { +if (this._instance) { +var c$ = this._instance._children; +if (c$) { +var parent = Polymer.dom(Polymer.dom(c$[0]).parentNode); +for (var i = 0, n; i < c$.length && (n = c$[i]); i++) { +parent.removeChild(n); +} +} +this._instance = null; +} +}, +_showHideChildren: function () { +var hidden = this.__hideTemplateChildren__ || !this.if; +if (this._instance) { +this._instance._showHideChildren(hidden); +} +}, +_forwardParentProp: function (prop, value) { +if (this._instance) { +this._instance[prop] = value; +} +}, +_forwardParentPath: function (path, value) { +if (this._instance) { +this._instance._notifyPath(path, value, true); +} +} +}); +Polymer({ +is: 'dom-bind', +extends: 'template', +_template: null, +created: function () { +var self = this; +Polymer.RenderStatus.whenReady(function () { +self._markImportsReady(); +}); +}, +_ensureReady: function () { +if (!this._readied) { +this._readySelf(); +} +}, +_markImportsReady: function () { +this._importsReady = true; +this._ensureReady(); +}, +_registerFeatures: function () { +this._prepConstructor(); +}, +_insertChildren: function () { +var parentDom = Polymer.dom(Polymer.dom(this).parentNode); +parentDom.insertBefore(this.root, this); +}, +_removeChildren: function () { +if (this._children) { +for (var i = 0; i < this._children.length; i++) { +this.root.appendChild(this._children[i]); +} +} +}, +_initFeatures: function () { +}, +_scopeElementClass: function (element, selector) { +if (this.dataHost) { +return this.dataHost._scopeElementClass(element, selector); +} else { +return selector; +} +}, +_prepConfigure: function () { +var config = {}; +for (var prop in this._propertyEffects) { +config[prop] = this[prop]; +} +var setupConfigure = this._setupConfigure; +this._setupConfigure = function () { +setupConfigure.call(this, config); +}; +}, +attached: function () { +if (this._importsReady) { +this.render(); +} +}, +detached: function () { +this._removeChildren(); +}, +render: function () { +this._ensureReady(); +if (!this._children) { +this._template = this; +this._prepAnnotations(); +this._prepEffects(); +this._prepBehaviors(); +this._prepConfigure(); +this._prepBindings(); +this._prepPropertyInfo(); +Polymer.Base._initFeatures.call(this); +this._children = Polymer.DomApi.arrayCopyChildNodes(this.root); +} +this._insertChildren(); +this.fire('dom-change'); +} +});</script><script> + /** + * The `<platinum-sw-cache>` element makes it easy to precache specific resources, perform runtime + * caching, and serve your cached resources when a network is unavailable. + * Under the hood, the [sw-toolbox](https://github.com/googlechrome/sw-toolbox) library is used + * for all the caching and request handling logic. + * `<platinum-sw-cache>` needs to be a child element of `<platinum-sw-register>`. + * A simple, yet useful configuration is + * + * <platinum-sw-register auto-register> + * <platinum-sw-cache></platinum-sw-cache> + * </platinum-sw-register> + * + * This is enough to have all of the resources your site uses cached at runtime, both local and + * cross-origin. + * (It uses the default `defaultCacheStrategy` of "networkFirst".) + * When there's a network available, visits to your site will go against the network copy of the + * resources, but if someone visits your site when they're offline, all the cached resources will + * be used. + * + * @demo demo/index.html An offline-capable eReader demo. + */ + Polymer({ + is: 'platinum-sw-cache', + + properties: { + /** + * Used to configure `<platinum-sw-precache>` behavior via a JSON file instead of via + * attributes. This can come in handy when the configuration (e.g. which files to precache) + * depends on the results of a build script. + * + * If configuration for the same properties are provided in both the JSON file and via the + * element's attributes, then in general the JSON file's values take precedence. The one + * exception is the `precache` property. Any values in the element's `precache` attribute will + * be concatenated with the values in the JSON file's `precache` property and the set of files + * that are precached will be the union of the two. + * + * There's one additional option, `precacheFingerprint`, that can be set in the JSON. If using + * a build script that might output a large number of files to precache, its recommended + * that your build script generate a unique "fingerprint" of the files. Any changes to the + * `precacheFingerprint` value will result in the underlying service worker kicking off the + * process of caching the files listed in `precache`. + * While there are a few different strategies for generating an appropriate + * `precacheFingerprint` value, a process that makes sense is to use a stable hash of the + * serialized `precache` array. That way, any changes to the list of files in `precache` + * will result in a new `precacheFingerprint` value. + * If your build script is Node.js based, one way to generate this hash is: + * + * var md5 = require('crypto').createHash('md5'); + * md5.update(JSON.stringify(precache)); + * var precacheFingerprint = md5.digest('hex'); + * + * Alternatively, you could use something like the + * [SHA-1 signature](http://stackoverflow.com/questions/1161869/how-to-get-sha-of-the-latest-commit-from-remote-git-repository) + * of your latest `git` commit for the `precacheFingerprint` value. + * + * An example file may look like: + * + * { + * "cacheId": "my-cache-id", + * "defaultCacheStrategy": "fastest", + * "disabled": false, + * "precache": ["file1.html", "file2.css"], + * "precacheFingerprint": "FINGERPRINT_OF_FILES_IN_PRECACHE" + * } + */ + cacheConfigFile: String, + + /** + * An id used to construct the name for the + * [Cache](https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache) + * in which all the resources will be stored. + * + * If nothing is provided, the default value set in + * [`toolbox.options.cacheName`](https://github.com/GoogleChrome/sw-toolbox/blob/8763dcc9fbc9352d58f184050e2131c42f7b6d68/lib/options.js#L28) + * will be used. + * + * The `cacheId` is combined with the service worker's scope to construct the cache name, so + * two `<platinum-sw-cache>` elements that are associated with different scopes will use + * different caches. + */ + cacheId: String, + + /** + * The caching strategy used for all requests, both for local and cross-origin resources. + * + * For a list of strategies, see the [`sw-toolbox` documentation](https://github.com/GoogleChrome/sw-toolbox#built-in-handlers). + * Specify a strategy as a string, without the "toolbox" prefix. E.g., for + * `toolbox.networkFirst`, set `defaultCacheStrategy` to "networkFirst". + * + * Note that the "cacheFirst" and "cacheOnly" strategies are not recommended, and may be + * explicitly prevented in a future release. More information can be found at + * https://github.com/PolymerElements/platinum-sw#cacheonly--cachefirst-defaultcachestrategy-considered-harmful + * + * @see {@link https://github.com/GoogleChrome/sw-toolbox#built-in-handlers} + */ + defaultCacheStrategy: { + type: String, + value: 'networkFirst' + }, + + /** + * If set to true, this element will not set up service worker caching. This is useful to + * conditionally enable or disable caching depending on the build environment. + */ + disabled: { + type: Boolean, + value: false + }, + + /** + * Used to provide a list of URLs that are always precached as soon as the service worker is + * installed. Corresponds to [`sw-toolbox`'s `precache()` method](https://github.com/GoogleChrome/sw-toolbox#toolboxprecachearrayofurls). + * + * This is useful for URLs that that wouldn't necessarily be picked up by runtime caching, + * i.e. a list of resources that are needed by one of the subpages of your site, or a list of + * resources that are only loaded via user interaction. + * + * `precache` can be used in conjunction with `cacheConfigFile`, and the two arrays will be + * concatenated. + * + * @see {@link https://github.com/GoogleChrome/sw-toolbox#toolboxprecachearrayofurls} + */ + precache: { + type: Array, + value: function() { return []; } + } + }, + + _getParameters: function(baseURI) { + return new Promise(function(resolve) { + var params = { + importscriptLate: new URL('bootstrap/sw-toolbox-setup.js', baseURI).href, + defaultCacheStrategy: this.defaultCacheStrategy, + precache: this.precache + }; + + if (this.cacheConfigFile) { + params.cacheConfigFile = this.cacheConfigFile; + window.fetch(this.cacheConfigFile).then(function(response) { + if (!response.ok) { + throw Error('unable to load ' + this.cacheConfigFile); + } + return response.json(); + }.bind(this)).then(function(config) { + this.disabled = config.disabled; + if (this.disabled) { + // Use an empty set of parameters to effectively disable caching. + params = {}; + } else { + // If there's a hash of the list of files to precache provided in the config file, + // then copy that over to the params that will be used to construct the service worker + // URL. This works around the issue where a potentially large number of precache + // files could result in a longer URL than a browser will allow. + // The actual list of files to precache (in config.precache) will be dealt by the + // service worker during the install phase, so we can ignore it here. + // See https://github.com/PolymerElements/platinum-sw/issues/53 + if (config.precacheFingerprint) { + params.precacheFingerprint = config.precacheFingerprint; + } else { + params.precache = params.precache.concat(config.precache); + } + params.cacheId = config.cacheId || params.cacheId; + params.defaultCacheStrategy = config.defaultCacheStrategy || + params.defaultCacheStrategy; + } + }.bind(this)).catch(function(error) { + console.info('Skipping precaching: ' + error.message); + }).then(function() { + resolve(params); + }); + } else { + resolve(params); + } + }.bind(this)); + } + }); +</script><script> + /** + * The `<platinum-sw-register>` element handles + * [service worker](http://www.html5rocks.com/en/tutorials/service-worker/introduction/) + * registration, reflects the overall service worker state, and coordinates the configuration + * provided by other Service Worker Elements. + * `<platinum-sw-register>` is used as a parent element for child elements in the + * `<platinum-sw-*>` group. + * + * <platinum-sw-register skip-waiting + * clients-claim + * auto-register + * state="{{state}}" + * on-service-worker-error="handleSWError" + * on-service-worker-updated="handleSWUpdated" + * on-service-worker-installed="handleSWInstalled"> + * ...one or more <platinum-sw-*> children which share the service worker registration... + * </platinum-sw-register> + * + * Please see https://github.com/PolymerElements/platinum-sw#top-level-sw-importjs for a + * *crucial* prerequisite file you must create before `<platinum-sw-register>` can be used! + * + * @demo demo/index.html An offline-capable eReader demo. + */ + Polymer({ + is: 'platinum-sw-register', + + // Used as an "emergency" switch if we make breaking changes in the way <platinum-sw-register> + // talks to service-worker.js. Otherwise, it shouldn't need to change, and isn't meant to be + // kept in sync with the element's release number. + _version: '1.0', + + /** + * Fired when the initial service worker installation completes successfully. + * The service worker will normally only be installed once, the first time a page with a + * `<platinum-sw-register>` element is visited in a given browser. If the same page is visited + * again, the existing service worker will be reused, and there won't be another + * `service-worker-installed` fired. + * + * @event service-worker-installed + * @param {String} A message indicating that the installation succeeded. + */ + + /** + * Fired when the service worker update flow completes successfully. + * If you make changes to your `<platinum-sw-register>` configuration (i.e. by adding in new + * `<platinum-sw-*>` child elements, or changing their attributes), users who had the old + * service worker installed will get the update installed when they see the modified elements. + * + * @event service-worker-updated + * @param {String} A message indicating that the update succeeded. + */ + + /** + * Fired when an error prevents the service worker installation from completing. + * + * @event service-worker-error + * @param {String} A message indicating what went wrong. + */ + + properties: { + /** + * Whether this element should automatically register the corresponding service worker as + * soon as its added to a page. + * + * If set to `false`, then the service worker won't be automatically registered, and you + * must call this element's `register()` method if you want service worker functionality. + * This is useful if, for example, the service worker needs to be configured using + * information that isn't immediately available at the time the page loads. + * + * If set to `true`, the service worker will be automatically registered without having to + * call any methods. + */ + autoRegister: { + type: Boolean, + value: false + }, + + /** + * The URI used as a base when constructing relative paths to service worker helper libraries + * that need to be loaded. + * + * This can normally be kept set to the default, which will use the directory containing this + * element as the base. However, if you [Vulcanize](https://github.com/polymer/vulcanize) your + * elements, then the default base might not be appropriate anymore. This will allow you to + * override it. + * + * See https://github.com/PolymerElements/platinum-sw#relative-paths--vulcanization for more + * information. + */ + baseUri: { + type: String, + // Grab the URI of this file to use as a base when resolving relative paths. + // Fallback to './' as a default, though current browsers that don't support + // document.currentScript also don't support service workers. + value: document.currentScript ? document.currentScript.baseURI : './' + }, + + /** + * Whether the activated service worker should [take immediate control](https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#clients-claim-method) + * of any pages under its scope. + * + * If this is `false`, the service worker won't have any effect until the next time the page + * is visited/reloaded. + * If this is `true`, it will take control and start handling events for the current page + * (and any pages under the same scope open in other tabs/windows) as soon it's active. + * @see {@link https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#clients-claim-method} + */ + clientsClaim: { + type: Boolean, + value: false + }, + + /** + * The service worker script that is [registered](https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#navigator-service-worker-register). + * The script *should* be located at the top level of your site, to ensure that it is able + * to control all the pages on your site. + * + * It's *strongly* recommended that you create a top-level file named `sw-import.js` + * containing only: + * + * `importScripts('bower_components/platinum-sw/service-worker.js');` + * + * (adjust to match the path where your `platinum-sw` element directory can be found). + * + * This will ensure that your service worker script contains everything needed to play + * nicely with the Service Worker Elements group. + * + * @see {@link https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#navigator-service-worker-register} + */ + href: { + type: String, + value: 'sw-import.js' + }, + + /** + * Whether the page should be automatically reloaded (via `window.location.reload()`) when + * the service worker is successfully installed. + * + * While it's perfectly valid to continue using a page with a freshly installed service + * worker, it's a common pattern to want to reload it immediately following the install. + * This ensures that, for example, if you're using a `<platinum-sw-cache>` with an on the + * fly caching strategy, it will get a chance to intercept all the requests needed to render + * your page and store them in the cache. + * + * If you don't immediately reload your page, then any resources that were loaded before the + * service worker was installed (e.g. this `platinum-sw-register.html` file) won't be present + * in the cache until the next time the page is loaded. + * + * Note that this reload will only happen when a service worker is installed for the first + * time. If the service worker is subsequently updated, it won't trigger another reload. + */ + reloadOnInstall: { + type: Boolean, + value: false + }, + + /** + * The scope of the service worker, relative to the registered service worker script. + * All pages that fall under this scope will be controlled by the registered service worker. + * + * Normally, this would not need to be changed, unless you want the service worker to only + * apply to a subset of your site. + * + * @see {@link https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#navigator-service-worker-register} + */ + scope: { + type: String, + value: './' + }, + + /** + * Whether an updated service worker should [bypass the `waiting` state](https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#service-worker-global-scope-skipwaiting) + * and immediately become `active`. + * + * Normally, during an update, the new service worker stays in the + * `waiting` state until the current page and any other tabs/windows that are using the old + * service worker are unloaded. + * + * If this is `false`, an updated service worker won't be activated until all instances of + * the old server worker have been unloaded. + * + * If this is `true`, an updated service worker will become `active` immediately. + * @see {@link https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#service-worker-global-scope-skipwaiting} + */ + skipWaiting: { + type: Boolean, + value: false + }, + + /** + * The current state of the service worker registered by this element. + * + * One of: + * - 'installed' + * - 'updated' + * - 'error' + * - 'unsupported' + */ + state: { + notify: true, + readOnly: true, + type: String + } + }, + + /** + * Registers the service worker based on the configuration options in this element and any + * child elements. + * + * If you set the `autoRegister` property to `true`, then this method is called automatically + * at page load. + * It can be useful to set `autoRegister` to `false` and then explicitly call this method if + * there are options that are only configured after the page is loaded. + */ + register: function() { + if ('serviceWorker' in navigator) { + this._constructServiceWorkerUrl().then(function(serviceWorkerUrl) { + this._registerServiceWorker(serviceWorkerUrl); + }.bind(this)); + } else { + this._setState('unsupported'); + this.fire('service-worker-error', 'Service workers are not available in the current browser.'); + } + }, + + _constructServiceWorkerUrl: function() { + var paramsPromises = []; + var children = Polymer.dom(this).children; + var baseUri = new URL(this.baseUri, window.location.href); + + for (var i = 0; i < children.length; i++) { + if (typeof children[i]._getParameters === 'function') { + paramsPromises.push(children[i]._getParameters(baseUri)); + } + } + + return Promise.all(paramsPromises).then(function(paramsResolutions) { + var params = { + baseURI: baseUri, + version: this._version + }; + + paramsResolutions.forEach(function(childParams) { + Object.keys(childParams).forEach(function(key) { + if (Array.isArray(params[key])) { + params[key] = params[key].concat(childParams[key]); + } else { + params[key] = [].concat(childParams[key]); + } + }); + }); + + return params; + }.bind(this)).then(function(params) { + if (params.importscriptLate) { + if (params.importscript) { + params.importscript = params.importscript.concat(params.importscriptLate); + } else { + params.importscript = params.importscriptLate; + } + } + + if (params.importscript) { + params.importscript = this._unique(params.importscript); + } + + // We've already concatenated importscriptLate, so don't include it in the serialized URL. + delete params.importscriptLate; + + params.clientsClaim = this.clientsClaim; + params.skipWaiting = this.skipWaiting; + + var serviceWorkerUrl = new URL(this.href, window.location); + // It's very important to ensure that the serialization is stable. + // Serializing the same settings should always produce the same URL. + // Serializing different settings should always produce a different URL. + // This ensures that the service worker upgrade flow is triggered when settings change. + serviceWorkerUrl.search = this._serializeUrlParams(params); + + return serviceWorkerUrl; + }.bind(this)); + }, + + _unique: function(arr) { + return arr.filter(function(item, index) { + return arr.indexOf(item) === index; + }); + }, + + _serializeUrlParams: function(params) { + return Object.keys(params).sort().map(function(key) { + // encodeURIComponent(['a', 'b']) => 'a%2Cb', + // so this will still work when the values are Arrays. + // TODO: It won't work if the values in the Arrays have ',' characters in them. + return encodeURIComponent(key) + "=" + encodeURIComponent(params[key]); + }).join('&'); + }, + + _registerServiceWorker: function(serviceWorkerUrl) { + navigator.serviceWorker.register(serviceWorkerUrl, {scope: this.scope}).then(function(registration) { + if (registration.active) { + this._setState('installed'); + } + + registration.onupdatefound = function() { + var installingWorker = registration.installing; + installingWorker.onstatechange = function() { + switch (installingWorker.state) { + case 'installed': + if (navigator.serviceWorker.controller) { + this._setState('updated'); + this.fire('service-worker-updated', + 'A new service worker was installed, replacing the old service worker.'); + } else { + if (this.reloadOnInstall) { + window.location.reload(); + } else { + this._setState('installed'); + this.fire('service-worker-installed', 'A new service worker was installed.'); + } + } + break; + + case 'redundant': + this._setState('error'); + this.fire('service-worker-error', 'The installing service worker became redundant.'); + break; + } + }.bind(this); + }.bind(this); + }.bind(this)).catch(function(error) { + this._setState('error'); + this.fire('service-worker-error', error.toString()); + if (error.name === 'NetworkError') { + var location = serviceWorkerUrl.origin + serviceWorkerUrl.pathname; + console.error('A valid service worker script was not found at ' + location + '\n' + + 'To learn how to fix this, please see\n' + + 'https://github.com/PolymerElements/platinum-sw#top-level-sw-importjs'); + } + }.bind(this)); + }, + + attached: function() { + if (this.autoRegister) { + this.async(this.register); + } + } + }); +</script><script> + +/** +Polymer.IronFitBehavior fits an element in another element using `max-height` and `max-width`, and +optionally centers it in the window or another element. + +The element will only be sized and/or positioned if it has not already been sized and/or positioned +by CSS. + +CSS properties | Action +-----------------------------|------------------------------------------- +`position` set | Element is not centered horizontally or vertically +`top` or `bottom` set | Element is not vertically centered +`left` or `right` set | Element is not horizontally centered +`max-height` or `height` set | Element respects `max-height` or `height` +`max-width` or `width` set | Element respects `max-width` or `width` + +@demo demo/index.html +@polymerBehavior +*/ + + Polymer.IronFitBehavior = { + + properties: { + + /** + * The element that will receive a `max-height`/`width`. By default it is the same as `this`, + * but it can be set to a child element. This is useful, for example, for implementing a + * scrolling region inside the element. + * @type {!Element} + */ + sizingTarget: { + type: Object, + value: function() { + return this; + } + }, + + /** + * The element to fit `this` into. + */ + fitInto: { + type: Object, + value: window + }, + + /** + * Set to true to auto-fit on attach. + */ + autoFitOnAttach: { + type: Boolean, + value: false + }, + + /** @type {?Object} */ + _fitInfo: { + type: Object + } + + }, + + get _fitWidth() { + var fitWidth; + if (this.fitInto === window) { + fitWidth = this.fitInto.innerWidth; + } else { + fitWidth = this.fitInto.getBoundingClientRect().width; + } + return fitWidth; + }, + + get _fitHeight() { + var fitHeight; + if (this.fitInto === window) { + fitHeight = this.fitInto.innerHeight; + } else { + fitHeight = this.fitInto.getBoundingClientRect().height; + } + return fitHeight; + }, + + get _fitLeft() { + var fitLeft; + if (this.fitInto === window) { + fitLeft = 0; + } else { + fitLeft = this.fitInto.getBoundingClientRect().left; + } + return fitLeft; + }, + + get _fitTop() { + var fitTop; + if (this.fitInto === window) { + fitTop = 0; + } else { + fitTop = this.fitInto.getBoundingClientRect().top; + } + return fitTop; + }, + + attached: function() { + if (this.autoFitOnAttach) { + if (window.getComputedStyle(this).display === 'none') { + setTimeout(function() { + this.fit(); + }.bind(this)); + } else { + this.fit(); + } + } + }, + + /** + * Fits and optionally centers the element into the window, or `fitInfo` if specified. + */ + fit: function() { + this._discoverInfo(); + this.constrain(); + this.center(); + }, + + /** + * Memoize information needed to position and size the target element. + */ + _discoverInfo: function() { + if (this._fitInfo) { + return; + } + var target = window.getComputedStyle(this); + var sizer = window.getComputedStyle(this.sizingTarget); + this._fitInfo = { + inlineStyle: { + top: this.style.top || '', + left: this.style.left || '' + }, + positionedBy: { + vertically: target.top !== 'auto' ? 'top' : (target.bottom !== 'auto' ? + 'bottom' : null), + horizontally: target.left !== 'auto' ? 'left' : (target.right !== 'auto' ? + 'right' : null), + css: target.position + }, + sizedBy: { + height: sizer.maxHeight !== 'none', + width: sizer.maxWidth !== 'none' + }, + margin: { + top: parseInt(target.marginTop, 10) || 0, + right: parseInt(target.marginRight, 10) || 0, + bottom: parseInt(target.marginBottom, 10) || 0, + left: parseInt(target.marginLeft, 10) || 0 + } + }; + }, + + /** + * Resets the target element's position and size constraints, and clear + * the memoized data. + */ + resetFit: function() { + if (!this._fitInfo || !this._fitInfo.sizedBy.height) { + this.sizingTarget.style.maxHeight = ''; + this.style.top = this._fitInfo ? this._fitInfo.inlineStyle.top : ''; + } + if (!this._fitInfo || !this._fitInfo.sizedBy.width) { + this.sizingTarget.style.maxWidth = ''; + this.style.left = this._fitInfo ? this._fitInfo.inlineStyle.left : ''; + } + if (this._fitInfo) { + this.style.position = this._fitInfo.positionedBy.css; + } + this._fitInfo = null; + }, + + /** + * Equivalent to calling `resetFit()` and `fit()`. Useful to call this after the element, + * the window, or the `fitInfo` element has been resized. + */ + refit: function() { + this.resetFit(); + this.fit(); + }, + + /** + * Constrains the size of the element to the window or `fitInfo` by setting `max-height` + * and/or `max-width`. + */ + constrain: function() { + var info = this._fitInfo; + // position at (0px, 0px) if not already positioned, so we can measure the natural size. + if (!this._fitInfo.positionedBy.vertically) { + this.style.top = '0px'; + } + if (!this._fitInfo.positionedBy.horizontally) { + this.style.left = '0px'; + } + if (!this._fitInfo.positionedBy.vertically || !this._fitInfo.positionedBy.horizontally) { + // need position:fixed to properly size the element + this.style.position = 'fixed'; + } + // need border-box for margin/padding + this.sizingTarget.style.boxSizing = 'border-box'; + // constrain the width and height if not already set + var rect = this.getBoundingClientRect(); + if (!info.sizedBy.height) { + this._sizeDimension(rect, info.positionedBy.vertically, 'top', 'bottom', 'Height'); + } + if (!info.sizedBy.width) { + this._sizeDimension(rect, info.positionedBy.horizontally, 'left', 'right', 'Width'); + } + }, + + _sizeDimension: function(rect, positionedBy, start, end, extent) { + var info = this._fitInfo; + var max = extent === 'Width' ? this._fitWidth : this._fitHeight; + var flip = (positionedBy === end); + var offset = flip ? max - rect[end] : rect[start]; + var margin = info.margin[flip ? start : end]; + var offsetExtent = 'offset' + extent; + var sizingOffset = this[offsetExtent] - this.sizingTarget[offsetExtent]; + this.sizingTarget.style['max' + extent] = (max - margin - offset - sizingOffset) + 'px'; + }, + + /** + * Centers horizontally and vertically if not already positioned. This also sets + * `position:fixed`. + */ + center: function() { + if (!this._fitInfo.positionedBy.vertically || !this._fitInfo.positionedBy.horizontally) { + // need position:fixed to center + this.style.position = 'fixed'; + } + if (!this._fitInfo.positionedBy.vertically) { + var top = (this._fitHeight - this.offsetHeight) / 2 + this._fitTop; + top -= this._fitInfo.margin.top; + this.style.top = top + 'px'; + } + if (!this._fitInfo.positionedBy.horizontally) { + var left = (this._fitWidth - this.offsetWidth) / 2 + this._fitLeft; + left -= this._fitInfo.margin.left; + this.style.left = left + 'px'; + } + } + + }; + +</script><script> + /** + * `IronResizableBehavior` is a behavior that can be used in Polymer elements to + * coordinate the flow of resize events between "resizers" (elements that control the + * size or hidden state of their children) and "resizables" (elements that need to be + * notified when they are resized or un-hidden by their parents in order to take + * action on their new measurements). + * Elements that perform measurement should add the `IronResizableBehavior` behavior to + * their element definition and listen for the `iron-resize` event on themselves. + * This event will be fired when they become showing after having been hidden, + * when they are resized explicitly by another resizable, or when the window has been + * resized. + * Note, the `iron-resize` event is non-bubbling. + * + * @polymerBehavior Polymer.IronResizableBehavior + * @demo demo/index.html + **/ + Polymer.IronResizableBehavior = { + properties: { + /** + * The closest ancestor element that implements `IronResizableBehavior`. + */ + _parentResizable: { + type: Object, + observer: '_parentResizableChanged' + }, + + /** + * True if this element is currently notifying its descedant elements of + * resize. + */ + _notifyingDescendant: { + type: Boolean, + value: false + } + }, + + listeners: { + 'iron-request-resize-notifications': '_onIronRequestResizeNotifications' + }, + + created: function() { + // We don't really need property effects on these, and also we want them + // to be created before the `_parentResizable` observer fires: + this._interestedResizables = []; + this._boundNotifyResize = this.notifyResize.bind(this); + }, + + attached: function() { + this.fire('iron-request-resize-notifications', null, { + node: this, + bubbles: true, + cancelable: true + }); + + if (!this._parentResizable) { + window.addEventListener('resize', this._boundNotifyResize); + this.notifyResize(); + } + }, + + detached: function() { + if (this._parentResizable) { + this._parentResizable.stopResizeNotificationsFor(this); + } else { + window.removeEventListener('resize', this._boundNotifyResize); + } + + this._parentResizable = null; + }, + + /** + * Can be called to manually notify a resizable and its descendant + * resizables of a resize change. + */ + notifyResize: function() { + if (!this.isAttached) { + return; + } + + this._interestedResizables.forEach(function(resizable) { + if (this.resizerShouldNotify(resizable)) { + this._notifyDescendant(resizable); + } + }, this); + + this._fireResize(); + }, + + /** + * Used to assign the closest resizable ancestor to this resizable + * if the ancestor detects a request for notifications. + */ + assignParentResizable: function(parentResizable) { + this._parentResizable = parentResizable; + }, + + /** + * Used to remove a resizable descendant from the list of descendants + * that should be notified of a resize change. + */ + stopResizeNotificationsFor: function(target) { + var index = this._interestedResizables.indexOf(target); + + if (index > -1) { + this._interestedResizables.splice(index, 1); + this.unlisten(target, 'iron-resize', '_onDescendantIronResize'); + } + }, + + /** + * This method can be overridden to filter nested elements that should or + * should not be notified by the current element. Return true if an element + * should be notified, or false if it should not be notified. + * + * @param {HTMLElement} element A candidate descendant element that + * implements `IronResizableBehavior`. + * @return {boolean} True if the `element` should be notified of resize. + */ + resizerShouldNotify: function(element) { return true; }, + + _onDescendantIronResize: function(event) { + if (this._notifyingDescendant) { + event.stopPropagation(); + return; + } + + // NOTE(cdata): In ShadowDOM, event retargetting makes echoing of the + // otherwise non-bubbling event "just work." We do it manually here for + // the case where Polymer is not using shadow roots for whatever reason: + if (!Polymer.Settings.useShadow) { + this._fireResize(); + } + }, + + _fireResize: function() { + this.fire('iron-resize', null, { + node: this, + bubbles: false + }); + }, + + _onIronRequestResizeNotifications: function(event) { + var target = event.path ? event.path[0] : event.target; + + if (target === this) { + return; + } + + if (this._interestedResizables.indexOf(target) === -1) { + this._interestedResizables.push(target); + this.listen(target, 'iron-resize', '_onDescendantIronResize'); + } + + target.assignParentResizable(this); + this._notifyDescendant(target); + + event.stopPropagation(); + }, + + _parentResizableChanged: function(parentResizable) { + if (parentResizable) { + window.removeEventListener('resize', this._boundNotifyResize); + } + }, + + _notifyDescendant: function(descendant) { + // NOTE(cdata): In IE10, attached is fired on children first, so it's + // important not to notify them if the parent is not attached yet (or + // else they will get redundantly notified when the parent attaches). + if (!this.isAttached) { + return; + } + + this._notifyingDescendant = true; + descendant.notifyResize(); + this._notifyingDescendant = false; + } + }; +</script><script> + + Polymer.IronOverlayManager = { + + _overlays: [], + + // iframes have a default z-index of 100, so this default should be at least + // that. + _minimumZ: 101, + + _backdrops: [], + + _applyOverlayZ: function(overlay, aboveZ) { + this._setZ(overlay, aboveZ + 2); + }, + + _setZ: function(element, z) { + element.style.zIndex = z; + }, + + // track overlays for z-index and focus managemant + addOverlay: function(overlay) { + var minimumZ = Math.max(this.currentOverlayZ(), this._minimumZ); + this._overlays.push(overlay); + var newZ = this.currentOverlayZ(); + if (newZ <= minimumZ) { + this._applyOverlayZ(overlay, minimumZ); + } + }, + + removeOverlay: function(overlay) { + var i = this._overlays.indexOf(overlay); + if (i >= 0) { + this._overlays.splice(i, 1); + this._setZ(overlay, ''); + } + }, + + currentOverlay: function() { + var i = this._overlays.length - 1; + while (this._overlays[i] && !this._overlays[i].opened) { + --i; + } + return this._overlays[i]; + }, + + currentOverlayZ: function() { + var z = this._minimumZ; + var current = this.currentOverlay(); + if (current) { + var z1 = window.getComputedStyle(current).zIndex; + if (!isNaN(z1)) { + z = Number(z1); + } + } + return z; + }, + + /** + * Ensures that the minimum z-index of new overlays is at least `minimumZ`. + * This does not effect the z-index of any existing overlays. + * + * @param {number} minimumZ + */ + ensureMinimumZ: function(minimumZ) { + this._minimumZ = Math.max(this._minimumZ, minimumZ); + }, + + focusOverlay: function() { + var current = this.currentOverlay(); + // We have to be careful to focus the next overlay _after_ any current + // transitions are complete (due to the state being toggled prior to the + // transition). Otherwise, we risk infinite recursion when a transitioning + // (closed) overlay becomes the current overlay. + // + // NOTE: We make the assumption that any overlay that completes a transition + // will call into focusOverlay to kick the process back off. Currently: + // transitionend -> _applyFocus -> focusOverlay. + if (current && !current.transitioning) { + current._applyFocus(); + } + }, + + trackBackdrop: function(element) { + // backdrops contains the overlays with a backdrop that are currently + // visible + if (element.opened) { + this._backdrops.push(element); + } else { + var index = this._backdrops.indexOf(element); + if (index >= 0) { + this._backdrops.splice(index, 1); + } + } + }, + + getBackdrops: function() { + return this._backdrops; + } + + }; + +</script><script> + +/** +Use `Polymer.IronOverlayBehavior` to implement an element that can be hidden or shown, and displays +on top of other content. It includes an optional backdrop, and can be used to implement a variety +of UI controls including dialogs and drop downs. Multiple overlays may be displayed at once. + +### Closing and canceling + +A dialog may be hidden by closing or canceling. The difference between close and cancel is user +intent. Closing generally implies that the user acknowledged the content on the overlay. By default, +it will cancel whenever the user taps outside it or presses the escape key. This behavior is +configurable with the `no-cancel-on-esc-key` and the `no-cancel-on-outside-click` properties. +`close()` should be called explicitly by the implementer when the user interacts with a control +in the overlay element. When the dialog is canceled, the overlay fires an 'iron-overlay-canceled' +event. Call `preventDefault` on this event to prevent the overlay from closing. + +### Positioning + +By default the element is sized and positioned to fit and centered inside the window. You can +position and size it manually using CSS. See `Polymer.IronFitBehavior`. + +### Backdrop + +Set the `with-backdrop` attribute to display a backdrop behind the overlay. The backdrop is +appended to `<body>` and is of type `<iron-overlay-backdrop>`. See its doc page for styling +options. + +### Limitations + +The element is styled to appear on top of other content by setting its `z-index` property. You +must ensure no element has a stacking context with a higher `z-index` than its parent stacking +context. You should place this element as a child of `<body>` whenever possible. + +@demo demo/index.html +@polymerBehavior Polymer.IronOverlayBehavior +*/ + + Polymer.IronOverlayBehaviorImpl = { + + properties: { + + /** + * True if the overlay is currently displayed. + */ + opened: { + observer: '_openedChanged', + type: Boolean, + value: false, + notify: true + }, + + /** + * True if the overlay was canceled when it was last closed. + */ + canceled: { + observer: '_canceledChanged', + readOnly: true, + type: Boolean, + value: false + }, + + /** + * Set to true to display a backdrop behind the overlay. + */ + withBackdrop: { + type: Boolean, + value: false + }, + + /** + * Set to true to disable auto-focusing the overlay or child nodes with + * the `autofocus` attribute` when the overlay is opened. + */ + noAutoFocus: { + type: Boolean, + value: false + }, + + /** + * Set to true to disable canceling the overlay with the ESC key. + */ + noCancelOnEscKey: { + type: Boolean, + value: false + }, + + /** + * Set to true to disable canceling the overlay by clicking outside it. + */ + noCancelOnOutsideClick: { + type: Boolean, + value: false + }, + + /** + * Returns the reason this dialog was last closed. + */ + closingReason: { + // was a getter before, but needs to be a property so other + // behaviors can override this. + type: Object + }, + + _manager: { + type: Object, + value: Polymer.IronOverlayManager + }, + + _boundOnCaptureClick: { + type: Function, + value: function() { + return this._onCaptureClick.bind(this); + } + }, + + _boundOnCaptureKeydown: { + type: Function, + value: function() { + return this._onCaptureKeydown.bind(this); + } + } + + }, + + listeners: { + 'iron-resize': '_onIronResize' + }, + + /** + * The backdrop element. + * @type Node + */ + get backdropElement() { + return this._backdrop; + }, + + get _focusNode() { + return Polymer.dom(this).querySelector('[autofocus]') || this; + }, + + registered: function() { + this._backdrop = document.createElement('iron-overlay-backdrop'); + }, + + ready: function() { + this._ensureSetup(); + }, + + attached: function() { + // Call _openedChanged here so that position can be computed correctly. + if (this._callOpenedWhenReady) { + this._openedChanged(); + } + }, + + detached: function() { + this.opened = false; + this._completeBackdrop(); + this._manager.removeOverlay(this); + }, + + /** + * Toggle the opened state of the overlay. + */ + toggle: function() { + this.opened = !this.opened; + }, + + /** + * Open the overlay. + */ + open: function() { + this.opened = true; + this.closingReason = {canceled: false}; + }, + + /** + * Close the overlay. + */ + close: function() { + this.opened = false; + this._setCanceled(false); + }, + + /** + * Cancels the overlay. + */ + cancel: function() { + var cancelEvent = this.fire('iron-overlay-canceled', undefined, {cancelable: true}); + if (cancelEvent.defaultPrevented) { + return; + } + + this.opened = false; + this._setCanceled(true); + }, + + _ensureSetup: function() { + if (this._overlaySetup) { + return; + } + this._overlaySetup = true; + this.style.outline = 'none'; + this.style.display = 'none'; + }, + + _openedChanged: function() { + if (this.opened) { + this.removeAttribute('aria-hidden'); + } else { + this.setAttribute('aria-hidden', 'true'); + } + + // wait to call after ready only if we're initially open + if (!this._overlaySetup) { + this._callOpenedWhenReady = this.opened; + return; + } + if (this._openChangedAsync) { + this.cancelAsync(this._openChangedAsync); + } + + this._toggleListeners(); + + if (this.opened) { + this._prepareRenderOpened(); + } + + // async here to allow overlay layer to become visible. + this._openChangedAsync = this.async(function() { + // overlay becomes visible here + this.style.display = ''; + // force layout to ensure transitions will go + /** @suppress {suspiciousCode} */ this.offsetWidth; + if (this.opened) { + this._renderOpened(); + } else { + this._renderClosed(); + } + this._openChangedAsync = null; + }); + + }, + + _canceledChanged: function() { + this.closingReason = this.closingReason || {}; + this.closingReason.canceled = this.canceled; + }, + + _toggleListener: function(enable, node, event, boundListener, capture) { + if (enable) { + // enable document-wide tap recognizer + if (event === 'tap') { + Polymer.Gestures.add(document, 'tap', null); + } + node.addEventListener(event, boundListener, capture); + } else { + // disable document-wide tap recognizer + if (event === 'tap') { + Polymer.Gestures.remove(document, 'tap', null); + } + node.removeEventListener(event, boundListener, capture); + } + }, + + _toggleListeners: function() { + if (this._toggleListenersAsync) { + this.cancelAsync(this._toggleListenersAsync); + } + // async so we don't auto-close immediately via a click. + this._toggleListenersAsync = this.async(function() { + this._toggleListener(this.opened, document, 'tap', this._boundOnCaptureClick, true); + this._toggleListener(this.opened, document, 'keydown', this._boundOnCaptureKeydown, true); + this._toggleListenersAsync = null; + }, 1); + }, + + // tasks which must occur before opening; e.g. making the element visible + _prepareRenderOpened: function() { + this._manager.addOverlay(this); + + if (this.withBackdrop) { + this.backdropElement.prepare(); + this._manager.trackBackdrop(this); + } + + this._preparePositioning(); + this.fit(); + this._finishPositioning(); + }, + + // tasks which cause the overlay to actually open; typically play an + // animation + _renderOpened: function() { + if (this.withBackdrop) { + this.backdropElement.open(); + } + this._finishRenderOpened(); + }, + + _renderClosed: function() { + if (this.withBackdrop) { + this.backdropElement.close(); + } + this._finishRenderClosed(); + }, + + _onTransitionend: function(event) { + // make sure this is our transition event. + if (event && event.target !== this) { + return; + } + if (this.opened) { + this._finishRenderOpened(); + } else { + this._finishRenderClosed(); + } + }, + + _finishRenderOpened: function() { + // focus the child node with [autofocus] + if (!this.noAutoFocus) { + this._focusNode.focus(); + } + + this.fire('iron-overlay-opened'); + + this._squelchNextResize = true; + this.async(this.notifyResize); + }, + + _finishRenderClosed: function() { + // hide the overlay and remove the backdrop + this.resetFit(); + this.style.display = 'none'; + this._completeBackdrop(); + this._manager.removeOverlay(this); + + this._focusNode.blur(); + // focus the next overlay, if there is one + this._manager.focusOverlay(); + + this.fire('iron-overlay-closed', this.closingReason); + + this._squelchNextResize = true; + this.async(this.notifyResize); + }, + + _completeBackdrop: function() { + if (this.withBackdrop) { + this._manager.trackBackdrop(this); + this.backdropElement.complete(); + } + }, + + _preparePositioning: function() { + this.style.transition = this.style.webkitTransition = 'none'; + this.style.transform = this.style.webkitTransform = 'none'; + this.style.display = ''; + }, + + _finishPositioning: function() { + this.style.display = 'none'; + this.style.transform = this.style.webkitTransform = ''; + // force layout to avoid application of transform + /** @suppress {suspiciousCode} */ this.offsetWidth; + this.style.transition = this.style.webkitTransition = ''; + }, + + _applyFocus: function() { + if (this.opened) { + if (!this.noAutoFocus) { + this._focusNode.focus(); + } + } else { + this._focusNode.blur(); + this._manager.focusOverlay(); + } + }, + + _onCaptureClick: function(event) { + if (!this.noCancelOnOutsideClick && + this._manager.currentOverlay() === this && + Polymer.dom(event).path.indexOf(this) === -1) { + this.cancel(); + } + }, + + _onCaptureKeydown: function(event) { + var ESC = 27; + if (!this.noCancelOnEscKey && (event.keyCode === ESC)) { + this.cancel(); + event.stopPropagation(); + event.stopImmediatePropagation(); + } + }, + + _onIronResize: function() { + if (this._squelchNextResize) { + this._squelchNextResize = false; + return; + } + if (this.opened) { + this.refit(); + } + } + +/** + * Fired after the `iron-overlay` opens. + * @event iron-overlay-opened + */ + +/** + * Fired when the `iron-overlay` is canceled, but before it is closed. + * Cancel the event to prevent the `iron-overlay` from closing. + * @event iron-overlay-canceled + */ + +/** + * Fired after the `iron-overlay` closes. + * @event iron-overlay-closed + * @param {{canceled: (boolean|undefined)}} set to the `closingReason` attribute + */ + }; + + /** @polymerBehavior */ + Polymer.IronOverlayBehavior = [Polymer.IronFitBehavior, Polymer.IronResizableBehavior, Polymer.IronOverlayBehaviorImpl]; + + +</script><style is=custom-style> + + :root { + + /* Shared Styles */ + --paper-font-common-base: { + font-family: 'Roboto', 'Noto', sans-serif; + -webkit-font-smoothing: antialiased; + }; + + --paper-font-common-code: { + font-family: 'Roboto Mono', 'Consolas', 'Menlo', monospace; + -webkit-font-smoothing: antialiased; + }; + + --paper-font-common-expensive-kerning: { + text-rendering: optimizeLegibility; + }; + + --paper-font-common-nowrap: { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + }; + + /* Material Font Styles */ + + --paper-font-display4: { + @apply(--paper-font-common-base); + @apply(--paper-font-common-nowrap); + + font-size: 112px; + font-weight: 300; + letter-spacing: -.044em; + line-height: 120px; + }; + + --paper-font-display3: { + @apply(--paper-font-common-base); + @apply(--paper-font-common-nowrap); + + font-size: 56px; + font-weight: 400; + letter-spacing: -.026em; + line-height: 60px; + }; + + --paper-font-display2: { + @apply(--paper-font-common-base); + + font-size: 45px; + font-weight: 400; + letter-spacing: -.018em; + line-height: 48px; + }; + + --paper-font-display1: { + @apply(--paper-font-common-base); + + font-size: 34px; + font-weight: 400; + letter-spacing: -.01em; + line-height: 40px; + }; + + --paper-font-headline: { + @apply(--paper-font-common-base); + + font-size: 24px; + font-weight: 400; + letter-spacing: -.012em; + line-height: 32px; + }; + + --paper-font-title: { + @apply(--paper-font-common-base); + @apply(--paper-font-common-nowrap); + + font-size: 20px; + font-weight: 500; + line-height: 28px; + }; + + --paper-font-subhead: { + @apply(--paper-font-common-base); + + font-size: 16px; + font-weight: 400; + line-height: 24px; + }; + + --paper-font-body2: { + @apply(--paper-font-common-base); + + font-size: 14px; + font-weight: 500; + line-height: 24px; + }; + + --paper-font-body1: { + @apply(--paper-font-common-base); + + font-size: 14px; + font-weight: 400; + line-height: 20px; + }; + + --paper-font-caption: { + @apply(--paper-font-common-base); + @apply(--paper-font-common-nowrap); + + font-size: 12px; + font-weight: 400; + letter-spacing: 0.011em; + line-height: 20px; + }; + + --paper-font-menu: { + @apply(--paper-font-common-base); + @apply(--paper-font-common-nowrap); + + font-size: 13px; + font-weight: 500; + line-height: 24px; + }; + + --paper-font-button: { + @apply(--paper-font-common-base); + @apply(--paper-font-common-nowrap); + + font-size: 14px; + font-weight: 500; + letter-spacing: 0.018em; + line-height: 24px; + text-transform: uppercase; + }; + + --paper-font-code2: { + @apply(--paper-font-common-code); + + font-size: 14px; + font-weight: 700; + line-height: 20px; + }; + + --paper-font-code1: { + @apply(--paper-font-common-code); + + font-size: 14px; + font-weight: 500; + line-height: 20px; + }; + + } + +</style><script> + + /** + * `iron-range-behavior` provides the behavior for something with a minimum to maximum range. + * + * @demo demo/index.html + * @polymerBehavior + */ + Polymer.IronRangeBehavior = { + + properties: { + + /** + * The number that represents the current value. + */ + value: { + type: Number, + value: 0, + notify: true, + reflectToAttribute: true + }, + + /** + * The number that indicates the minimum value of the range. + */ + min: { + type: Number, + value: 0, + notify: true + }, + + /** + * The number that indicates the maximum value of the range. + */ + max: { + type: Number, + value: 100, + notify: true + }, + + /** + * Specifies the value granularity of the range's value. + */ + step: { + type: Number, + value: 1, + notify: true + }, + + /** + * Returns the ratio of the value. + */ + ratio: { + type: Number, + value: 0, + readOnly: true, + notify: true + }, + }, + + observers: [ + '_update(value, min, max, step)' + ], + + _calcRatio: function(value) { + return (this._clampValue(value) - this.min) / (this.max - this.min); + }, + + _clampValue: function(value) { + return Math.min(this.max, Math.max(this.min, this._calcStep(value))); + }, + + _calcStep: function(value) { + /** + * if we calculate the step using + * `Math.round(value / step) * step` we may hit a precision point issue + * eg. 0.1 * 0.2 = 0.020000000000000004 + * http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html + * + * as a work around we can divide by the reciprocal of `step` + */ + // polymer/issues/2493 + value = parseFloat(value); + return this.step ? (Math.round((value + this.min) / this.step) - + (this.min / this.step)) / (1 / this.step) : value; + }, + + _validateValue: function() { + var v = this._clampValue(this.value); + this.value = this.oldValue = isNaN(v) ? this.oldValue : v; + return this.value !== v; + }, + + _update: function() { + this._validateValue(); + this._setRatio(this._calcRatio(this.value) * 100); + } + +}; +</script><style is=custom-style> + + :root { + + /* Material Design color palette for Google products */ + + --google-red-100: #f4c7c3; + --google-red-300: #e67c73; + --google-red-500: #db4437; + --google-red-700: #c53929; + + --google-blue-100: #c6dafc; + --google-blue-300: #7baaf7; + --google-blue-500: #4285f4; + --google-blue-700: #3367d6; + + --google-green-100: #b7e1cd; + --google-green-300: #57bb8a; + --google-green-500: #0f9d58; + --google-green-700: #0b8043; + + --google-yellow-100: #fce8b2; + --google-yellow-300: #f7cb4d; + --google-yellow-500: #f4b400; + --google-yellow-700: #f09300; + + --google-grey-100: #f5f5f5; + --google-grey-300: #e0e0e0; + --google-grey-500: #9e9e9e; + --google-grey-700: #616161; + + /* Material Design color palette from online spec document */ + + --paper-red-50: #ffebee; + --paper-red-100: #ffcdd2; + --paper-red-200: #ef9a9a; + --paper-red-300: #e57373; + --paper-red-400: #ef5350; + --paper-red-500: #f44336; + --paper-red-600: #e53935; + --paper-red-700: #d32f2f; + --paper-red-800: #c62828; + --paper-red-900: #b71c1c; + --paper-red-a100: #ff8a80; + --paper-red-a200: #ff5252; + --paper-red-a400: #ff1744; + --paper-red-a700: #d50000; + + --paper-pink-50: #fce4ec; + --paper-pink-100: #f8bbd0; + --paper-pink-200: #f48fb1; + --paper-pink-300: #f06292; + --paper-pink-400: #ec407a; + --paper-pink-500: #e91e63; + --paper-pink-600: #d81b60; + --paper-pink-700: #c2185b; + --paper-pink-800: #ad1457; + --paper-pink-900: #880e4f; + --paper-pink-a100: #ff80ab; + --paper-pink-a200: #ff4081; + --paper-pink-a400: #f50057; + --paper-pink-a700: #c51162; + + --paper-purple-50: #f3e5f5; + --paper-purple-100: #e1bee7; + --paper-purple-200: #ce93d8; + --paper-purple-300: #ba68c8; + --paper-purple-400: #ab47bc; + --paper-purple-500: #9c27b0; + --paper-purple-600: #8e24aa; + --paper-purple-700: #7b1fa2; + --paper-purple-800: #6a1b9a; + --paper-purple-900: #4a148c; + --paper-purple-a100: #ea80fc; + --paper-purple-a200: #e040fb; + --paper-purple-a400: #d500f9; + --paper-purple-a700: #aa00ff; + + --paper-deep-purple-50: #ede7f6; + --paper-deep-purple-100: #d1c4e9; + --paper-deep-purple-200: #b39ddb; + --paper-deep-purple-300: #9575cd; + --paper-deep-purple-400: #7e57c2; + --paper-deep-purple-500: #673ab7; + --paper-deep-purple-600: #5e35b1; + --paper-deep-purple-700: #512da8; + --paper-deep-purple-800: #4527a0; + --paper-deep-purple-900: #311b92; + --paper-deep-purple-a100: #b388ff; + --paper-deep-purple-a200: #7c4dff; + --paper-deep-purple-a400: #651fff; + --paper-deep-purple-a700: #6200ea; + + --paper-indigo-50: #e8eaf6; + --paper-indigo-100: #c5cae9; + --paper-indigo-200: #9fa8da; + --paper-indigo-300: #7986cb; + --paper-indigo-400: #5c6bc0; + --paper-indigo-500: #3f51b5; + --paper-indigo-600: #3949ab; + --paper-indigo-700: #303f9f; + --paper-indigo-800: #283593; + --paper-indigo-900: #1a237e; + --paper-indigo-a100: #8c9eff; + --paper-indigo-a200: #536dfe; + --paper-indigo-a400: #3d5afe; + --paper-indigo-a700: #304ffe; + + --paper-blue-50: #e3f2fd; + --paper-blue-100: #bbdefb; + --paper-blue-200: #90caf9; + --paper-blue-300: #64b5f6; + --paper-blue-400: #42a5f5; + --paper-blue-500: #2196f3; + --paper-blue-600: #1e88e5; + --paper-blue-700: #1976d2; + --paper-blue-800: #1565c0; + --paper-blue-900: #0d47a1; + --paper-blue-a100: #82b1ff; + --paper-blue-a200: #448aff; + --paper-blue-a400: #2979ff; + --paper-blue-a700: #2962ff; + + --paper-light-blue-50: #e1f5fe; + --paper-light-blue-100: #b3e5fc; + --paper-light-blue-200: #81d4fa; + --paper-light-blue-300: #4fc3f7; + --paper-light-blue-400: #29b6f6; + --paper-light-blue-500: #03a9f4; + --paper-light-blue-600: #039be5; + --paper-light-blue-700: #0288d1; + --paper-light-blue-800: #0277bd; + --paper-light-blue-900: #01579b; + --paper-light-blue-a100: #80d8ff; + --paper-light-blue-a200: #40c4ff; + --paper-light-blue-a400: #00b0ff; + --paper-light-blue-a700: #0091ea; + + --paper-cyan-50: #e0f7fa; + --paper-cyan-100: #b2ebf2; + --paper-cyan-200: #80deea; + --paper-cyan-300: #4dd0e1; + --paper-cyan-400: #26c6da; + --paper-cyan-500: #00bcd4; + --paper-cyan-600: #00acc1; + --paper-cyan-700: #0097a7; + --paper-cyan-800: #00838f; + --paper-cyan-900: #006064; + --paper-cyan-a100: #84ffff; + --paper-cyan-a200: #18ffff; + --paper-cyan-a400: #00e5ff; + --paper-cyan-a700: #00b8d4; + + --paper-teal-50: #e0f2f1; + --paper-teal-100: #b2dfdb; + --paper-teal-200: #80cbc4; + --paper-teal-300: #4db6ac; + --paper-teal-400: #26a69a; + --paper-teal-500: #009688; + --paper-teal-600: #00897b; + --paper-teal-700: #00796b; + --paper-teal-800: #00695c; + --paper-teal-900: #004d40; + --paper-teal-a100: #a7ffeb; + --paper-teal-a200: #64ffda; + --paper-teal-a400: #1de9b6; + --paper-teal-a700: #00bfa5; + + --paper-green-50: #e8f5e9; + --paper-green-100: #c8e6c9; + --paper-green-200: #a5d6a7; + --paper-green-300: #81c784; + --paper-green-400: #66bb6a; + --paper-green-500: #4caf50; + --paper-green-600: #43a047; + --paper-green-700: #388e3c; + --paper-green-800: #2e7d32; + --paper-green-900: #1b5e20; + --paper-green-a100: #b9f6ca; + --paper-green-a200: #69f0ae; + --paper-green-a400: #00e676; + --paper-green-a700: #00c853; + + --paper-light-green-50: #f1f8e9; + --paper-light-green-100: #dcedc8; + --paper-light-green-200: #c5e1a5; + --paper-light-green-300: #aed581; + --paper-light-green-400: #9ccc65; + --paper-light-green-500: #8bc34a; + --paper-light-green-600: #7cb342; + --paper-light-green-700: #689f38; + --paper-light-green-800: #558b2f; + --paper-light-green-900: #33691e; + --paper-light-green-a100: #ccff90; + --paper-light-green-a200: #b2ff59; + --paper-light-green-a400: #76ff03; + --paper-light-green-a700: #64dd17; + + --paper-lime-50: #f9fbe7; + --paper-lime-100: #f0f4c3; + --paper-lime-200: #e6ee9c; + --paper-lime-300: #dce775; + --paper-lime-400: #d4e157; + --paper-lime-500: #cddc39; + --paper-lime-600: #c0ca33; + --paper-lime-700: #afb42b; + --paper-lime-800: #9e9d24; + --paper-lime-900: #827717; + --paper-lime-a100: #f4ff81; + --paper-lime-a200: #eeff41; + --paper-lime-a400: #c6ff00; + --paper-lime-a700: #aeea00; + + --paper-yellow-50: #fffde7; + --paper-yellow-100: #fff9c4; + --paper-yellow-200: #fff59d; + --paper-yellow-300: #fff176; + --paper-yellow-400: #ffee58; + --paper-yellow-500: #ffeb3b; + --paper-yellow-600: #fdd835; + --paper-yellow-700: #fbc02d; + --paper-yellow-800: #f9a825; + --paper-yellow-900: #f57f17; + --paper-yellow-a100: #ffff8d; + --paper-yellow-a200: #ffff00; + --paper-yellow-a400: #ffea00; + --paper-yellow-a700: #ffd600; + + --paper-amber-50: #fff8e1; + --paper-amber-100: #ffecb3; + --paper-amber-200: #ffe082; + --paper-amber-300: #ffd54f; + --paper-amber-400: #ffca28; + --paper-amber-500: #ffc107; + --paper-amber-600: #ffb300; + --paper-amber-700: #ffa000; + --paper-amber-800: #ff8f00; + --paper-amber-900: #ff6f00; + --paper-amber-a100: #ffe57f; + --paper-amber-a200: #ffd740; + --paper-amber-a400: #ffc400; + --paper-amber-a700: #ffab00; + + --paper-orange-50: #fff3e0; + --paper-orange-100: #ffe0b2; + --paper-orange-200: #ffcc80; + --paper-orange-300: #ffb74d; + --paper-orange-400: #ffa726; + --paper-orange-500: #ff9800; + --paper-orange-600: #fb8c00; + --paper-orange-700: #f57c00; + --paper-orange-800: #ef6c00; + --paper-orange-900: #e65100; + --paper-orange-a100: #ffd180; + --paper-orange-a200: #ffab40; + --paper-orange-a400: #ff9100; + --paper-orange-a700: #ff6500; + + --paper-deep-orange-50: #fbe9e7; + --paper-deep-orange-100: #ffccbc; + --paper-deep-orange-200: #ffab91; + --paper-deep-orange-300: #ff8a65; + --paper-deep-orange-400: #ff7043; + --paper-deep-orange-500: #ff5722; + --paper-deep-orange-600: #f4511e; + --paper-deep-orange-700: #e64a19; + --paper-deep-orange-800: #d84315; + --paper-deep-orange-900: #bf360c; + --paper-deep-orange-a100: #ff9e80; + --paper-deep-orange-a200: #ff6e40; + --paper-deep-orange-a400: #ff3d00; + --paper-deep-orange-a700: #dd2c00; + + --paper-brown-50: #efebe9; + --paper-brown-100: #d7ccc8; + --paper-brown-200: #bcaaa4; + --paper-brown-300: #a1887f; + --paper-brown-400: #8d6e63; + --paper-brown-500: #795548; + --paper-brown-600: #6d4c41; + --paper-brown-700: #5d4037; + --paper-brown-800: #4e342e; + --paper-brown-900: #3e2723; + + --paper-grey-50: #fafafa; + --paper-grey-100: #f5f5f5; + --paper-grey-200: #eeeeee; + --paper-grey-300: #e0e0e0; + --paper-grey-400: #bdbdbd; + --paper-grey-500: #9e9e9e; + --paper-grey-600: #757575; + --paper-grey-700: #616161; + --paper-grey-800: #424242; + --paper-grey-900: #212121; + + --paper-blue-grey-50: #eceff1; + --paper-blue-grey-100: #cfd8dc; + --paper-blue-grey-200: #b0bec5; + --paper-blue-grey-300: #90a4ae; + --paper-blue-grey-400: #78909c; + --paper-blue-grey-500: #607d8b; + --paper-blue-grey-600: #546e7a; + --paper-blue-grey-700: #455a64; + --paper-blue-grey-800: #37474f; + --paper-blue-grey-900: #263238; + + /* opacity for dark text on a light background */ + --dark-divider-opacity: 0.12; + --dark-disabled-opacity: 0.38; /* or hint text or icon */ + --dark-secondary-opacity: 0.54; + --dark-primary-opacity: 0.87; + + /* opacity for light text on a dark background */ + --light-divider-opacity: 0.12; + --light-disabled-opacity: 0.3; /* or hint text or icon */ + --light-secondary-opacity: 0.7; + --light-primary-opacity: 1.0; + + } + +</style><style> + /* IE 10 support for HTML5 hidden attr */ + [hidden] { + display: none !important; + } +</style><style is=custom-style> + :root { + + --layout: { + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + }; + + --layout-inline: { + display: -ms-inline-flexbox; + display: -webkit-inline-flex; + display: inline-flex; + }; + + --layout-horizontal: { + @apply(--layout); + + -ms-flex-direction: row; + -webkit-flex-direction: row; + flex-direction: row; + }; + + --layout-horizontal-reverse: { + @apply(--layout); + + -ms-flex-direction: row-reverse; + -webkit-flex-direction: row-reverse; + flex-direction: row-reverse; + }; + + --layout-vertical: { + @apply(--layout); + + -ms-flex-direction: column; + -webkit-flex-direction: column; + flex-direction: column; + }; + + --layout-vertical-reverse: { + @apply(--layout); + + -ms-flex-direction: column-reverse; + -webkit-flex-direction: column-reverse; + flex-direction: column-reverse; + }; + + --layout-wrap: { + -ms-flex-wrap: wrap; + -webkit-flex-wrap: wrap; + flex-wrap: wrap; + }; + + --layout-wrap-reverse: { + -ms-flex-wrap: wrap-reverse; + -webkit-flex-wrap: wrap-reverse; + flex-wrap: wrap-reverse; + }; + + --layout-flex-auto: { + -ms-flex: 1 1 auto; + -webkit-flex: 1 1 auto; + flex: 1 1 auto; + }; + + --layout-flex-none: { + -ms-flex: none; + -webkit-flex: none; + flex: none; + }; + + --layout-flex: { + -ms-flex: 1 1 0.000000001px; + -webkit-flex: 1; + flex: 1; + -webkit-flex-basis: 0.000000001px; + flex-basis: 0.000000001px; + }; + + --layout-flex-2: { + -ms-flex: 2; + -webkit-flex: 2; + flex: 2; + }; + + --layout-flex-3: { + -ms-flex: 3; + -webkit-flex: 3; + flex: 3; + }; + + --layout-flex-4: { + -ms-flex: 4; + -webkit-flex: 4; + flex: 4; + }; + + --layout-flex-5: { + -ms-flex: 5; + -webkit-flex: 5; + flex: 5; + }; + + --layout-flex-6: { + -ms-flex: 6; + -webkit-flex: 6; + flex: 6; + }; + + --layout-flex-7: { + -ms-flex: 7; + -webkit-flex: 7; + flex: 7; + }; + + --layout-flex-8: { + -ms-flex: 8; + -webkit-flex: 8; + flex: 8; + }; + + --layout-flex-9: { + -ms-flex: 9; + -webkit-flex: 9; + flex: 9; + }; + + --layout-flex-10: { + -ms-flex: 10; + -webkit-flex: 10; + flex: 10; + }; + + --layout-flex-11: { + -ms-flex: 11; + -webkit-flex: 11; + flex: 11; + }; + + --layout-flex-12: { + -ms-flex: 12; + -webkit-flex: 12; + flex: 12; + }; + + /* alignment in cross axis */ + + --layout-start: { + -ms-flex-align: start; + -webkit-align-items: flex-start; + align-items: flex-start; + }; + + --layout-center: { + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; + }; + + --layout-end: { + -ms-flex-align: end; + -webkit-align-items: flex-end; + align-items: flex-end; + }; + + /* alignment in main axis */ + + --layout-start-justified: { + -ms-flex-pack: start; + -webkit-justify-content: flex-start; + justify-content: flex-start; + }; + + --layout-center-justified: { + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + }; + + --layout-end-justified: { + -ms-flex-pack: end; + -webkit-justify-content: flex-end; + justify-content: flex-end; + }; + + --layout-around-justified: { + -ms-flex-pack: around; + -webkit-justify-content: space-around; + justify-content: space-around; + }; + + --layout-justified: { + -ms-flex-pack: justify; + -webkit-justify-content: space-between; + justify-content: space-between; + }; + + --layout-center-center: { + @apply(--layout-center); + @apply(--layout-center-justified); + }; + + /* self alignment */ + + --layout-self-start: { + -ms-align-self: flex-start; + -webkit-align-self: flex-start; + align-self: flex-start; + }; + + --layout-self-center: { + -ms-align-self: center; + -webkit-align-self: center; + align-self: center; + }; + + --layout-self-end: { + -ms-align-self: flex-end; + -webkit-align-self: flex-end; + align-self: flex-end; + }; + + --layout-self-stretch: { + -ms-align-self: stretch; + -webkit-align-self: stretch; + align-self: stretch; + }; + + /******************************* + Other Layout + *******************************/ + + --layout-block: { + display: block; + }; + + --layout-invisible: { + visibility: hidden !important; + }; + + --layout-relative: { + position: relative; + }; + + --layout-fit: { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + }; + + --layout-scroll: { + -webkit-overflow-scrolling: touch; + overflow: auto; + }; + + --layout-fullbleed: { + margin: 0; + height: 100vh; + }; + + /* fixed position */ + + --layout-fixed-top: { + position: fixed; + top: 0; + left: 0; + right: 0; + }; + + --layout-fixed-right: { + position: fixed; + top: 0; + right: 0; + bottom: 0; + }; + + --layout-fixed-bottom: { + position: fixed; + right: 0; + bottom: 0; + left: 0; + }; + + --layout-fixed-left: { + position: fixed; + top: 0; + bottom: 0; + left: 0; + }; + + } + +</style><script> + + /** + * @param {!Function} selectCallback + * @constructor + */ + Polymer.IronSelection = function(selectCallback) { + this.selection = []; + this.selectCallback = selectCallback; + }; + + Polymer.IronSelection.prototype = { + + /** + * Retrieves the selected item(s). + * + * @method get + * @returns Returns the selected item(s). If the multi property is true, + * `get` will return an array, otherwise it will return + * the selected item or undefined if there is no selection. + */ + get: function() { + return this.multi ? this.selection.slice() : this.selection[0]; + }, + + /** + * Clears all the selection except the ones indicated. + * + * @method clear + * @param {Array} excludes items to be excluded. + */ + clear: function(excludes) { + this.selection.slice().forEach(function(item) { + if (!excludes || excludes.indexOf(item) < 0) { + this.setItemSelected(item, false); + } + }, this); + }, + + /** + * Indicates if a given item is selected. + * + * @method isSelected + * @param {*} item The item whose selection state should be checked. + * @returns Returns true if `item` is selected. + */ + isSelected: function(item) { + return this.selection.indexOf(item) >= 0; + }, + + /** + * Sets the selection state for a given item to either selected or deselected. + * + * @method setItemSelected + * @param {*} item The item to select. + * @param {boolean} isSelected True for selected, false for deselected. + */ + setItemSelected: function(item, isSelected) { + if (item != null) { + if (isSelected) { + this.selection.push(item); + } else { + var i = this.selection.indexOf(item); + if (i >= 0) { + this.selection.splice(i, 1); + } + } + if (this.selectCallback) { + this.selectCallback(item, isSelected); + } + } + }, + + /** + * Sets the selection state for a given item. If the `multi` property + * is true, then the selected state of `item` will be toggled; otherwise + * the `item` will be selected. + * + * @method select + * @param {*} item The item to select. + */ + select: function(item) { + if (this.multi) { + this.toggle(item); + } else if (this.get() !== item) { + this.setItemSelected(this.get(), false); + this.setItemSelected(item, true); + } + }, + + /** + * Toggles the selection state for `item`. + * + * @method toggle + * @param {*} item The item to toggle. + */ + toggle: function(item) { + this.setItemSelected(item, !this.isSelected(item)); + } + + }; + +</script><script> + + /** @polymerBehavior */ + Polymer.IronSelectableBehavior = { + + /** + * Fired when iron-selector is activated (selected or deselected). + * It is fired before the selected items are changed. + * Cancel the event to abort selection. + * + * @event iron-activate + */ + + /** + * Fired when an item is selected + * + * @event iron-select + */ + + /** + * Fired when an item is deselected + * + * @event iron-deselect + */ + + /** + * Fired when the list of selectable items changes (e.g., items are + * added or removed). The detail of the event is a list of mutation + * records that describe what changed. + * + * @event iron-items-changed + */ + + properties: { + + /** + * If you want to use the attribute value of an element for `selected` instead of the index, + * set this to the name of the attribute. + */ + attrForSelected: { + type: String, + value: null + }, + + /** + * Gets or sets the selected element. The default is to use the index of the item. + */ + selected: { + type: String, + notify: true + }, + + /** + * Returns the currently selected item. + * + * @type {?Object} + */ + selectedItem: { + type: Object, + readOnly: true, + notify: true + }, + + /** + * The event that fires from items when they are selected. Selectable + * will listen for this event from items and update the selection state. + * Set to empty string to listen to no events. + */ + activateEvent: { + type: String, + value: 'tap', + observer: '_activateEventChanged' + }, + + /** + * This is a CSS selector string. If this is set, only items that match the CSS selector + * are selectable. + */ + selectable: String, + + /** + * The class to set on elements when selected. + */ + selectedClass: { + type: String, + value: 'iron-selected' + }, + + /** + * The attribute to set on elements when selected. + */ + selectedAttribute: { + type: String, + value: null + }, + + /** + * The list of items from which a selection can be made. + */ + items: { + type: Array, + readOnly: true, + value: function() { + return []; + } + }, + + /** + * The set of excluded elements where the key is the `localName` + * of the element that will be ignored from the item list. + * + * @default {template: 1} + */ + _excludedLocalNames: { + type: Object, + value: function() { + return { + 'template': 1 + }; + } + } + }, + + observers: [ + '_updateSelected(attrForSelected, selected)' + ], + + created: function() { + this._bindFilterItem = this._filterItem.bind(this); + this._selection = new Polymer.IronSelection(this._applySelection.bind(this)); + }, + + attached: function() { + this._observer = this._observeItems(this); + this._updateItems(); + if (!this._shouldUpdateSelection) { + this._updateSelected(this.attrForSelected,this.selected) + } + this._addListener(this.activateEvent); + }, + + detached: function() { + if (this._observer) { + Polymer.dom(this).unobserveNodes(this._observer); + } + this._removeListener(this.activateEvent); + }, + + /** + * Returns the index of the given item. + * + * @method indexOf + * @param {Object} item + * @returns Returns the index of the item + */ + indexOf: function(item) { + return this.items.indexOf(item); + }, + + /** + * Selects the given value. + * + * @method select + * @param {string} value the value to select. + */ + select: function(value) { + this.selected = value; + }, + + /** + * Selects the previous item. + * + * @method selectPrevious + */ + selectPrevious: function() { + var length = this.items.length; + var index = (Number(this._valueToIndex(this.selected)) - 1 + length) % length; + this.selected = this._indexToValue(index); + }, + + /** + * Selects the next item. + * + * @method selectNext + */ + selectNext: function() { + var index = (Number(this._valueToIndex(this.selected)) + 1) % this.items.length; + this.selected = this._indexToValue(index); + }, + + get _shouldUpdateSelection() { + return this.selected != null; + }, + + _addListener: function(eventName) { + this.listen(this, eventName, '_activateHandler'); + }, + + _removeListener: function(eventName) { + this.unlisten(this, eventName, '_activateHandler'); + }, + + _activateEventChanged: function(eventName, old) { + this._removeListener(old); + this._addListener(eventName); + }, + + _updateItems: function() { + var nodes = Polymer.dom(this).queryDistributedElements(this.selectable || '*'); + nodes = Array.prototype.filter.call(nodes, this._bindFilterItem); + this._setItems(nodes); + }, + + _updateSelected: function() { + this._selectSelected(this.selected); + }, + + _selectSelected: function(selected) { + this._selection.select(this._valueToItem(this.selected)); + }, + + _filterItem: function(node) { + return !this._excludedLocalNames[node.localName]; + }, + + _valueToItem: function(value) { + return (value == null) ? null : this.items[this._valueToIndex(value)]; + }, + + _valueToIndex: function(value) { + if (this.attrForSelected) { + for (var i = 0, item; item = this.items[i]; i++) { + if (this._valueForItem(item) == value) { + return i; + } + } + } else { + return Number(value); + } + }, + + _indexToValue: function(index) { + if (this.attrForSelected) { + var item = this.items[index]; + if (item) { + return this._valueForItem(item); + } + } else { + return index; + } + }, + + _valueForItem: function(item) { + return item[this.attrForSelected] || item.getAttribute(this.attrForSelected); + }, + + _applySelection: function(item, isSelected) { + if (this.selectedClass) { + this.toggleClass(this.selectedClass, isSelected, item); + } + if (this.selectedAttribute) { + this.toggleAttribute(this.selectedAttribute, isSelected, item); + } + this._selectionChange(); + this.fire('iron-' + (isSelected ? 'select' : 'deselect'), {item: item}); + }, + + _selectionChange: function() { + this._setSelectedItem(this._selection.get()); + }, + + // observe items change under the given node. + _observeItems: function(node) { + return Polymer.dom(node).observeNodes(function(mutations) { + // Let other interested parties know about the change so that + // we don't have to recreate mutation observers everywher. + this.fire('iron-items-changed', mutations, { + bubbles: false, + cancelable: false + }); + + this._updateItems(); + + if (this._shouldUpdateSelection) { + this._updateSelected(); + } + }); + }, + + _activateHandler: function(e) { + var t = e.target; + var items = this.items; + while (t && t != this) { + var i = items.indexOf(t); + if (i >= 0) { + var value = this._indexToValue(i); + this._itemActivate(value, t); + return; + } + t = t.parentNode; + } + }, + + _itemActivate: function(value, item) { + if (!this.fire('iron-activate', + {selected: value, item: item}, {cancelable: true}).defaultPrevented) { + this.select(value); + } + } + + }; + +</script><script> + + (function() { + + // monostate data + var metaDatas = {}; + var metaArrays = {}; + var singleton = null; + + Polymer.IronMeta = Polymer({ + + is: 'iron-meta', + + properties: { + + /** + * The type of meta-data. All meta-data of the same type is stored + * together. + */ + type: { + type: String, + value: 'default', + observer: '_typeChanged' + }, + + /** + * The key used to store `value` under the `type` namespace. + */ + key: { + type: String, + observer: '_keyChanged' + }, + + /** + * The meta-data to store or retrieve. + */ + value: { + type: Object, + notify: true, + observer: '_valueChanged' + }, + + /** + * If true, `value` is set to the iron-meta instance itself. + */ + self: { + type: Boolean, + observer: '_selfChanged' + }, + + /** + * Array of all meta-data values for the given type. + */ + list: { + type: Array, + notify: true + } + + }, + + hostAttributes: { + hidden: true + }, + + /** + * Only runs if someone invokes the factory/constructor directly + * e.g. `new Polymer.IronMeta()` + * + * @param {{type: (string|undefined), key: (string|undefined), value}=} config + */ + factoryImpl: function(config) { + if (config) { + for (var n in config) { + switch(n) { + case 'type': + case 'key': + case 'value': + this[n] = config[n]; + break; + } + } + } + }, + + created: function() { + // TODO(sjmiles): good for debugging? + this._metaDatas = metaDatas; + this._metaArrays = metaArrays; + }, + + _keyChanged: function(key, old) { + this._resetRegistration(old); + }, + + _valueChanged: function(value) { + this._resetRegistration(this.key); + }, + + _selfChanged: function(self) { + if (self) { + this.value = this; + } + }, + + _typeChanged: function(type) { + this._unregisterKey(this.key); + if (!metaDatas[type]) { + metaDatas[type] = {}; + } + this._metaData = metaDatas[type]; + if (!metaArrays[type]) { + metaArrays[type] = []; + } + this.list = metaArrays[type]; + this._registerKeyValue(this.key, this.value); + }, + + /** + * Retrieves meta data value by key. + * + * @method byKey + * @param {string} key The key of the meta-data to be returned. + * @return {*} + */ + byKey: function(key) { + return this._metaData && this._metaData[key]; + }, + + _resetRegistration: function(oldKey) { + this._unregisterKey(oldKey); + this._registerKeyValue(this.key, this.value); + }, + + _unregisterKey: function(key) { + this._unregister(key, this._metaData, this.list); + }, + + _registerKeyValue: function(key, value) { + this._register(key, value, this._metaData, this.list); + }, + + _register: function(key, value, data, list) { + if (key && data && value !== undefined) { + data[key] = value; + list.push(value); + } + }, + + _unregister: function(key, data, list) { + if (key && data) { + if (key in data) { + var value = data[key]; + delete data[key]; + this.arrayDelete(list, value); + } + } + } + + }); + + Polymer.IronMeta.getIronMeta = function getIronMeta() { + if (singleton === null) { + singleton = new Polymer.IronMeta(); + } + return singleton; + }; + + /** + `iron-meta-query` can be used to access infomation stored in `iron-meta`. + + Examples: + + If I create an instance like this: + + <iron-meta key="info" value="foo/bar"></iron-meta> + + Note that value="foo/bar" is the metadata I've defined. I could define more + attributes or use child nodes to define additional metadata. + + Now I can access that element (and it's metadata) from any `iron-meta-query` instance: + + var value = new Polymer.IronMetaQuery({key: 'info'}).value; + + @group Polymer Iron Elements + @element iron-meta-query + */ + Polymer.IronMetaQuery = Polymer({ + + is: 'iron-meta-query', + + properties: { + + /** + * The type of meta-data. All meta-data of the same type is stored + * together. + */ + type: { + type: String, + value: 'default', + observer: '_typeChanged' + }, + + /** + * Specifies a key to use for retrieving `value` from the `type` + * namespace. + */ + key: { + type: String, + observer: '_keyChanged' + }, + + /** + * The meta-data to store or retrieve. + */ + value: { + type: Object, + notify: true, + readOnly: true + }, + + /** + * Array of all meta-data values for the given type. + */ + list: { + type: Array, + notify: true + } + + }, + + /** + * Actually a factory method, not a true constructor. Only runs if + * someone invokes it directly (via `new Polymer.IronMeta()`); + * + * @param {{type: (string|undefined), key: (string|undefined)}=} config + */ + factoryImpl: function(config) { + if (config) { + for (var n in config) { + switch(n) { + case 'type': + case 'key': + this[n] = config[n]; + break; + } + } + } + }, + + created: function() { + // TODO(sjmiles): good for debugging? + this._metaDatas = metaDatas; + this._metaArrays = metaArrays; + }, + + _keyChanged: function(key) { + this._setValue(this._metaData && this._metaData[key]); + }, + + _typeChanged: function(type) { + this._metaData = metaDatas[type]; + this.list = metaArrays[type]; + if (this.key) { + this._keyChanged(this.key); + } + }, + + /** + * Retrieves meta data value by key. + * @param {string} key The key of the meta-data to be returned. + * @return {*} + */ + byKey: function(key) { + return this._metaData && this._metaData[key]; + } + + }); + + })(); +</script><script> + + /** + * Use `Polymer.NeonAnimationBehavior` to implement an animation. + * @polymerBehavior + */ + Polymer.NeonAnimationBehavior = { + + properties: { + + /** + * Defines the animation timing. + */ + animationTiming: { + type: Object, + value: function() { + return { + duration: 500, + easing: 'cubic-bezier(0.4, 0, 0.2, 1)', + fill: 'both' + } + } + } + + }, + + registered: function() { + new Polymer.IronMeta({type: 'animation', key: this.is, value: this.constructor}); + }, + + /** + * Do any animation configuration here. + */ + // configure: function(config) { + // }, + + /** + * Returns the animation timing by mixing in properties from `config` to the defaults defined + * by the animation. + */ + timingFromConfig: function(config) { + if (config.timing) { + for (var property in config.timing) { + this.animationTiming[property] = config.timing[property]; + } + } + return this.animationTiming; + }, + + /** + * Sets `transform` and `transformOrigin` properties along with the prefixed versions. + */ + setPrefixedProperty: function(node, property, value) { + var map = { + 'transform': ['webkitTransform'], + 'transformOrigin': ['mozTransformOrigin', 'webkitTransformOrigin'] + }; + var prefixes = map[property]; + for (var prefix, index = 0; prefix = prefixes[index]; index++) { + node.style[prefix] = value; + } + node.style[property] = value; + }, + + /** + * Called when the animation finishes. + */ + complete: function() {} + + }; + +</script><script>// Copyright 2014 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +!function(a,b){b["true"]=a;var c={},d={},e={},f=null;!function(a){function b(a){if("number"==typeof a)return a;var b={};for(var c in a)b[c]=a[c];return b}function c(){this._delay=0,this._endDelay=0,this._fill="none",this._iterationStart=0,this._iterations=1,this._duration=0,this._playbackRate=1,this._direction="normal",this._easing="linear"}function d(b,d){var e=new c;return d&&(e.fill="both",e.duration="auto"),"number"!=typeof b||isNaN(b)?void 0!==b&&Object.getOwnPropertyNames(b).forEach(function(c){if("auto"!=b[c]){if(("number"==typeof e[c]||"duration"==c)&&("number"!=typeof b[c]||isNaN(b[c])))return;if("fill"==c&&-1==s.indexOf(b[c]))return;if("direction"==c&&-1==t.indexOf(b[c]))return;if("playbackRate"==c&&1!==b[c]&&a.isDeprecated("AnimationEffectTiming.playbackRate","2014-11-28","Use Animation.playbackRate instead."))return;e[c]=b[c]}}):e.duration=b,e}function e(a){return"number"==typeof a&&(a=isNaN(a)?{duration:0}:{duration:a}),a}function f(b,c){b=a.numericTimingToObject(b);var e=d(b,c);return e._easing=i(e.easing),e}function g(a,b,c,d){return 0>a||a>1||0>c||c>1?B:function(e){function f(a,b,c){return 3*a*(1-c)*(1-c)*c+3*b*(1-c)*c*c+c*c*c}if(0==e||1==e)return e;for(var g=0,h=1;;){var i=(g+h)/2,j=f(a,c,i);if(Math.abs(e-j)<.001)return f(b,d,i);e>j?g=i:h=i}}}function h(a,b){return function(c){if(c>=1)return 1;var d=1/a;return c+=b*d,c-c%d}}function i(a){var b=z.exec(a);if(b)return g.apply(this,b.slice(1).map(Number));var c=A.exec(a);if(c)return h(Number(c[1]),{start:u,middle:v,end:w}[c[2]]);var d=x[a];return d?d:B}function j(a){return Math.abs(k(a)/a.playbackRate)}function k(a){return a.duration*a.iterations}function l(a,b,c){return null==b?C:b<c.delay?D:b>=c.delay+a?E:F}function m(a,b,c,d,e){switch(d){case D:return"backwards"==b||"both"==b?0:null;case F:return c-e;case E:return"forwards"==b||"both"==b?a:null;case C:return null}}function n(a,b,c,d){return(d.playbackRate<0?b-a:b)*d.playbackRate+c}function o(a,b,c,d,e){return 1/0===c||c===-1/0||c-d==b&&e.iterations&&(e.iterations+e.iterationStart)%1==0?a:c%a}function p(a,b,c,d){return 0===c?0:b==a?d.iterationStart+d.iterations-1:Math.floor(c/a)}function q(a,b,c,d){var e=a%2>=1,f="normal"==d.direction||d.direction==(e?"alternate-reverse":"alternate"),g=f?c:b-c,h=g/b;return b*d.easing(h)}function r(a,b,c){var d=l(a,b,c),e=m(a,c.fill,b,d,c.delay);if(null===e)return null;if(0===a)return d===D?0:1;var f=c.iterationStart*c.duration,g=n(a,e,f,c),h=o(c.duration,k(c),g,f,c),i=p(c.duration,h,g,c);return q(i,c.duration,h,c)/c.duration}var s="backwards|forwards|both|none".split("|"),t="reverse|alternate|alternate-reverse".split("|");c.prototype={_setMember:function(b,c){this["_"+b]=c,this._effect&&(this._effect._timingInput[b]=c,this._effect._timing=a.normalizeTimingInput(a.normalizeTimingInput(this._effect._timingInput)),this._effect.activeDuration=a.calculateActiveDuration(this._effect._timing),this._effect._animation&&this._effect._animation._rebuildUnderlyingAnimation())},get playbackRate(){return this._playbackRate},set delay(a){this._setMember("delay",a)},get delay(){return this._delay},set endDelay(a){this._setMember("endDelay",a)},get endDelay(){return this._endDelay},set fill(a){this._setMember("fill",a)},get fill(){return this._fill},set iterationStart(a){this._setMember("iterationStart",a)},get iterationStart(){return this._iterationStart},set duration(a){this._setMember("duration",a)},get duration(){return this._duration},set direction(a){this._setMember("direction",a)},get direction(){return this._direction},set easing(a){this._setMember("easing",a)},get easing(){return this._easing},set iterations(a){this._setMember("iterations",a)},get iterations(){return this._iterations}};var u=1,v=.5,w=0,x={ease:g(.25,.1,.25,1),"ease-in":g(.42,0,1,1),"ease-out":g(0,0,.58,1),"ease-in-out":g(.42,0,.58,1),"step-start":h(1,u),"step-middle":h(1,v),"step-end":h(1,w)},y="\\s*(-?\\d+\\.?\\d*|-?\\.\\d+)\\s*",z=new RegExp("cubic-bezier\\("+y+","+y+","+y+","+y+"\\)"),A=/steps\(\s*(\d+)\s*,\s*(start|middle|end)\s*\)/,B=function(a){return a},C=0,D=1,E=2,F=3;a.cloneTimingInput=b,a.makeTiming=d,a.numericTimingToObject=e,a.normalizeTimingInput=f,a.calculateActiveDuration=j,a.calculateTimeFraction=r,a.calculatePhase=l,a.toTimingFunction=i}(c,f),function(a){function b(a,b){return a in h?h[a][b]||b:b}function c(a,c,d){var g=e[a];if(g){f.style[a]=c;for(var h in g){var i=g[h],j=f.style[i];d[i]=b(i,j)}}else d[a]=b(a,c)}function d(b){function d(){var a=e.length;null==e[a-1].offset&&(e[a-1].offset=1),a>1&&null==e[0].offset&&(e[0].offset=0);for(var b=0,c=e[0].offset,d=1;a>d;d++){var f=e[d].offset;if(null!=f){for(var g=1;d-b>g;g++)e[b+g].offset=c+(f-c)*g/(d-b);b=d,c=f}}}if(!Array.isArray(b)&&null!==b)throw new TypeError("Keyframes must be null or an array of keyframes");if(null==b)return[];for(var e=b.map(function(b){var d={};for(var e in b){var f=b[e];if("offset"==e){if(null!=f&&(f=Number(f),!isFinite(f)))throw new TypeError("keyframe offsets must be numbers.")}else{if("composite"==e)throw{type:DOMException.NOT_SUPPORTED_ERR,name:"NotSupportedError",message:"add compositing is not supported"};f="easing"==e?a.toTimingFunction(f):""+f}c(e,f,d)}return void 0==d.offset&&(d.offset=null),void 0==d.easing&&(d.easing=a.toTimingFunction("linear")),d}),f=!0,g=-1/0,h=0;h<e.length;h++){var i=e[h].offset;if(null!=i){if(g>i)throw{code:DOMException.INVALID_MODIFICATION_ERR,name:"InvalidModificationError",message:"Keyframes are not loosely sorted by offset. Sort or specify offsets."};g=i}else f=!1}return e=e.filter(function(a){return a.offset>=0&&a.offset<=1}),f||d(),e}var e={background:["backgroundImage","backgroundPosition","backgroundSize","backgroundRepeat","backgroundAttachment","backgroundOrigin","backgroundClip","backgroundColor"],border:["borderTopColor","borderTopStyle","borderTopWidth","borderRightColor","borderRightStyle","borderRightWidth","borderBottomColor","borderBottomStyle","borderBottomWidth","borderLeftColor","borderLeftStyle","borderLeftWidth"],borderBottom:["borderBottomWidth","borderBottomStyle","borderBottomColor"],borderColor:["borderTopColor","borderRightColor","borderBottomColor","borderLeftColor"],borderLeft:["borderLeftWidth","borderLeftStyle","borderLeftColor"],borderRadius:["borderTopLeftRadius","borderTopRightRadius","borderBottomRightRadius","borderBottomLeftRadius"],borderRight:["borderRightWidth","borderRightStyle","borderRightColor"],borderTop:["borderTopWidth","borderTopStyle","borderTopColor"],borderWidth:["borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth"],flex:["flexGrow","flexShrink","flexBasis"],font:["fontFamily","fontSize","fontStyle","fontVariant","fontWeight","lineHeight"],margin:["marginTop","marginRight","marginBottom","marginLeft"],outline:["outlineColor","outlineStyle","outlineWidth"],padding:["paddingTop","paddingRight","paddingBottom","paddingLeft"]},f=document.createElementNS("http://www.w3.org/1999/xhtml","div"),g={thin:"1px",medium:"3px",thick:"5px"},h={borderBottomWidth:g,borderLeftWidth:g,borderRightWidth:g,borderTopWidth:g,fontSize:{"xx-small":"60%","x-small":"75%",small:"89%",medium:"100%",large:"120%","x-large":"150%","xx-large":"200%"},fontWeight:{normal:"400",bold:"700"},outlineWidth:g,textShadow:{none:"0px 0px 0px transparent"},boxShadow:{none:"0px 0px 0px 0px transparent"}};a.normalizeKeyframes=d}(c,f),function(a){var b={};a.isDeprecated=function(a,c,d,e){var f=e?"are":"is",g=new Date,h=new Date(c);return h.setMonth(h.getMonth()+3),h>g?(a in b||console.warn("Web Animations: "+a+" "+f+" deprecated and will stop working on "+h.toDateString()+". "+d),b[a]=!0,!1):!0},a.deprecated=function(b,c,d,e){var f=e?"are":"is";if(a.isDeprecated(b,c,d,e))throw new Error(b+" "+f+" no longer supported. "+d)}}(c),function(){if(document.documentElement.animate){var a=document.documentElement.animate([],0),b=!0;if(a&&(b=!1,"play|currentTime|pause|reverse|playbackRate|cancel|finish|startTime|playState".split("|").forEach(function(c){void 0===a[c]&&(b=!0)})),!b)return}!function(a,b){function c(a){for(var b={},c=0;c<a.length;c++)for(var d in a[c])if("offset"!=d&&"easing"!=d&&"composite"!=d){var e={offset:a[c].offset,easing:a[c].easing,value:a[c][d]};b[d]=b[d]||[],b[d].push(e)}for(var f in b){var g=b[f];if(0!=g[0].offset||1!=g[g.length-1].offset)throw{type:DOMException.NOT_SUPPORTED_ERR,name:"NotSupportedError",message:"Partial keyframes are not supported"}}return b}function d(a){var c=[];for(var d in a)for(var e=a[d],f=0;f<e.length-1;f++){var g=e[f].offset,h=e[f+1].offset,i=e[f].value,j=e[f+1].value;g==h&&(1==h?i=j:j=i),c.push({startTime:g,endTime:h,easing:e[f].easing,property:d,interpolation:b.propertyInterpolation(d,i,j)})}return c.sort(function(a,b){return a.startTime-b.startTime}),c}b.convertEffectInput=function(e){var f=a.normalizeKeyframes(e),g=c(f),h=d(g);return function(a,c){if(null!=c)h.filter(function(a){return 0>=c&&0==a.startTime||c>=1&&1==a.endTime||c>=a.startTime&&c<=a.endTime}).forEach(function(d){var e=c-d.startTime,f=d.endTime-d.startTime,g=0==f?0:d.easing(e/f);b.apply(a,d.property,d.interpolation(g))});else for(var d in g)"offset"!=d&&"easing"!=d&&"composite"!=d&&b.clear(a,d)}}}(c,d,f),function(a){function b(a,b,c){e[c]=e[c]||[],e[c].push([a,b])}function c(a,c,d){for(var e=0;e<d.length;e++){var f=d[e];b(a,c,f),/-/.test(f)&&b(a,c,f.replace(/-(.)/g,function(a,b){return b.toUpperCase()}))}}function d(b,c,d){if("initial"==c||"initial"==d){var g=b.replace(/-(.)/g,function(a,b){return b.toUpperCase()});"initial"==c&&(c=f[g]),"initial"==d&&(d=f[g])}for(var h=c==d?[]:e[b],i=0;h&&i<h.length;i++){var j=h[i][0](c),k=h[i][0](d);if(void 0!==j&&void 0!==k){var l=h[i][1](j,k);if(l){var m=a.Interpolation.apply(null,l);return function(a){return 0==a?c:1==a?d:m(a)}}}}return a.Interpolation(!1,!0,function(a){return a?d:c})}var e={};a.addPropertiesHandler=c;var f={backgroundColor:"transparent",backgroundPosition:"0% 0%",borderBottomColor:"currentColor",borderBottomLeftRadius:"0px",borderBottomRightRadius:"0px",borderBottomWidth:"3px",borderLeftColor:"currentColor",borderLeftWidth:"3px",borderRightColor:"currentColor",borderRightWidth:"3px",borderSpacing:"2px",borderTopColor:"currentColor",borderTopLeftRadius:"0px",borderTopRightRadius:"0px",borderTopWidth:"3px",bottom:"auto",clip:"rect(0px, 0px, 0px, 0px)",color:"black",fontSize:"100%",fontWeight:"400",height:"auto",left:"auto",letterSpacing:"normal",lineHeight:"120%",marginBottom:"0px",marginLeft:"0px",marginRight:"0px",marginTop:"0px",maxHeight:"none",maxWidth:"none",minHeight:"0px",minWidth:"0px",opacity:"1.0",outlineColor:"invert",outlineOffset:"0px",outlineWidth:"3px",paddingBottom:"0px",paddingLeft:"0px",paddingRight:"0px",paddingTop:"0px",right:"auto",textIndent:"0px",textShadow:"0px 0px 0px transparent",top:"auto",transform:"",verticalAlign:"0px",visibility:"visible",width:"auto",wordSpacing:"normal",zIndex:"auto"};a.propertyInterpolation=d}(d,f),function(a,b){function c(b){var c=a.calculateActiveDuration(b),d=function(d){return a.calculateTimeFraction(c,d,b)};return d._totalDuration=b.delay+c+b.endDelay,d._isCurrent=function(d){var e=a.calculatePhase(c,d,b);return e===PhaseActive||e===PhaseBefore},d}b.KeyframeEffect=function(d,e,f){var g,h=c(a.normalizeTimingInput(f)),i=b.convertEffectInput(e),j=function(){i(d,g)};return j._update=function(a){return g=h(a),null!==g},j._clear=function(){i(d,null)},j._hasSameTarget=function(a){return d===a},j._isCurrent=h._isCurrent,j._totalDuration=h._totalDuration,j},b.NullEffect=function(a){var b=function(){a&&(a(),a=null)};return b._update=function(){return null},b._totalDuration=0,b._isCurrent=function(){return!1},b._hasSameTarget=function(){return!1},b}}(c,d,f),function(a){a.apply=function(b,c,d){b.style[a.propertyName(c)]=d},a.clear=function(b,c){b.style[a.propertyName(c)]=""}}(d,f),function(a){window.Element.prototype.animate=function(b,c){return a.timeline._play(a.KeyframeEffect(this,b,c))}}(d),function(a){function b(a,c,d){if("number"==typeof a&&"number"==typeof c)return a*(1-d)+c*d;if("boolean"==typeof a&&"boolean"==typeof c)return.5>d?a:c;if(a.length==c.length){for(var e=[],f=0;f<a.length;f++)e.push(b(a[f],c[f],d));return e}throw"Mismatched interpolation arguments "+a+":"+c}a.Interpolation=function(a,c,d){return function(e){return d(b(a,c,e))}}}(d,f),function(a,b){a.sequenceNumber=0;var c=function(a,b,c){this.target=a,this.currentTime=b,this.timelineTime=c,this.type="finish",this.bubbles=!1,this.cancelable=!1,this.currentTarget=a,this.defaultPrevented=!1,this.eventPhase=Event.AT_TARGET,this.timeStamp=Date.now()};b.Animation=function(b){this._sequenceNumber=a.sequenceNumber++,this._currentTime=0,this._startTime=null,this._paused=!1,this._playbackRate=1,this._inTimeline=!0,this._finishedFlag=!1,this.onfinish=null,this._finishHandlers=[],this._effect=b,this._inEffect=this._effect._update(0),this._idle=!0,this._currentTimePending=!1},b.Animation.prototype={_ensureAlive:function(){this._inEffect=this._effect._update(this.playbackRate<0&&0===this.currentTime?-1:this.currentTime),this._inTimeline||!this._inEffect&&this._finishedFlag||(this._inTimeline=!0,b.timeline._animations.push(this))},_tickCurrentTime:function(a,b){a!=this._currentTime&&(this._currentTime=a,this._isFinished&&!b&&(this._currentTime=this._playbackRate>0?this._totalDuration:0),this._ensureAlive())},get currentTime(){return this._idle||this._currentTimePending?null:this._currentTime},set currentTime(a){a=+a,isNaN(a)||(b.restart(),this._paused||null==this._startTime||(this._startTime=this._timeline.currentTime-a/this._playbackRate),this._currentTimePending=!1,this._currentTime!=a&&(this._tickCurrentTime(a,!0),b.invalidateEffects()))},get startTime(){return this._startTime},set startTime(a){a=+a,isNaN(a)||this._paused||this._idle||(this._startTime=a,this._tickCurrentTime((this._timeline.currentTime-this._startTime)*this.playbackRate),b.invalidateEffects())},get playbackRate(){return this._playbackRate},set playbackRate(a){if(a!=this._playbackRate){var b=this.currentTime;this._playbackRate=a,this._startTime=null,"paused"!=this.playState&&"idle"!=this.playState&&this.play(),null!=b&&(this.currentTime=b)}},get _isFinished(){return!this._idle&&(this._playbackRate>0&&this._currentTime>=this._totalDuration||this._playbackRate<0&&this._currentTime<=0)},get _totalDuration(){return this._effect._totalDuration},get playState(){return this._idle?"idle":null==this._startTime&&!this._paused&&0!=this.playbackRate||this._currentTimePending?"pending":this._paused?"paused":this._isFinished?"finished":"running"},play:function(){this._paused=!1,(this._isFinished||this._idle)&&(this._currentTime=this._playbackRate>0?0:this._totalDuration,this._startTime=null,b.invalidateEffects()),this._finishedFlag=!1,b.restart(),this._idle=!1,this._ensureAlive()},pause:function(){this._isFinished||this._paused||this._idle||(this._currentTimePending=!0),this._startTime=null,this._paused=!0},finish:function(){this._idle||(this.currentTime=this._playbackRate>0?this._totalDuration:0,this._startTime=this._totalDuration-this.currentTime,this._currentTimePending=!1)},cancel:function(){this._inEffect&&(this._inEffect=!1,this._idle=!0,this.currentTime=0,this._startTime=null,this._effect._update(null),b.invalidateEffects(),b.restart())},reverse:function(){this.playbackRate*=-1,this.play()},addEventListener:function(a,b){"function"==typeof b&&"finish"==a&&this._finishHandlers.push(b)},removeEventListener:function(a,b){if("finish"==a){var c=this._finishHandlers.indexOf(b);c>=0&&this._finishHandlers.splice(c,1)}},_fireEvents:function(a){var b=this._isFinished;if((b||this._idle)&&!this._finishedFlag){var d=new c(this,this._currentTime,a),e=this._finishHandlers.concat(this.onfinish?[this.onfinish]:[]);setTimeout(function(){e.forEach(function(a){a.call(d.target,d)})},0)}this._finishedFlag=b},_tick:function(a){return this._idle||this._paused||(null==this._startTime?this.startTime=a-this._currentTime/this.playbackRate:this._isFinished||this._tickCurrentTime((a-this._startTime)*this.playbackRate)),this._currentTimePending=!1,this._fireEvents(a),!this._idle&&(this._inEffect||!this._finishedFlag)}}}(c,d,f),function(a,b){function c(a){var b=i;i=[],a<s.currentTime&&(a=s.currentTime),g(a),b.forEach(function(b){b[1](a)}),o&&g(a),f(),l=void 0}function d(a,b){return a._sequenceNumber-b._sequenceNumber}function e(){this._animations=[],this.currentTime=window.performance&&performance.now?performance.now():0}function f(){p.forEach(function(a){a()}),p.length=0}function g(a){n=!1;var c=b.timeline;c.currentTime=a,c._animations.sort(d),m=!1;var e=c._animations;c._animations=[];var f=[],g=[];e=e.filter(function(b){return b._inTimeline=b._tick(a),b._inEffect?g.push(b._effect):f.push(b._effect),b._isFinished||b._paused||b._idle||(m=!0),b._inTimeline}),p.push.apply(p,f),p.push.apply(p,g),c._animations.push.apply(c._animations,e),o=!1,m&&requestAnimationFrame(function(){})}var h=window.requestAnimationFrame,i=[],j=0;window.requestAnimationFrame=function(a){var b=j++;return 0==i.length&&h(c),i.push([b,a]),b},window.cancelAnimationFrame=function(a){i.forEach(function(b){b[0]==a&&(b[1]=function(){})})},e.prototype={_play:function(c){c._timing=a.normalizeTimingInput(c.timing);var d=new b.Animation(c);return d._idle=!1,d._timeline=this,this._animations.push(d),b.restart(),b.invalidateEffects(),d}};var k,l=void 0,k=function(){return void 0==l&&(l=performance.now()),l},m=!1,n=!1;b.restart=function(){return m||(m=!0,requestAnimationFrame(function(){}),n=!0),n};var o=!1;b.invalidateEffects=function(){o=!0};var p=[],q=1e3/60,r=window.getComputedStyle;Object.defineProperty(window,"getComputedStyle",{configurable:!0,enumerable:!0,value:function(){if(o){var a=k();a-s.currentTime>0&&(s.currentTime+=q*(Math.floor((a-s.currentTime)/q)+1)),g(s.currentTime)}return f(),r.apply(this,arguments)}});var s=new e;b.timeline=s}(c,d,f),function(a){function b(a,b){var c=a.exec(b);return c?(c=a.ignoreCase?c[0].toLowerCase():c[0],[c,b.substr(c.length)]):void 0}function c(a,b){b=b.replace(/^\s*/,"");var c=a(b);return c?[c[0],c[1].replace(/^\s*/,"")]:void 0}function d(a,d,e){a=c.bind(null,a);for(var f=[];;){var g=a(e);if(!g)return[f,e];if(f.push(g[0]),e=g[1],g=b(d,e),!g||""==g[1])return[f,e];e=g[1]}}function e(a,b){for(var c=0,d=0;d<b.length&&(!/\s|,/.test(b[d])||0!=c);d++)if("("==b[d])c++;else if(")"==b[d]&&(c--,0==c&&d++,0>=c))break;var e=a(b.substr(0,d));return void 0==e?void 0:[e,b.substr(d)]}function f(a,b){for(var c=a,d=b;c&&d;)c>d?c%=d:d%=c;return c=a*b/(c+d)}function g(a){return function(b){var c=a(b);return c&&(c[0]=void 0),c}}function h(a,b){return function(c){var d=a(c);return d?d:[b,c]}}function i(b,c){for(var d=[],e=0;e<b.length;e++){var f=a.consumeTrimmed(b[e],c);if(!f||""==f[0])return;void 0!==f[0]&&d.push(f[0]),c=f[1]}return""==c?d:void 0}function j(a,b,c,d,e){for(var g=[],h=[],i=[],j=f(d.length,e.length),k=0;j>k;k++){var l=b(d[k%d.length],e[k%e.length]);if(!l)return;g.push(l[0]),h.push(l[1]),i.push(l[2])}return[g,h,function(b){var d=b.map(function(a,b){return i[b](a)}).join(c);return a?a(d):d}]}function k(a,b,c){for(var d=[],e=[],f=[],g=0,h=0;h<c.length;h++)if("function"==typeof c[h]){var i=c[h](a[g],b[g++]);d.push(i[0]),e.push(i[1]),f.push(i[2])}else!function(a){d.push(!1),e.push(!1),f.push(function(){return c[a]})}(h);return[d,e,function(a){for(var b="",c=0;c<a.length;c++)b+=f[c](a[c]);return b}]}a.consumeToken=b,a.consumeTrimmed=c,a.consumeRepeated=d,a.consumeParenthesised=e,a.ignore=g,a.optional=h,a.consumeList=i,a.mergeNestedRepeated=j.bind(null,null),a.mergeWrappedNestedRepeated=j,a.mergeList=k}(d),function(a){function b(b){function c(b){var c=a.consumeToken(/^inset/i,b);if(c)return d.inset=!0,c;var c=a.consumeLengthOrPercent(b);if(c)return d.lengths.push(c[0]),c;var c=a.consumeColor(b);return c?(d.color=c[0],c):void 0}var d={inset:!1,lengths:[],color:null},e=a.consumeRepeated(c,/^/,b);return e&&e[0].length?[d,e[1]]:void 0}function c(c){var d=a.consumeRepeated(b,/^,/,c);return d&&""==d[1]?d[0]:void 0}function d(b,c){for(;b.lengths.length<Math.max(b.lengths.length,c.lengths.length);)b.lengths.push({px:0});for(;c.lengths.length<Math.max(b.lengths.length,c.lengths.length);)c.lengths.push({px:0});if(b.inset==c.inset&&!!b.color==!!c.color){for(var d,e=[],f=[[],0],g=[[],0],h=0;h<b.lengths.length;h++){var i=a.mergeDimensions(b.lengths[h],c.lengths[h],2==h);f[0].push(i[0]),g[0].push(i[1]),e.push(i[2])}if(b.color&&c.color){var j=a.mergeColors(b.color,c.color);f[1]=j[0],g[1]=j[1],d=j[2]}return[f,g,function(a){for(var c=b.inset?"inset ":" ",f=0;f<e.length;f++)c+=e[f](a[0][f])+" ";return d&&(c+=d(a[1])),c}]}}function e(b,c,d,e){function f(a){return{inset:a,color:[0,0,0,0],lengths:[{px:0},{px:0},{px:0},{px:0}]}}for(var g=[],h=[],i=0;i<d.length||i<e.length;i++){var j=d[i]||f(e[i].inset),k=e[i]||f(d[i].inset);g.push(j),h.push(k)}return a.mergeNestedRepeated(b,c,g,h)}var f=e.bind(null,d,", ");a.addPropertiesHandler(c,f,["box-shadow","text-shadow"])}(d),function(a){function b(a){return a.toFixed(3).replace(".000","")}function c(a,b,c){return Math.min(b,Math.max(a,c))}function d(a){return/^\s*[-+]?(\d*\.)?\d+\s*$/.test(a)?Number(a):void 0}function e(a,c){return[a,c,b]}function f(a,b){return 0!=a?h(0,1/0)(a,b):void 0}function g(a,b){return[a,b,function(a){return Math.round(c(1,1/0,a))}]}function h(a,d){return function(e,f){return[e,f,function(e){return b(c(a,d,e))}]}}function i(a,b){return[a,b,Math.round]}a.clamp=c,a.addPropertiesHandler(d,h(0,1/0),["border-image-width","line-height"]),a.addPropertiesHandler(d,h(0,1),["opacity","shape-image-threshold"]),a.addPropertiesHandler(d,f,["flex-grow","flex-shrink"]),a.addPropertiesHandler(d,g,["orphans","widows"]),a.addPropertiesHandler(d,i,["z-index"]),a.parseNumber=d,a.mergeNumbers=e,a.numberToString=b}(d,f),function(a){function b(a,b){return"visible"==a||"visible"==b?[0,1,function(c){return 0>=c?a:c>=1?b:"visible"}]:void 0}a.addPropertiesHandler(String,b,["visibility"])}(d),function(a){function b(a){a=a.trim(),e.fillStyle="#000",e.fillStyle=a;var b=e.fillStyle;if(e.fillStyle="#fff",e.fillStyle=a,b==e.fillStyle){e.fillRect(0,0,1,1);var c=e.getImageData(0,0,1,1).data;e.clearRect(0,0,1,1);var d=c[3]/255;return[c[0]*d,c[1]*d,c[2]*d,d]}}function c(b,c){return[b,c,function(b){function c(a){return Math.max(0,Math.min(255,a))}if(b[3])for(var d=0;3>d;d++)b[d]=Math.round(c(b[d]/b[3]));return b[3]=a.numberToString(a.clamp(0,1,b[3])),"rgba("+b.join(",")+")"}]}var d=document.createElementNS("http://www.w3.org/1999/xhtml","canvas");d.width=d.height=1;var e=d.getContext("2d");a.addPropertiesHandler(b,c,["background-color","border-bottom-color","border-left-color","border-right-color","border-top-color","color","outline-color","text-decoration-color"]),a.consumeColor=a.consumeParenthesised.bind(null,b),a.mergeColors=c}(d,f),function(a,b){function c(a,b){if(b=b.trim().toLowerCase(),"0"==b&&"px".search(a)>=0)return{px:0};if(/^[^(]*$|^calc/.test(b)){b=b.replace(/calc\(/g,"(");var c={};b=b.replace(a,function(a){return c[a]=null,"U"+a});for(var d="U("+a.source+")",e=b.replace(/[-+]?(\d*\.)?\d+/g,"N").replace(new RegExp("N"+d,"g"),"D").replace(/\s[+-]\s/g,"O").replace(/\s/g,""),f=[/N\*(D)/g,/(N|D)[*/]N/g,/(N|D)O\1/g,/\((N|D)\)/g],g=0;g<f.length;)f[g].test(e)?(e=e.replace(f[g],"$1"),g=0):g++;if("D"==e){for(var h in c){var i=eval(b.replace(new RegExp("U"+h,"g"),"").replace(new RegExp(d,"g"),"*0"));if(!isFinite(i))return;c[h]=i}return c}}}function d(a,b){return e(a,b,!0)}function e(b,c,d){var e,f=[];for(e in b)f.push(e);for(e in c)f.indexOf(e)<0&&f.push(e);return b=f.map(function(a){return b[a]||0}),c=f.map(function(a){return c[a]||0}),[b,c,function(b){var c=b.map(function(c,e){return 1==b.length&&d&&(c=Math.max(c,0)),a.numberToString(c)+f[e]}).join(" + ");return b.length>1?"calc("+c+")":c}]}var f="px|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc",g=c.bind(null,new RegExp(f,"g")),h=c.bind(null,new RegExp(f+"|%","g")),i=c.bind(null,/deg|rad|grad|turn/g);a.parseLength=g,a.parseLengthOrPercent=h,a.consumeLengthOrPercent=a.consumeParenthesised.bind(null,h),a.parseAngle=i,a.mergeDimensions=e;var j=a.consumeParenthesised.bind(null,g),k=a.consumeRepeated.bind(void 0,j,/^/),l=a.consumeRepeated.bind(void 0,k,/^,/);a.consumeSizePairList=l;var m=function(a){var b=l(a);return b&&""==b[1]?b[0]:void 0},n=a.mergeNestedRepeated.bind(void 0,d," "),o=a.mergeNestedRepeated.bind(void 0,n,",");a.mergeNonNegativeSizePair=n,a.addPropertiesHandler(m,o,["background-size"]),a.addPropertiesHandler(h,d,["border-bottom-width","border-image-width","border-left-width","border-right-width","border-top-width","flex-basis","font-size","height","line-height","max-height","max-width","outline-width","width"]),a.addPropertiesHandler(h,e,["border-bottom-left-radius","border-bottom-right-radius","border-top-left-radius","border-top-right-radius","bottom","left","letter-spacing","margin-bottom","margin-left","margin-right","margin-top","min-height","min-width","outline-offset","padding-bottom","padding-left","padding-right","padding-top","perspective","right","shape-margin","text-indent","top","vertical-align","word-spacing"])}(d,f),function(a){function b(b){return a.consumeLengthOrPercent(b)||a.consumeToken(/^auto/,b)}function c(c){var d=a.consumeList([a.ignore(a.consumeToken.bind(null,/^rect/)),a.ignore(a.consumeToken.bind(null,/^\(/)),a.consumeRepeated.bind(null,b,/^,/),a.ignore(a.consumeToken.bind(null,/^\)/))],c);return d&&4==d[0].length?d[0]:void 0}function d(b,c){return"auto"==b||"auto"==c?[!0,!1,function(d){var e=d?b:c;if("auto"==e)return"auto";var f=a.mergeDimensions(e,e);return f[2](f[0])}]:a.mergeDimensions(b,c)}function e(a){return"rect("+a+")"}var f=a.mergeWrappedNestedRepeated.bind(null,e,d,", ");a.parseBox=c,a.mergeBoxes=f,a.addPropertiesHandler(c,f,["clip"])}(d,f),function(a){function b(a){return function(b){var c=0;return a.map(function(a){return a===j?b[c++]:a})}}function c(a){return a}function d(b){if(b=b.toLowerCase().trim(),"none"==b)return[];for(var c,d=/\s*(\w+)\(([^)]*)\)/g,e=[],f=0;c=d.exec(b);){if(c.index!=f)return;f=c.index+c[0].length;var g=c[1],h=m[g];if(!h)return;var i=c[2].split(","),j=h[0];if(j.length<i.length)return;for(var n=[],o=0;o<j.length;o++){var p,q=i[o],r=j[o];if(p=q?{A:function(b){return"0"==b.trim()?l:a.parseAngle(b)},N:a.parseNumber,T:a.parseLengthOrPercent,L:a.parseLength}[r.toUpperCase()](q):{a:l,n:n[0],t:k}[r],void 0===p)return;n.push(p)}if(e.push({t:g,d:n}),d.lastIndex==b.length)return e}}function e(a){return a.toFixed(6).replace(".000000","")}function f(b,c){if(b.decompositionPair!==c){b.decompositionPair=c;var d=a.makeMatrixDecomposition(b)}if(c.decompositionPair!==b){c.decompositionPair=b;var f=a.makeMatrixDecomposition(c)}return null==d[0]||null==f[0]?[[!1],[!0],function(a){return a?c[0].d:b[0].d}]:(d[0].push(0),f[0].push(1),[d,f,function(b){var c=a.quat(d[0][3],f[0][3],b[5]),g=a.composeMatrix(b[0],b[1],b[2],c,b[4]),h=g.map(e).join(",");return h}])}function g(a){return a.replace(/[xy]/,"")}function h(a){return a.replace(/(x|y|z|3d)?$/,"3d")}function i(b,c){var d=a.makeMatrixDecomposition&&!0,e=!1;if(!b.length||!c.length){b.length||(e=!0,b=c,c=[]);for(var i=0;i<b.length;i++){var j=b[i].t,k=b[i].d,l="scale"==j.substr(0,5)?1:0;c.push({t:j,d:k.map(function(a){if("number"==typeof a)return l;var b={};for(var c in a)b[c]=l;return b})})}}var n=function(a,b){return"perspective"==a&&"perspective"==b||("matrix"==a||"matrix3d"==a)&&("matrix"==b||"matrix3d"==b)},o=[],p=[],q=[];if(b.length!=c.length){if(!d)return;var r=f(b,c);o=[r[0]],p=[r[1]],q=[["matrix",[r[2]]]]}else for(var i=0;i<b.length;i++){var j,s=b[i].t,t=c[i].t,u=b[i].d,v=c[i].d,w=m[s],x=m[t];if(n(s,t)){if(!d)return;var r=f([b[i]],[c[i]]);o.push(r[0]),p.push(r[1]),q.push(["matrix",[r[2]]])}else{if(s==t)j=s;else if(w[2]&&x[2]&&g(s)==g(t))j=g(s),u=w[2](u),v=x[2](v);else{if(!w[1]||!x[1]||h(s)!=h(t)){if(!d)return;var r=f(b,c);o=[r[0]],p=[r[1]],q=[["matrix",[r[2]]]];break}j=h(s),u=w[1](u),v=x[1](v)}for(var y=[],z=[],A=[],B=0;B<u.length;B++){var C="number"==typeof u[B]?a.mergeNumbers:a.mergeDimensions,r=C(u[B],v[B]);y[B]=r[0],z[B]=r[1],A.push(r[2])}o.push(y),p.push(z),q.push([j,A])}}if(e){var D=o;o=p,p=D}return[o,p,function(a){return a.map(function(a,b){var c=a.map(function(a,c){return q[b][1][c](a)}).join(",");return"matrix"==q[b][0]&&16==c.split(",").length&&(q[b][0]="matrix3d"),q[b][0]+"("+c+")"}).join(" ")}]}var j=null,k={px:0},l={deg:0},m={matrix:["NNNNNN",[j,j,0,0,j,j,0,0,0,0,1,0,j,j,0,1],c],matrix3d:["NNNNNNNNNNNNNNNN",c],rotate:["A"],rotatex:["A"],rotatey:["A"],rotatez:["A"],rotate3d:["NNNA"],perspective:["L"],scale:["Nn",b([j,j,1]),c],scalex:["N",b([j,1,1]),b([j,1])],scaley:["N",b([1,j,1]),b([1,j])],scalez:["N",b([1,1,j])],scale3d:["NNN",c],skew:["Aa",null,c],skewx:["A",null,b([j,l])],skewy:["A",null,b([l,j])],translate:["Tt",b([j,j,k]),c],translatex:["T",b([j,k,k]),b([j,k])],translatey:["T",b([k,j,k]),b([k,j])],translatez:["L",b([k,k,j])],translate3d:["TTL",c]};a.addPropertiesHandler(d,i,["transform"])}(d,f),function(a){function b(a,b){b.concat([a]).forEach(function(b){b in document.documentElement.style&&(c[a]=b)})}var c={};b("transform",["webkitTransform","msTransform"]),b("transformOrigin",["webkitTransformOrigin"]),b("perspective",["webkitPerspective"]),b("perspectiveOrigin",["webkitPerspectiveOrigin"]),a.propertyName=function(a){return c[a]||a}}(d,f)}(),!function(a,b){function c(a){var b=window.document.timeline;b.currentTime=a,b._discardAnimations(),0==b._animations.length?e=!1:requestAnimationFrame(c)}var d=window.requestAnimationFrame;window.requestAnimationFrame=function(a){return d(function(b){window.document.timeline._updateAnimationsPromises(),a(b),window.document.timeline._updateAnimationsPromises()})},b.AnimationTimeline=function(){this._animations=[],this.currentTime=void 0},b.AnimationTimeline.prototype={getAnimations:function(){return this._discardAnimations(),this._animations.slice()},_updateAnimationsPromises:function(){b.animationsWithPromises=b.animationsWithPromises.filter(function(a){return a._updatePromises()})},_discardAnimations:function(){this._updateAnimationsPromises(),this._animations=this._animations.filter(function(a){return"finished"!=a.playState&&"idle"!=a.playState})},_play:function(a){var c=new b.Animation(a,this);return this._animations.push(c),b.restartWebAnimationsNextTick(),c._updatePromises(),c._animation.play(),c._updatePromises(),c},play:function(a){return a&&a.remove(),this._play(a)}};var e=!1;b.restartWebAnimationsNextTick=function(){e||(e=!0,requestAnimationFrame(c))};var f=new b.AnimationTimeline;b.timeline=f;try{Object.defineProperty(window.document,"timeline",{configurable:!0,get:function(){return f}})}catch(g){}try{window.document.timeline=f}catch(g){}}(c,e,f),function(a,b){b.animationsWithPromises=[],b.Animation=function(b,c){if(this.effect=b,b&&(b._animation=this),!c)throw new Error("Animation with null timeline is not supported");this._timeline=c,this._sequenceNumber=a.sequenceNumber++,this._holdTime=0,this._paused=!1,this._isGroup=!1,this._animation=null,this._childAnimations=[],this._callback=null,this._oldPlayState="idle",this._rebuildUnderlyingAnimation(),this._animation.cancel(),this._updatePromises()},b.Animation.prototype={_updatePromises:function(){var a=this._oldPlayState,b=this.playState;return this._readyPromise&&b!==a&&("idle"==b?(this._rejectReadyPromise(),this._readyPromise=void 0):"pending"==a?this._resolveReadyPromise():"pending"==b&&(this._readyPromise=void 0)),this._finishedPromise&&b!==a&&("idle"==b?(this._rejectFinishedPromise(),this._finishedPromise=void 0):"finished"==b?this._resolveFinishedPromise():"finished"==a&&(this._finishedPromise=void 0)),this._oldPlayState=this.playState,this._readyPromise||this._finishedPromise},_rebuildUnderlyingAnimation:function(){this._updatePromises();var a,c,d,e,f=this._animation?!0:!1;f&&(a=this.playbackRate,c=this._paused,d=this.startTime,e=this.currentTime,this._animation.cancel(),this._animation._wrapper=null,this._animation=null),(!this.effect||this.effect instanceof window.KeyframeEffect)&&(this._animation=b.newUnderlyingAnimationForKeyframeEffect(this.effect),b.bindAnimationForKeyframeEffect(this)),(this.effect instanceof window.SequenceEffect||this.effect instanceof window.GroupEffect)&&(this._animation=b.newUnderlyingAnimationForGroup(this.effect),b.bindAnimationForGroup(this)),this.effect&&this.effect._onsample&&b.bindAnimationForCustomEffect(this),f&&(1!=a&&(this.playbackRate=a),null!==d?this.startTime=d:null!==e?this.currentTime=e:null!==this._holdTime&&(this.currentTime=this._holdTime),c&&this.pause()),this._updatePromises() +},_updateChildren:function(){if(this.effect&&"idle"!=this.playState){var a=this.effect._timing.delay;this._childAnimations.forEach(function(c){this._arrangeChildren(c,a),this.effect instanceof window.SequenceEffect&&(a+=b.groupChildDuration(c.effect))}.bind(this))}},_setExternalAnimation:function(a){if(this.effect&&this._isGroup)for(var b=0;b<this.effect.children.length;b++)this.effect.children[b]._animation=a,this._childAnimations[b]._setExternalAnimation(a)},_constructChildAnimations:function(){if(this.effect&&this._isGroup){var a=this.effect._timing.delay;this._removeChildAnimations(),this.effect.children.forEach(function(c){var d=window.document.timeline._play(c);this._childAnimations.push(d),d.playbackRate=this.playbackRate,this._paused&&d.pause(),c._animation=this.effect._animation,this._arrangeChildren(d,a),this.effect instanceof window.SequenceEffect&&(a+=b.groupChildDuration(c))}.bind(this))}},_arrangeChildren:function(a,b){null===this.startTime?a.currentTime=this.currentTime-b/this.playbackRate:a.startTime!==this.startTime+b/this.playbackRate&&(a.startTime=this.startTime+b/this.playbackRate)},get timeline(){return this._timeline},get playState(){return this._animation?this._animation.playState:"idle"},get finished(){return window.Promise?(this._finishedPromise||(-1==b.animationsWithPromises.indexOf(this)&&b.animationsWithPromises.push(this),this._finishedPromise=new Promise(function(a,b){this._resolveFinishedPromise=function(){a(this)},this._rejectFinishedPromise=function(){b({type:DOMException.ABORT_ERR,name:"AbortError"})}}.bind(this)),"finished"==this.playState&&this._resolveFinishedPromise()),this._finishedPromise):(console.warn("Animation Promises require JavaScript Promise constructor"),null)},get ready(){return window.Promise?(this._readyPromise||(-1==b.animationsWithPromises.indexOf(this)&&b.animationsWithPromises.push(this),this._readyPromise=new Promise(function(a,b){this._resolveReadyPromise=function(){a(this)},this._rejectReadyPromise=function(){b({type:DOMException.ABORT_ERR,name:"AbortError"})}}.bind(this)),"pending"!==this.playState&&this._resolveReadyPromise()),this._readyPromise):(console.warn("Animation Promises require JavaScript Promise constructor"),null)},get onfinish(){return this._onfinish},set onfinish(a){"function"==typeof a?(this._onfinish=a,this._animation.onfinish=function(b){b.target=this,a.call(this,b)}.bind(this)):(this._animation.onfinish=a,this.onfinish=this._animation.onfinish)},get currentTime(){this._updatePromises();var a=this._animation.currentTime;return this._updatePromises(),a},set currentTime(a){this._updatePromises(),this._animation.currentTime=isFinite(a)?a:Math.sign(a)*Number.MAX_VALUE,this._register(),this._forEachChild(function(b,c){b.currentTime=a-c}),this._updatePromises()},get startTime(){return this._animation.startTime},set startTime(a){this._updatePromises(),this._animation.startTime=isFinite(a)?a:Math.sign(a)*Number.MAX_VALUE,this._register(),this._forEachChild(function(b,c){b.startTime=a+c}),this._updatePromises()},get playbackRate(){return this._animation.playbackRate},set playbackRate(a){this._updatePromises();var b=this.currentTime;this._animation.playbackRate=a,this._forEachChild(function(b){b.playbackRate=a}),"paused"!=this.playState&&"idle"!=this.playState&&this.play(),null!==b&&(this.currentTime=b),this._updatePromises()},play:function(){this._updatePromises(),this._paused=!1,this._animation.play(),-1==this._timeline._animations.indexOf(this)&&this._timeline._animations.push(this),this._register(),b.awaitStartTime(this),this._forEachChild(function(a){var b=a.currentTime;a.play(),a.currentTime=b}),this._updatePromises()},pause:function(){this._updatePromises(),this.currentTime&&(this._holdTime=this.currentTime),this._animation.pause(),this._register(),this._forEachChild(function(a){a.pause()}),this._paused=!0,this._updatePromises()},finish:function(){this._updatePromises(),this._animation.finish(),this._register(),this._updatePromises()},cancel:function(){this._updatePromises(),this._animation.cancel(),this._register(),this._removeChildAnimations(),this._updatePromises()},reverse:function(){this._updatePromises();var a=this.currentTime;this._animation.reverse(),this._forEachChild(function(a){a.reverse()}),null!==a&&(this.currentTime=a),this._updatePromises()},addEventListener:function(a,b){var c=b;"function"==typeof b&&(c=function(a){a.target=this,b.call(this,a)}.bind(this),b._wrapper=c),this._animation.addEventListener(a,c)},removeEventListener:function(a,b){this._animation.removeEventListener(a,b&&b._wrapper||b)},_removeChildAnimations:function(){for(;this._childAnimations.length;)this._childAnimations.pop().cancel()},_forEachChild:function(b){var c=0;if(this.effect.children&&this._childAnimations.length<this.effect.children.length&&this._constructChildAnimations(),this._childAnimations.forEach(function(a){b.call(this,a,c),this.effect instanceof window.SequenceEffect&&(c+=a.effect.activeDuration)}.bind(this)),"pending"!=this.playState){var d=this.effect._timing,e=this.currentTime;null!==e&&(e=a.calculateTimeFraction(a.calculateActiveDuration(d),e,d)),(null==e||isNaN(e))&&this._removeChildAnimations()}}},window.Animation=b.Animation}(c,e,f),function(a,b){function c(b){this._frames=a.normalizeKeyframes(b)}function d(){for(var a=!1;h.length;){var b=h.shift();b._updateChildren(),a=!0}return a}var e=function(a){if(a._animation=void 0,a instanceof window.SequenceEffect||a instanceof window.GroupEffect)for(var b=0;b<a.children.length;b++)e(a.children[b])};b.removeMulti=function(a){for(var b=[],c=0;c<a.length;c++){var d=a[c];d._parent?(-1==b.indexOf(d._parent)&&b.push(d._parent),d._parent.children.splice(d._parent.children.indexOf(d),1),d._parent=null,e(d)):d._animation&&d._animation.effect==d&&(d._animation.cancel(),d._animation.effect=new KeyframeEffect(null,[]),d._animation._callback&&(d._animation._callback._animation=null),d._animation._rebuildUnderlyingAnimation(),e(d))}for(c=0;c<b.length;c++)b[c]._rebuild()},b.KeyframeEffect=function(b,d,e){return this.target=b,this._parent=null,e=a.numericTimingToObject(e),this._timingInput=a.cloneTimingInput(e),this._timing=a.normalizeTimingInput(e),this.timing=a.makeTiming(e,!1,this),this.timing._effect=this,"function"==typeof d?(a.deprecated("Custom KeyframeEffect","2015-06-22","Use KeyframeEffect.onsample instead."),this._normalizedKeyframes=d):this._normalizedKeyframes=new c(d),this._keyframes=d,this.activeDuration=a.calculateActiveDuration(this._timing),this},b.KeyframeEffect.prototype={getFrames:function(){return"function"==typeof this._normalizedKeyframes?this._normalizedKeyframes:this._normalizedKeyframes._frames},set onsample(a){if("function"==typeof this.getFrames())throw new Error("Setting onsample on custom effect KeyframeEffect is not supported.");this._onsample=a,this._animation&&this._animation._rebuildUnderlyingAnimation()},get parent(){return this._parent},clone:function(){if("function"==typeof this.getFrames())throw new Error("Cloning custom effects is not supported.");var b=new KeyframeEffect(this.target,[],a.cloneTimingInput(this._timingInput));return b._normalizedKeyframes=this._normalizedKeyframes,b._keyframes=this._keyframes,b},remove:function(){b.removeMulti([this])}};var f=Element.prototype.animate;Element.prototype.animate=function(a,c){return b.timeline._play(new b.KeyframeEffect(this,a,c))};var g=document.createElementNS("http://www.w3.org/1999/xhtml","div");b.newUnderlyingAnimationForKeyframeEffect=function(a){if(a){var b=a.target||g,c=a._keyframes;"function"==typeof c&&(c=[]);var d=a._timingInput}else var b=g,c=[],d=0;return f.apply(b,[c,d])},b.bindAnimationForKeyframeEffect=function(a){a.effect&&"function"==typeof a.effect._normalizedKeyframes&&b.bindAnimationForCustomEffect(a)};var h=[];b.awaitStartTime=function(a){null===a.startTime&&a._isGroup&&(0==h.length&&requestAnimationFrame(d),h.push(a))};var i=window.getComputedStyle;Object.defineProperty(window,"getComputedStyle",{configurable:!0,enumerable:!0,value:function(){window.document.timeline._updateAnimationsPromises();var a=i.apply(this,arguments);return d()&&(a=i.apply(this,arguments)),window.document.timeline._updateAnimationsPromises(),a}}),window.KeyframeEffect=b.KeyframeEffect,window.Element.prototype.getAnimations=function(){return document.timeline.getAnimations().filter(function(a){return null!==a.effect&&a.effect.target==this}.bind(this))}}(c,e,f),function(a,b){function c(a){a._registered||(a._registered=!0,f.push(a),g||(g=!0,requestAnimationFrame(d)))}function d(){var a=f;f=[],a.sort(function(a,b){return a._sequenceNumber-b._sequenceNumber}),a=a.filter(function(a){a();var b=a._animation?a._animation.playState:"idle";return"running"!=b&&"pending"!=b&&(a._registered=!1),a._registered}),f.push.apply(f,a),f.length?(g=!0,requestAnimationFrame(d)):g=!1}var e=(document.createElementNS("http://www.w3.org/1999/xhtml","div"),0);b.bindAnimationForCustomEffect=function(b){var d,f=b.effect.target,g="function"==typeof b.effect.getFrames();d=g?b.effect.getFrames():b.effect._onsample;var h=b.effect.timing,i=null;h=a.normalizeTimingInput(h);var j=function(){var c=j._animation?j._animation.currentTime:null;null!==c&&(c=a.calculateTimeFraction(a.calculateActiveDuration(h),c,h),isNaN(c)&&(c=null)),c!==i&&(g?d(c,f,b.effect):d(c,b.effect,b.effect._animation)),i=c};j._animation=b,j._registered=!1,j._sequenceNumber=e++,b._callback=j,c(j)};var f=[],g=!1;b.Animation.prototype._register=function(){this._callback&&c(this._callback)}}(c,e,f),function(a,b){function c(a){return a._timing.delay+a.activeDuration+a._timing.endDelay}function d(b,c){this._parent=null,this.children=b||[],this._reparent(this.children),c=a.numericTimingToObject(c),this._timingInput=a.cloneTimingInput(c),this._timing=a.normalizeTimingInput(c,!0),this.timing=a.makeTiming(c,!0,this),this.timing._effect=this,"auto"===this._timing.duration&&(this._timing.duration=this.activeDuration)}window.SequenceEffect=function(){d.apply(this,arguments)},window.GroupEffect=function(){d.apply(this,arguments)},d.prototype={_isAncestor:function(a){for(var b=this;null!==b;){if(b==a)return!0;b=b._parent}return!1},_rebuild:function(){for(var a=this;a;)"auto"===a.timing.duration&&(a._timing.duration=a.activeDuration),a=a._parent;this._animation&&this._animation._rebuildUnderlyingAnimation()},_reparent:function(a){b.removeMulti(a);for(var c=0;c<a.length;c++)a[c]._parent=this},_putChild:function(a,b){for(var c=b?"Cannot append an ancestor or self":"Cannot prepend an ancestor or self",d=0;d<a.length;d++)if(this._isAncestor(a[d]))throw{type:DOMException.HIERARCHY_REQUEST_ERR,name:"HierarchyRequestError",message:c};for(var d=0;d<a.length;d++)b?this.children.push(a[d]):this.children.unshift(a[d]);this._reparent(a),this._rebuild()},append:function(){this._putChild(arguments,!0)},prepend:function(){this._putChild(arguments,!1)},get parent(){return this._parent},get firstChild(){return this.children.length?this.children[0]:null},get lastChild(){return this.children.length?this.children[this.children.length-1]:null},clone:function(){for(var b=a.cloneTimingInput(this._timingInput),c=[],d=0;d<this.children.length;d++)c.push(this.children[d].clone());return this instanceof GroupEffect?new GroupEffect(c,b):new SequenceEffect(c,b)},remove:function(){b.removeMulti([this])}},window.SequenceEffect.prototype=Object.create(d.prototype),Object.defineProperty(window.SequenceEffect.prototype,"activeDuration",{get:function(){var a=0;return this.children.forEach(function(b){a+=c(b)}),Math.max(a,0)}}),window.GroupEffect.prototype=Object.create(d.prototype),Object.defineProperty(window.GroupEffect.prototype,"activeDuration",{get:function(){var a=0;return this.children.forEach(function(b){a=Math.max(a,c(b))}),a}}),b.newUnderlyingAnimationForGroup=function(c){var d,e=null,f=function(b){var c=d._wrapper;return c&&"pending"!=c.playState&&c.effect?null==b?void c._removeChildAnimations():0==b&&c.playbackRate<0&&(e||(e=a.normalizeTimingInput(c.effect.timing)),b=a.calculateTimeFraction(a.calculateActiveDuration(e),-1,e),isNaN(b)||null==b)?(c._forEachChild(function(a){a.currentTime=-1}),void c._removeChildAnimations()):void 0:void 0},g=new KeyframeEffect(null,[],c._timing);return g.onsample=f,d=b.timeline._play(g)},b.bindAnimationForGroup=function(a){a._animation._wrapper=a,a._isGroup=!0,b.awaitStartTime(a),a._constructChildAnimations(),a._setExternalAnimation(a)},b.groupChildDuration=c}(c,e,f)}({},function(){return this}()); +//# sourceMappingURL=web-animations-next-lite.min.js.map</script><script> + + Polymer({ + + is: 'opaque-animation', + + behaviors: [ + Polymer.NeonAnimationBehavior + ], + + configure: function(config) { + var node = config.node; + node.style.opacity = '0'; + this._effect = new KeyframeEffect(node, [ + {'opacity': '1'}, + {'opacity': '1'} + ], this.timingFromConfig(config)); + return this._effect; + }, + + complete: function(config) { + config.node.style.opacity = ''; + } + + }); + +</script><script> + + /** + * `Polymer.NeonAnimatableBehavior` is implemented by elements containing animations for use with + * elements implementing `Polymer.NeonAnimationRunnerBehavior`. + * @polymerBehavior + */ + Polymer.NeonAnimatableBehavior = { + + properties: { + + /** + * Animation configuration. See README for more info. + */ + animationConfig: { + type: Object + }, + + /** + * Convenience property for setting an 'entry' animation. Do not set `animationConfig.entry` + * manually if using this. The animated node is set to `this` if using this property. + */ + entryAnimation: { + observer: '_entryAnimationChanged', + type: String + }, + + /** + * Convenience property for setting an 'exit' animation. Do not set `animationConfig.exit` + * manually if using this. The animated node is set to `this` if using this property. + */ + exitAnimation: { + observer: '_exitAnimationChanged', + type: String + } + + }, + + _entryAnimationChanged: function() { + this.animationConfig = this.animationConfig || {}; + if (this.entryAnimation !== 'fade-in-animation') { + // insert polyfill hack + this.animationConfig['entry'] = [{ + name: 'opaque-animation', + node: this + }, { + name: this.entryAnimation, + node: this + }]; + } else { + this.animationConfig['entry'] = [{ + name: this.entryAnimation, + node: this + }]; + } + }, + + _exitAnimationChanged: function() { + this.animationConfig = this.animationConfig || {}; + this.animationConfig['exit'] = [{ + name: this.exitAnimation, + node: this + }]; + }, + + _copyProperties: function(config1, config2) { + // shallowly copy properties from config2 to config1 + for (var property in config2) { + config1[property] = config2[property]; + } + }, + + _cloneConfig: function(config) { + var clone = { + isClone: true + }; + this._copyProperties(clone, config); + return clone; + }, + + _getAnimationConfigRecursive: function(type, map, allConfigs) { + if (!this.animationConfig) { + return; + } + + // type is optional + var thisConfig; + if (type) { + thisConfig = this.animationConfig[type]; + } else { + thisConfig = this.animationConfig; + } + + if (!Array.isArray(thisConfig)) { + thisConfig = [thisConfig]; + } + + // iterate animations and recurse to process configurations from child nodes + if (thisConfig) { + for (var config, index = 0; config = thisConfig[index]; index++) { + if (config.animatable) { + config.animatable._getAnimationConfigRecursive(config.type || type, map, allConfigs); + } else { + if (config.id) { + var cachedConfig = map[config.id]; + if (cachedConfig) { + // merge configurations with the same id, making a clone lazily + if (!cachedConfig.isClone) { + map[config.id] = this._cloneConfig(cachedConfig) + cachedConfig = map[config.id]; + } + this._copyProperties(cachedConfig, config); + } else { + // put any configs with an id into a map + map[config.id] = config; + } + } else { + allConfigs.push(config); + } + } + } + } + }, + + /** + * An element implementing `Polymer.NeonAnimationRunnerBehavior` calls this method to configure + * an animation with an optional type. Elements implementing `Polymer.NeonAnimatableBehavior` + * should define the property `animationConfig`, which is either a configuration object + * or a map of animation type to array of configuration objects. + */ + getAnimationConfig: function(type) { + var map = []; + var allConfigs = []; + this._getAnimationConfigRecursive(type, map, allConfigs); + // append the configurations saved in the map to the array + for (var key in map) { + allConfigs.push(map[key]); + } + return allConfigs; + } + + }; + +</script><script> + + /** + * `Polymer.NeonAnimationRunnerBehavior` adds a method to run animations. + * + * @polymerBehavior Polymer.NeonAnimationRunnerBehavior + */ + Polymer.NeonAnimationRunnerBehaviorImpl = { + + properties: { + + _animationMeta: { + type: Object, + value: function() { + return new Polymer.IronMeta({type: 'animation'}); + } + }, + + /** @type {?Object} */ + _player: { + type: Object + } + + }, + + _configureAnimationEffects: function(allConfigs) { + var allAnimations = []; + if (allConfigs.length > 0) { + for (var config, index = 0; config = allConfigs[index]; index++) { + var animationConstructor = this._animationMeta.byKey(config.name); + if (animationConstructor) { + var animation = animationConstructor && new animationConstructor(); + var effect = animation.configure(config); + if (effect) { + allAnimations.push({ + animation: animation, + config: config, + effect: effect + }); + } + } else { + console.warn(this.is + ':', config.name, 'not found!'); + } + } + } + return allAnimations; + }, + + _runAnimationEffects: function(allEffects) { + return document.timeline.play(new GroupEffect(allEffects)); + }, + + _completeAnimations: function(allAnimations) { + for (var animation, index = 0; animation = allAnimations[index]; index++) { + animation.animation.complete(animation.config); + } + }, + + /** + * Plays an animation with an optional `type`. + * @param {string=} type + * @param {!Object=} cookie + */ + playAnimation: function(type, cookie) { + var allConfigs = this.getAnimationConfig(type); + if (!allConfigs) { + return; + } + var allAnimations = this._configureAnimationEffects(allConfigs); + var allEffects = allAnimations.map(function(animation) { + return animation.effect; + }); + + if (allEffects.length > 0) { + this._player = this._runAnimationEffects(allEffects); + this._player.onfinish = function() { + this._completeAnimations(allAnimations); + + if (this._player) { + this._player.cancel(); + this._player = null; + } + + this.fire('neon-animation-finish', cookie, {bubbles: false}); + }.bind(this); + + } else { + this.fire('neon-animation-finish', cookie, {bubbles: false}); + } + }, + + /** + * Cancels the currently running animation. + */ + cancelAnimation: function() { + if (this._player) { + this._player.cancel(); + } + } + }; + + /** @polymerBehavior Polymer.NeonAnimationRunnerBehavior */ + Polymer.NeonAnimationRunnerBehavior = [ + Polymer.NeonAnimatableBehavior, + Polymer.NeonAnimationRunnerBehaviorImpl + ]; +</script><link rel=stylesheet href="https://fonts.googleapis.com/css?family=Roboto:400,300,500,700"><style is=custom-style> +:root { + --dark-primary-color: #303F9F; + --default-primary-color: #3F51B5; + --light-primary-color: #C5CAE9; + --text-primary-color: #ffffff; + /*text/icons*/ + --accent-color: #FF4081; + --primary-background-color: #c5cae9; + --primary-text-color: #212121; + --secondary-text-color: #727272; + --disabled-text-color: #bdbdbd; + --divider-color: #B6B6B6; + /* Components */ + /* paper-drawer-panel */ + --drawer-menu-color: #ffffff; + --drawer-border-color: 1px solid #ccc; + --drawer-toolbar-border-color: 1px solid rgba(0, 0, 0, 0.22); + /* paper-menu */ + --paper-menu-background-color: #fff; + --menu-link-color: #111111; +} + +paper-progress { + width: 100%; + z-index: 10000; + position: absolute; + top: 0; +} +neon-animated-pages{ + height: 100vh; +} +</style><script> + + /** + * Use `Polymer.NeonSharedElementAnimatableBehavior` to implement elements containing shared element + * animations. + * @polymerBehavior Polymer.NeonSharedElementAnimatableBehavior + */ + Polymer.NeonSharedElementAnimatableBehaviorImpl = { + + properties: { + + /** + * A map of shared element id to node. + */ + sharedElements: { + type: Object, + value: {} + } + + } + + }; + + /** @polymerBehavior Polymer.NeonSharedElementAnimatableBehavior */ + Polymer.NeonSharedElementAnimatableBehavior = [ + Polymer.NeonAnimatableBehavior, + Polymer.NeonSharedElementAnimatableBehaviorImpl + ]; + +</script><script> + + Polymer({ + + is: 'cascaded-animation', + + behaviors: [ + Polymer.NeonAnimationBehavior + ], + + properties: { + + /** @type {!Polymer.IronMeta} */ + _animationMeta: { + type: Object, + value: function() { + return new Polymer.IronMeta({type: 'animation'}); + } + } + + }, + + /** + * @param {{ + * animation: string, + * nodes: !Array<!Element>, + * nodeDelay: (number|undefined), + * timing: (Object|undefined) + * }} config + */ + configure: function(config) { + var animationConstructor = /** @type {Function} */ ( + this._animationMeta.byKey(config.animation)); + if (!animationConstructor) { + console.warn(this.is + ':', 'constructor for', config.animation, 'not found!'); + return; + } + + this._animations = []; + var nodes = config.nodes; + var effects = []; + var nodeDelay = config.nodeDelay || 50; + + config.timing = config.timing || {}; + config.timing.delay = config.timing.delay || 0; + + var oldDelay = config.timing.delay; + for (var node, index = 0; node = nodes[index]; index++) { + config.timing.delay += nodeDelay; + config.node = node; + + var animation = new animationConstructor(); + var effect = animation.configure(config); + + this._animations.push(animation); + effects.push(effect); + } + config.timing.delay = oldDelay; + + this._effect = new GroupEffect(effects); + return this._effect; + }, + + complete: function() { + for (var animation, index = 0; animation = this._animations[index]; index++) { + animation.complete(animation.config); + } + } + + }); + +</script><script> + + Polymer({ + + is: 'fade-in-animation', + + behaviors: [ + Polymer.NeonAnimationBehavior + ], + + configure: function(config) { + var node = config.node; + this._effect = new KeyframeEffect(node, [ + {'opacity': '0'}, + {'opacity': '1'} + ], this.timingFromConfig(config)); + return this._effect; + } + + }); + +</script><script> + + Polymer({ + + is: 'fade-out-animation', + + behaviors: [ + Polymer.NeonAnimationBehavior + ], + + configure: function(config) { + var node = config.node; + this._effect = new KeyframeEffect(node, [ + {'opacity': '1'}, + {'opacity': '0'} + ], this.timingFromConfig(config)); + return this._effect; + } + + }); + +</script><script> + + /** + * Use `Polymer.NeonSharedElementAnimationBehavior` to implement shared element animations. + * @polymerBehavior Polymer.NeonSharedElementAnimationBehavior + */ + Polymer.NeonSharedElementAnimationBehaviorImpl = { + + properties: { + + /** + * Cached copy of shared elements. + */ + sharedElements: { + type: Object + } + + }, + + /** + * Finds shared elements based on `config`. + */ + findSharedElements: function(config) { + var fromPage = config.fromPage; + var toPage = config.toPage; + if (!fromPage || !toPage) { + console.warn(this.is + ':', !fromPage ? 'fromPage' : 'toPage', 'is undefined!'); + return null; + }; + + if (!fromPage.sharedElements || !toPage.sharedElements) { + console.warn(this.is + ':', 'sharedElements are undefined for', !fromPage.sharedElements ? fromPage : toPage); + return null; + }; + + var from = fromPage.sharedElements[config.id] + var to = toPage.sharedElements[config.id]; + + if (!from || !to) { + console.warn(this.is + ':', 'sharedElement with id', config.id, 'not found in', !from ? fromPage : toPage); + return null; + } + + this.sharedElements = { + from: from, + to: to + }; + return this.sharedElements; + } + + }; + + /** @polymerBehavior Polymer.NeonSharedElementAnimationBehavior */ + Polymer.NeonSharedElementAnimationBehavior = [ + Polymer.NeonAnimationBehavior, + Polymer.NeonSharedElementAnimationBehaviorImpl + ]; + +</script><script> + + Polymer({ + + is: 'hero-animation', + + behaviors: [ + Polymer.NeonSharedElementAnimationBehavior + ], + + configure: function(config) { + var shared = this.findSharedElements(config); + if (!shared) { + return; + } + + var fromRect = shared.from.getBoundingClientRect(); + var toRect = shared.to.getBoundingClientRect(); + + var deltaLeft = fromRect.left - toRect.left; + var deltaTop = fromRect.top - toRect.top; + var deltaWidth = fromRect.width / toRect.width; + var deltaHeight = fromRect.height / toRect.height; + + this.setPrefixedProperty(shared.to, 'transformOrigin', '0 0'); + shared.to.style.zIndex = 10000; + shared.from.style.visibility = 'hidden'; + + this._effect = new KeyframeEffect(shared.to, [ + {'transform': 'translate(' + deltaLeft + 'px,' + deltaTop + 'px) scale(' + deltaWidth + ',' + deltaHeight + ')'}, + {'transform': 'none'} + ], this.timingFromConfig(config)); + + return this._effect; + }, + + complete: function(config) { + var shared = this.findSharedElements(config); + if (!shared) { + return null; + } + shared.to.style.zIndex = ''; + shared.from.style.visibility = ''; + } + + }); + +</script><script> + + Polymer({ + + is: 'ripple-animation', + + behaviors: [ + Polymer.NeonSharedElementAnimationBehavior + ], + + configure: function(config) { + var shared = this.findSharedElements(config); + if (!shared) { + return null; + } + + var translateX, translateY; + var toRect = shared.to.getBoundingClientRect(); + if (config.gesture) { + translateX = config.gesture.x - (toRect.left + (toRect.width / 2)); + translateY = config.gesture.y - (toRect.top + (toRect.height / 2)); + } else { + var fromRect = shared.from.getBoundingClientRect(); + translateX = (fromRect.left + (fromRect.width / 2)) - (toRect.left + (toRect.width / 2)); + translateY = (fromRect.top + (fromRect.height / 2)) - (toRect.top + (toRect.height / 2)); + } + var translate = 'translate(' + translateX + 'px,' + translateY + 'px)'; + + var size = Math.max(toRect.width + Math.abs(translateX) * 2, toRect.height + Math.abs(translateY) * 2); + var diameter = Math.sqrt(2 * size * size); + var scaleX = diameter / toRect.width; + var scaleY = diameter / toRect.height; + var scale = 'scale(' + scaleX + ',' + scaleY + ')'; + + this.setPrefixedProperty(shared.to, 'transformOrigin', '50% 50%'); + shared.to.style.borderRadius = '50%'; + + this._effect = new KeyframeEffect(shared.to, [ + {'transform': translate + ' scale(0)'}, + {'transform': translate + ' ' + scale} + ], this.timingFromConfig(config)); + return this._effect; + }, + + complete: function() { + if (this.sharedElements) { + this.setPrefixedProperty(this.sharedElements.to, 'transformOrigin', ''); + this.sharedElements.to.style.borderRadius = ''; + } + } + + }); + +</script><script> + Polymer({ + is: 'reverse-ripple-animation', + + behaviors: [ + Polymer.NeonSharedElementAnimationBehavior + ], + + configure: function(config) { + var shared = this.findSharedElements(config); + if (!shared) { + return null; + } + + var translateX, translateY; + var fromRect = shared.from.getBoundingClientRect(); + if (config.gesture) { + translateX = config.gesture.x - (fromRect.left + (fromRect.width / 2)); + translateY = config.gesture.y - (fromRect.top + (fromRect.height / 2)); + } else { + var toRect = shared.to.getBoundingClientRect(); + translateX = (toRect.left + (toRect.width / 2)) - (fromRect.left + (fromRect.width / 2)); + translateY = (toRect.top + (toRect.height / 2)) - (fromRect.top + (fromRect.height / 2)); + } + var translate = 'translate(' + translateX + 'px,' + translateY + 'px)'; + + var size = Math.max(fromRect.width + Math.abs(translateX) * 2, fromRect.height + Math.abs(translateY) * 2); + var diameter = Math.sqrt(2 * size * size); + var scaleX = diameter / fromRect.width; + var scaleY = diameter / fromRect.height; + var scale = 'scale(' + scaleX + ',' + scaleY + ')'; + + this.setPrefixedProperty(shared.from, 'transformOrigin', '50% 50%'); + shared.from.style.borderRadius = '50%'; + + this._effect = new KeyframeEffect(shared.from, [ + {'transform': translate + ' ' + scale}, + {'transform': translate + ' scale(0)'} + ], this.timingFromConfig(config)); + return this._effect; + }, + + complete: function() { + if (this.sharedElements) { + this.setPrefixedProperty(this.sharedElements.from, 'transformOrigin', ''); + this.sharedElements.from.style.borderRadius = ''; + } + } + }); +</script><script> + + Polymer({ + + is: 'scale-down-animation', + + behaviors: [ + Polymer.NeonAnimationBehavior + ], + + configure: function(config) { + var node = config.node; + + if (config.transformOrigin) { + this.setPrefixedProperty(node, 'transformOrigin', config.transformOrigin); + } + + var scaleProperty = 'scale(0, 0)'; + if (config.axis === 'x') { + scaleProperty = 'scale(0, 1)'; + } else if (config.axis === 'y') { + scaleProperty = 'scale(1, 0)'; + } + + this._effect = new KeyframeEffect(node, [ + {'transform': 'scale(1,1)'}, + {'transform': scaleProperty} + ], this.timingFromConfig(config)); + + return this._effect; + } + + }); + +</script><script> + + Polymer({ + + is: 'scale-up-animation', + + behaviors: [ + Polymer.NeonAnimationBehavior + ], + + configure: function(config) { + var node = config.node; + + if (config.transformOrigin) { + this.setPrefixedProperty(node, 'transformOrigin', config.transformOrigin); + } + + var scaleProperty = 'scale(0)'; + if (config.axis === 'x') { + scaleProperty = 'scale(0, 1)'; + } else if (config.axis === 'y') { + scaleProperty = 'scale(1, 0)'; + } + + this._effect = new KeyframeEffect(node, [ + {'transform': scaleProperty}, + {'transform': 'scale(1, 1)'} + ], this.timingFromConfig(config)); + + return this._effect; + } + + }); + +</script><script> + + Polymer({ + + is: 'slide-from-left-animation', + + behaviors: [ + Polymer.NeonAnimationBehavior + ], + + configure: function(config) { + var node = config.node; + + if (config.transformOrigin) { + this.setPrefixedProperty(node, 'transformOrigin', config.transformOrigin); + } else { + this.setPrefixedProperty(node, 'transformOrigin', '0 50%'); + } + + this._effect = new KeyframeEffect(node, [ + {'transform': 'translateX(-100%)'}, + {'transform': 'none'} + ], this.timingFromConfig(config)); + + return this._effect; + } + + }); + +</script><script> + + Polymer({ + + is: 'slide-from-right-animation', + + behaviors: [ + Polymer.NeonAnimationBehavior + ], + + configure: function(config) { + var node = config.node; + + if (config.transformOrigin) { + this.setPrefixedProperty(node, 'transformOrigin', config.transformOrigin); + } else { + this.setPrefixedProperty(node, 'transformOrigin', '0 50%'); + } + + this._effect = new KeyframeEffect(node, [ + {'transform': 'translateX(100%)'}, + {'transform': 'none'} + ], this.timingFromConfig(config)); + + return this._effect; + } + + }); + +</script><script> + + Polymer({ + + is: 'slide-left-animation', + + behaviors: [ + Polymer.NeonAnimationBehavior + ], + + configure: function(config) { + var node = config.node; + + if (config.transformOrigin) { + this.setPrefixedProperty(node, 'transformOrigin', config.transformOrigin); + } else { + this.setPrefixedProperty(node, 'transformOrigin', '0 50%'); + } + + this._effect = new KeyframeEffect(node, [ + {'transform': 'none'}, + {'transform': 'translateX(-100%)'} + ], this.timingFromConfig(config)); + + return this._effect; + } + + }); + +</script><script> + + Polymer({ + + is: 'slide-right-animation', + + behaviors: [ + Polymer.NeonAnimationBehavior + ], + + configure: function(config) { + var node = config.node; + + if (config.transformOrigin) { + this.setPrefixedProperty(node, 'transformOrigin', config.transformOrigin); + } else { + this.setPrefixedProperty(node, 'transformOrigin', '0 50%'); + } + + this._effect = new KeyframeEffect(node, [ + {'transform': 'none'}, + {'transform': 'translateX(100%)'} + ], this.timingFromConfig(config)); + + return this._effect; + } + + }); + +</script><script> + + Polymer({ + + is: 'slide-up-animation', + + behaviors: [ + Polymer.NeonAnimationBehavior + ], + + configure: function(config) { + var node = config.node; + + if (config.transformOrigin) { + this.setPrefixedProperty(node, 'transformOrigin', config.transformOrigin); + } else { + this.setPrefixedProperty(node, 'transformOrigin', '50% 0'); + } + + this._effect = new KeyframeEffect(node, [ + {'transform': 'translate(0)'}, + {'transform': 'translateY(-100%)'} + ], this.timingFromConfig(config)); + + return this._effect; + } + + }); + +</script><script> + + Polymer({ + + is: 'slide-down-animation', + + behaviors: [ + Polymer.NeonAnimationBehavior + ], + + configure: function(config) { + var node = config.node; + + if (config.transformOrigin) { + this.setPrefixedProperty(node, 'transformOrigin', config.transformOrigin); + } else { + this.setPrefixedProperty(node, 'transformOrigin', '50% 0'); + } + + this._effect = new KeyframeEffect(node, [ + {'transform': 'translateY(-100%)'}, + {'transform': 'none'} + ], this.timingFromConfig(config)); + + return this._effect; + } + + }); + +</script><script> + + Polymer({ + + is: 'transform-animation', + + behaviors: [ + Polymer.NeonAnimationBehavior + ], + + /** + * @param {{ + * node: !Element, + * transformOrigin: (string|undefined), + * transformFrom: (string|undefined), + * transformTo: (string|undefined), + * timing: (Object|undefined) + * }} config + */ + configure: function(config) { + var node = config.node; + var transformFrom = config.transformFrom || 'none'; + var transformTo = config.transformTo || 'none'; + + if (config.transformOrigin) { + this.setPrefixedProperty(node, 'transformOrigin', config.transformOrigin); + } + + this._effect = new KeyframeEffect(node, [ + {'transform': transformFrom}, + {'transform': transformTo} + ], this.timingFromConfig(config)); + + return this._effect; + } + + }); + +</script><style> + + /******************************* + Flex Layout + *******************************/ + + html /deep/ .layout.horizontal, + html /deep/ .layout.horizontal-reverse, + html /deep/ .layout.vertical, + html /deep/ .layout.vertical-reverse { + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + } + + html /deep/ .layout.inline { + display: -ms-inline-flexbox; + display: -webkit-inline-flex; + display: inline-flex; + } + + html /deep/ .layout.horizontal { + -ms-flex-direction: row; + -webkit-flex-direction: row; + flex-direction: row; + } + + html /deep/ .layout.horizontal-reverse { + -ms-flex-direction: row-reverse; + -webkit-flex-direction: row-reverse; + flex-direction: row-reverse; + } + + html /deep/ .layout.vertical { + -ms-flex-direction: column; + -webkit-flex-direction: column; + flex-direction: column; + } + + html /deep/ .layout.vertical-reverse { + -ms-flex-direction: column-reverse; + -webkit-flex-direction: column-reverse; + flex-direction: column-reverse; + } + + html /deep/ .layout.wrap { + -ms-flex-wrap: wrap; + -webkit-flex-wrap: wrap; + flex-wrap: wrap; + } + + html /deep/ .layout.wrap-reverse { + -ms-flex-wrap: wrap-reverse; + -webkit-flex-wrap: wrap-reverse; + flex-wrap: wrap-reverse; + } + + html /deep/ .flex-auto { + -ms-flex: 1 1 auto; + -webkit-flex: 1 1 auto; + flex: 1 1 auto; + } + + html /deep/ .flex-none { + -ms-flex: none; + -webkit-flex: none; + flex: none; + } + + html /deep/ .flex, + html /deep/ .flex-1 { + -ms-flex: 1; + -webkit-flex: 1; + flex: 1; + } + + html /deep/ .flex-2 { + -ms-flex: 2; + -webkit-flex: 2; + flex: 2; + } + + html /deep/ .flex-3 { + -ms-flex: 3; + -webkit-flex: 3; + flex: 3; + } + + html /deep/ .flex-4 { + -ms-flex: 4; + -webkit-flex: 4; + flex: 4; + } + + html /deep/ .flex-5 { + -ms-flex: 5; + -webkit-flex: 5; + flex: 5; + } + + html /deep/ .flex-6 { + -ms-flex: 6; + -webkit-flex: 6; + flex: 6; + } + + html /deep/ .flex-7 { + -ms-flex: 7; + -webkit-flex: 7; + flex: 7; + } + + html /deep/ .flex-8 { + -ms-flex: 8; + -webkit-flex: 8; + flex: 8; + } + + html /deep/ .flex-9 { + -ms-flex: 9; + -webkit-flex: 9; + flex: 9; + } + + html /deep/ .flex-10 { + -ms-flex: 10; + -webkit-flex: 10; + flex: 10; + } + + html /deep/ .flex-11 { + -ms-flex: 11; + -webkit-flex: 11; + flex: 11; + } + + html /deep/ .flex-12 { + -ms-flex: 12; + -webkit-flex: 12; + flex: 12; + } + + /* alignment in cross axis */ + + html /deep/ .layout.start { + -ms-flex-align: start; + -webkit-align-items: flex-start; + align-items: flex-start; + } + + html /deep/ .layout.center, + html /deep/ .layout.center-center { + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; + } + + html /deep/ .layout.end { + -ms-flex-align: end; + -webkit-align-items: flex-end; + align-items: flex-end; + } + + /* alignment in main axis */ + + html /deep/ .layout.start-justified { + -ms-flex-pack: start; + -webkit-justify-content: flex-start; + justify-content: flex-start; + } + + html /deep/ .layout.center-justified, + html /deep/ .layout.center-center { + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + } + + html /deep/ .layout.end-justified { + -ms-flex-pack: end; + -webkit-justify-content: flex-end; + justify-content: flex-end; + } + + html /deep/ .layout.around-justified { + -ms-flex-pack: around; + -webkit-justify-content: space-around; + justify-content: space-around; + } + + html /deep/ .layout.justified { + -ms-flex-pack: justify; + -webkit-justify-content: space-between; + justify-content: space-between; + } + + /* self alignment */ + + html /deep/ .self-start { + -ms-align-self: flex-start; + -webkit-align-self: flex-start; + align-self: flex-start; + } + + html /deep/ .self-center { + -ms-align-self: center; + -webkit-align-self: center; + align-self: center; + } + + html /deep/ .self-end { + -ms-align-self: flex-end; + -webkit-align-self: flex-end; + align-self: flex-end; + } + + html /deep/ .self-stretch { + -ms-align-self: stretch; + -webkit-align-self: stretch; + align-self: stretch; + } + + /******************************* + Other Layout + *******************************/ + + html /deep/ .block { + display: block; + } + + /* IE 10 support for HTML5 hidden attr */ + html /deep/ [hidden] { + display: none !important; + } + + html /deep/ .invisible { + visibility: hidden !important; + } + + html /deep/ .relative { + position: relative; + } + + html /deep/ .fit { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + } + + body.fullbleed { + margin: 0; + height: 100vh; + } + + html /deep/ .scroll { + -webkit-overflow-scrolling: touch; + overflow: auto; + } + + .fixed-bottom, + .fixed-left, + .fixed-right, + .fixed-top { + position: fixed; + } + + html /deep/ .fixed-top { + top: 0; + left: 0; + right: 0; + } + + html /deep/ .fixed-right { + top: 0; + right: 0; + bottom: 0; + } + + html /deep/ .fixed-bottom { + right: 0; + bottom: 0; + left: 0; + } + + html /deep/ .fixed-left { + top: 0; + bottom: 0; + left: 0; + } + +</style><style> + + /******************************* + Flex Layout + *******************************/ + + .layout.horizontal, + .layout.horizontal-reverse, + .layout.vertical, + .layout.vertical-reverse { + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + } + + .layout.inline { + display: -ms-inline-flexbox; + display: -webkit-inline-flex; + display: inline-flex; + } + + .layout.horizontal { + -ms-flex-direction: row; + -webkit-flex-direction: row; + flex-direction: row; + } + + .layout.horizontal-reverse { + -ms-flex-direction: row-reverse; + -webkit-flex-direction: row-reverse; + flex-direction: row-reverse; + } + + .layout.vertical { + -ms-flex-direction: column; + -webkit-flex-direction: column; + flex-direction: column; + } + + .layout.vertical-reverse { + -ms-flex-direction: column-reverse; + -webkit-flex-direction: column-reverse; + flex-direction: column-reverse; + } + + .layout.wrap { + -ms-flex-wrap: wrap; + -webkit-flex-wrap: wrap; + flex-wrap: wrap; + } + + .layout.wrap-reverse { + -ms-flex-wrap: wrap-reverse; + -webkit-flex-wrap: wrap-reverse; + flex-wrap: wrap-reverse; + } + + .flex-auto { + -ms-flex: 1 1 auto; + -webkit-flex: 1 1 auto; + flex: 1 1 auto; + } + + .flex-none { + -ms-flex: none; + -webkit-flex: none; + flex: none; + } + + .flex, + .flex-1 { + -ms-flex: 1; + -webkit-flex: 1; + flex: 1; + } + + .flex-2 { + -ms-flex: 2; + -webkit-flex: 2; + flex: 2; + } + + .flex-3 { + -ms-flex: 3; + -webkit-flex: 3; + flex: 3; + } + + .flex-4 { + -ms-flex: 4; + -webkit-flex: 4; + flex: 4; + } + + .flex-5 { + -ms-flex: 5; + -webkit-flex: 5; + flex: 5; + } + + .flex-6 { + -ms-flex: 6; + -webkit-flex: 6; + flex: 6; + } + + .flex-7 { + -ms-flex: 7; + -webkit-flex: 7; + flex: 7; + } + + .flex-8 { + -ms-flex: 8; + -webkit-flex: 8; + flex: 8; + } + + .flex-9 { + -ms-flex: 9; + -webkit-flex: 9; + flex: 9; + } + + .flex-10 { + -ms-flex: 10; + -webkit-flex: 10; + flex: 10; + } + + .flex-11 { + -ms-flex: 11; + -webkit-flex: 11; + flex: 11; + } + + .flex-12 { + -ms-flex: 12; + -webkit-flex: 12; + flex: 12; + } + + /* alignment in cross axis */ + + .layout.start { + -ms-flex-align: start; + -webkit-align-items: flex-start; + align-items: flex-start; + } + + .layout.center, + .layout.center-center { + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; + } + + .layout.end { + -ms-flex-align: end; + -webkit-align-items: flex-end; + align-items: flex-end; + } + + /* alignment in main axis */ + + .layout.start-justified { + -ms-flex-pack: start; + -webkit-justify-content: flex-start; + justify-content: flex-start; + } + + .layout.center-justified, + .layout.center-center { + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + } + + .layout.end-justified { + -ms-flex-pack: end; + -webkit-justify-content: flex-end; + justify-content: flex-end; + } + + .layout.around-justified { + -ms-flex-pack: around; + -webkit-justify-content: space-around; + justify-content: space-around; + } + + .layout.justified { + -ms-flex-pack: justify; + -webkit-justify-content: space-between; + justify-content: space-between; + } + + /* self alignment */ + + .self-start { + -ms-align-self: flex-start; + -webkit-align-self: flex-start; + align-self: flex-start; + } + + .self-center { + -ms-align-self: center; + -webkit-align-self: center; + align-self: center; + } + + .self-end { + -ms-align-self: flex-end; + -webkit-align-self: flex-end; + align-self: flex-end; + } + + .self-stretch { + -ms-align-self: stretch; + -webkit-align-self: stretch; + align-self: stretch; + } + + /******************************* + Other Layout + *******************************/ + + .block { + display: block; + } + + /* IE 10 support for HTML5 hidden attr */ + [hidden] { + display: none !important; + } + + .invisible { + visibility: hidden !important; + } + + .relative { + position: relative; + } + + .fit { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + } + + body.fullbleed { + margin: 0; + height: 100vh; + } + + .scroll { + -webkit-overflow-scrolling: touch; + overflow: auto; + } + + /* fixed position */ + + .fixed-bottom, + .fixed-left, + .fixed-right, + .fixed-top { + position: fixed; + } + + .fixed-top { + top: 0; + left: 0; + right: 0; + } + + .fixed-right { + top: 0; + right: 0; + bottom: 0; + } + + .fixed-bottom { + right: 0; + bottom: 0; + left: 0; + } + + .fixed-left { + top: 0; + bottom: 0; + left: 0; + } + +</style><style> + +.paper-font-display4, +.paper-font-display3, +.paper-font-display2, +.paper-font-display1, +.paper-font-headline, +.paper-font-title, +.paper-font-subhead, +.paper-font-body2, +.paper-font-body1, +.paper-font-caption, +.paper-font-menu, +.paper-font-button { + font-family: 'Roboto', 'Noto', sans-serif; + -webkit-font-smoothing: antialiased; /* OS X subpixel AA bleed bug */ +} + +.paper-font-code2, +.paper-font-code1 { + font-family: 'Roboto Mono', 'Consolas', 'Menlo', monospace; + -webkit-font-smoothing: antialiased; /* OS X subpixel AA bleed bug */ +} + +/* Opt for better kerning for headers & other short labels. */ +.paper-font-display4, +.paper-font-display3, +.paper-font-display2, +.paper-font-display1, +.paper-font-headline, +.paper-font-title, +.paper-font-subhead, +.paper-font-menu, +.paper-font-button { + text-rendering: optimizeLegibility; +} + +/* +"Line wrapping only applies to Body, Subhead, Headline, and the smaller Display +styles. All other styles should exist as single lines." +*/ +.paper-font-display4, +.paper-font-display3, +.paper-font-title, +.paper-font-caption, +.paper-font-menu, +.paper-font-button { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.paper-font-display4 { + font-size: 112px; + font-weight: 300; + letter-spacing: -.044em; + line-height: 120px; +} + +.paper-font-display3 { + font-size: 56px; + font-weight: 400; + letter-spacing: -.026em; + line-height: 60px; +} + +.paper-font-display2 { + font-size: 45px; + font-weight: 400; + letter-spacing: -.018em; + line-height: 48px; +} + +.paper-font-display1 { + font-size: 34px; + font-weight: 400; + letter-spacing: -.01em; + line-height: 40px; +} + +.paper-font-headline { + font-size: 24px; + font-weight: 400; + letter-spacing: -.012em; + line-height: 32px; +} + +.paper-font-title { + font-size: 20px; + font-weight: 500; + line-height: 28px; +} + +.paper-font-subhead { + font-size: 16px; + font-weight: 400; + line-height: 24px; +} + +.paper-font-body2 { + font-size: 14px; + font-weight: 500; + line-height: 24px; +} + +.paper-font-body1 { + font-size: 14px; + font-weight: 400; + line-height: 20px; +} + +.paper-font-caption { + font-size: 12px; + font-weight: 400; + letter-spacing: 0.011em; + line-height: 20px; +} + +.paper-font-menu { + font-size: 13px; + font-weight: 500; + line-height: 24px; +} + +.paper-font-button { + font-size: 14px; + font-weight: 500; + letter-spacing: 0.018em; + line-height: 24px; + text-transform: uppercase; +} + +.paper-font-code2 { + font-size: 14px; + font-weight: 700; + line-height: 20px; +} + +.paper-font-code1 { + font-size: 14px; + font-weight: 500; + line-height: 20px; +} + +</style><style> +.shadow-transition { + transition: box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1); +} + +.shadow-elevation-2dp { + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), + 0 1px 5px 0 rgba(0, 0, 0, 0.12), + 0 3px 1px -2px rgba(0, 0, 0, 0.2); +} + +.shadow-elevation-3dp { + box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.14), + 0 1px 8px 0 rgba(0, 0, 0, 0.12), + 0 3px 3px -2px rgba(0, 0, 0, 0.4); +} + +.shadow-elevation-4dp { + box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), + 0 1px 10px 0 rgba(0, 0, 0, 0.12), + 0 2px 4px -1px rgba(0, 0, 0, 0.4); +} + +.shadow-elevation-6dp { + box-shadow: 0 6px 10px 0 rgba(0, 0, 0, 0.14), + 0 1px 18px 0 rgba(0, 0, 0, 0.12), + 0 3px 5px -1px rgba(0, 0, 0, 0.4); +} + +.shadow-elevation-8dp { + box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14), + 0 3px 14px 2px rgba(0, 0, 0, 0.12), + 0 5px 5px -3px rgba(0, 0, 0, 0.4); +} + +.shadow-elevation-16dp { + box-shadow: 0 16px 24px 2px rgba(0, 0, 0, 0.14), + 0 6px 30px 5px rgba(0, 0, 0, 0.12), + 0 8px 10px -5px rgba(0, 0, 0, 0.4); +} + +</style><style is=custom-style> + + :root { + /* + * Light background theme + */ + --light-theme-background-color: #ffffff; + --light-theme-base-color: #000000; + --light-theme-text-color: #212121; + --light-theme-secondary-color: #737373; /* for secondary text and icons */ + --light-theme-disabled-color: #9b9b9b; /* disabled/hint text */ + --light-theme-divider-color: #dbdbdb; + + /* + * Dark background theme + */ + --dark-theme-background-color: #212121; + --dark-theme-base-color: #ffffff; + --dark-theme-text-color: #ffffff; + --dark-theme-secondary-color: #bcbcbc; /* for secondary text and icons */ + --dark-theme-disabled-color: #646464; /* disabled/hint text */ + --dark-theme-divider-color: #3c3c3c; + + /* + * Primary and accent colors. Also see color.html for more colors. + */ + --primary-color: #3f51b5; /* --paper-indigo-500 */ + --light-primary-color: #c5cae9; /* --paper-indigo-100 */ + --dark-primary-color: #303f9f; /* --paper-indigo-700 */ + + --accent-color: #ff4081; /* --paper-pink-a200 */ + --light-accent-color: #ff80ab; /* --paper-pink-a100 */ + --dark-accent-color: #f50057; /* --paper-pink-a400 */ + + /* + * Deprecated values because of their confusing names. + */ + --primary-text-color: var(--light-theme-text-color); + --text-primary-color: var(--dark-theme-text-color); + --primary-background-color: var(--light-theme-background-color); + --secondary-text-color: var(--light-theme-secondary-color); + --disabled-text-color:var(--light-theme-disabled-color); + --divider-color: var(--light-theme-divider-color); + --default-primary-color: var(--primary-color); + } + +</style><script> + (function() { + 'use strict'; + + /** + * Chrome uses an older version of DOM Level 3 Keyboard Events + * + * Most keys are labeled as text, but some are Unicode codepoints. + * Values taken from: http://www.w3.org/TR/2007/WD-DOM-Level-3-Events-20071221/keyset.html#KeySet-Set + */ + var KEY_IDENTIFIER = { + 'U+0008': 'backspace', + 'U+0009': 'tab', + 'U+001B': 'esc', + 'U+0020': 'space', + 'U+007F': 'del' + }; + + /** + * Special table for KeyboardEvent.keyCode. + * KeyboardEvent.keyIdentifier is better, and KeyBoardEvent.key is even better + * than that. + * + * Values from: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent.keyCode#Value_of_keyCode + */ + var KEY_CODE = { + 8: 'backspace', + 9: 'tab', + 13: 'enter', + 27: 'esc', + 33: 'pageup', + 34: 'pagedown', + 35: 'end', + 36: 'home', + 32: 'space', + 37: 'left', + 38: 'up', + 39: 'right', + 40: 'down', + 46: 'del', + 106: '*' + }; + + /** + * MODIFIER_KEYS maps the short name for modifier keys used in a key + * combo string to the property name that references those same keys + * in a KeyboardEvent instance. + */ + var MODIFIER_KEYS = { + 'shift': 'shiftKey', + 'ctrl': 'ctrlKey', + 'alt': 'altKey', + 'meta': 'metaKey' + }; + + /** + * Matches a keyIdentifier string. + */ + var IDENT_CHAR = /U\+/; + + /** + * Matches arrow keys in Gecko 27.0+ + */ + var ARROW_KEY = /^arrow/; + + /** + * Matches space keys everywhere (notably including IE10's exceptional name + * `spacebar`). + */ + var SPACE_KEY = /^space(bar)?/; + + function transformKey(key) { + var validKey = ''; + if (key) { + var lKey = key.toLowerCase(); + if (lKey === ' ' || SPACE_KEY.test(lKey)) { + validKey = 'space'; + } else if (lKey.length == 1) { + validKey = lKey; + } else if (ARROW_KEY.test(lKey)) { + validKey = lKey.replace('arrow', ''); + } else if (lKey == 'multiply') { + // numpad '*' can map to Multiply on IE/Windows + validKey = '*'; + } else { + validKey = lKey; + } + } + return validKey; + } + + function transformKeyIdentifier(keyIdent) { + var validKey = ''; + if (keyIdent) { + if (keyIdent in KEY_IDENTIFIER) { + validKey = KEY_IDENTIFIER[keyIdent]; + } else if (IDENT_CHAR.test(keyIdent)) { + keyIdent = parseInt(keyIdent.replace('U+', '0x'), 16); + validKey = String.fromCharCode(keyIdent).toLowerCase(); + } else { + validKey = keyIdent.toLowerCase(); + } + } + return validKey; + } + + function transformKeyCode(keyCode) { + var validKey = ''; + if (Number(keyCode)) { + if (keyCode >= 65 && keyCode <= 90) { + // ascii a-z + // lowercase is 32 offset from uppercase + validKey = String.fromCharCode(32 + keyCode); + } else if (keyCode >= 112 && keyCode <= 123) { + // function keys f1-f12 + validKey = 'f' + (keyCode - 112); + } else if (keyCode >= 48 && keyCode <= 57) { + // top 0-9 keys + validKey = String(48 - keyCode); + } else if (keyCode >= 96 && keyCode <= 105) { + // num pad 0-9 + validKey = String(96 - keyCode); + } else { + validKey = KEY_CODE[keyCode]; + } + } + return validKey; + } + + function normalizedKeyForEvent(keyEvent) { + // fall back from .key, to .keyIdentifier, to .keyCode, and then to + // .detail.key to support artificial keyboard events + return transformKey(keyEvent.key) || + transformKeyIdentifier(keyEvent.keyIdentifier) || + transformKeyCode(keyEvent.keyCode) || + transformKey(keyEvent.detail.key) || ''; + } + + function keyComboMatchesEvent(keyCombo, event, eventKey) { + return eventKey === keyCombo.key && + (!keyCombo.hasModifiers || ( + !!event.shiftKey === !!keyCombo.shiftKey && + !!event.ctrlKey === !!keyCombo.ctrlKey && + !!event.altKey === !!keyCombo.altKey && + !!event.metaKey === !!keyCombo.metaKey) + ); + } + + function parseKeyComboString(keyComboString) { + if (keyComboString.length === 1) { + return { + combo: keyComboString, + key: keyComboString, + event: 'keydown' + }; + } + return keyComboString.split('+').reduce(function(parsedKeyCombo, keyComboPart) { + var eventParts = keyComboPart.split(':'); + var keyName = eventParts[0]; + var event = eventParts[1]; + + if (keyName in MODIFIER_KEYS) { + parsedKeyCombo[MODIFIER_KEYS[keyName]] = true; + parsedKeyCombo.hasModifiers = true; + } else { + parsedKeyCombo.key = keyName; + parsedKeyCombo.event = event || 'keydown'; + } + + return parsedKeyCombo; + }, { + combo: keyComboString.split(':').shift() + }); + } + + function parseEventString(eventString) { + return eventString.trim().split(' ').map(function(keyComboString) { + return parseKeyComboString(keyComboString); + }); + } + + /** + * `Polymer.IronA11yKeysBehavior` provides a normalized interface for processing + * keyboard commands that pertain to [WAI-ARIA best practices](http://www.w3.org/TR/wai-aria-practices/#kbd_general_binding). + * The element takes care of browser differences with respect to Keyboard events + * and uses an expressive syntax to filter key presses. + * + * Use the `keyBindings` prototype property to express what combination of keys + * will trigger the event to fire. + * + * Use the `key-event-target` attribute to set up event handlers on a specific + * node. + * The `keys-pressed` event will fire when one of the key combinations set with the + * `keys` property is pressed. + * + * @demo demo/index.html + * @polymerBehavior + */ + Polymer.IronA11yKeysBehavior = { + properties: { + /** + * The HTMLElement that will be firing relevant KeyboardEvents. + */ + keyEventTarget: { + type: Object, + value: function() { + return this; + } + }, + + /** + * If true, this property will cause the implementing element to + * automatically stop propagation on any handled KeyboardEvents. + */ + stopKeyboardEventPropagation: { + type: Boolean, + value: false + }, + + _boundKeyHandlers: { + type: Array, + value: function() { + return []; + } + }, + + // We use this due to a limitation in IE10 where instances will have + // own properties of everything on the "prototype". + _imperativeKeyBindings: { + type: Object, + value: function() { + return {}; + } + } + }, + + observers: [ + '_resetKeyEventListeners(keyEventTarget, _boundKeyHandlers)' + ], + + keyBindings: {}, + + registered: function() { + this._prepKeyBindings(); + }, + + attached: function() { + this._listenKeyEventListeners(); + }, + + detached: function() { + this._unlistenKeyEventListeners(); + }, + + /** + * Can be used to imperatively add a key binding to the implementing + * element. This is the imperative equivalent of declaring a keybinding + * in the `keyBindings` prototype property. + */ + addOwnKeyBinding: function(eventString, handlerName) { + this._imperativeKeyBindings[eventString] = handlerName; + this._prepKeyBindings(); + this._resetKeyEventListeners(); + }, + + /** + * When called, will remove all imperatively-added key bindings. + */ + removeOwnKeyBindings: function() { + this._imperativeKeyBindings = {}; + this._prepKeyBindings(); + this._resetKeyEventListeners(); + }, + + keyboardEventMatchesKeys: function(event, eventString) { + var keyCombos = parseEventString(eventString); + var eventKey = normalizedKeyForEvent(event); + for (var i = 0; i < keyCombos.length; ++i) { + if (keyComboMatchesEvent(keyCombos[i], event, eventKey)) { + return true; + } + } + return false; + }, + + _collectKeyBindings: function() { + var keyBindings = this.behaviors.map(function(behavior) { + return behavior.keyBindings; + }); + + if (keyBindings.indexOf(this.keyBindings) === -1) { + keyBindings.push(this.keyBindings); + } + + return keyBindings; + }, + + _prepKeyBindings: function() { + this._keyBindings = {}; + + this._collectKeyBindings().forEach(function(keyBindings) { + for (var eventString in keyBindings) { + this._addKeyBinding(eventString, keyBindings[eventString]); + } + }, this); + + for (var eventString in this._imperativeKeyBindings) { + this._addKeyBinding(eventString, this._imperativeKeyBindings[eventString]); + } + + // Give precedence to combos with modifiers to be checked first. + for (var eventName in this._keyBindings) { + this._keyBindings[eventName].sort(function (kb1, kb2) { + var b1 = kb1[0].hasModifiers; + var b2 = kb2[0].hasModifiers; + return (b1 === b2) ? 0 : b1 ? -1 : 1; + }) + } + }, + + _addKeyBinding: function(eventString, handlerName) { + parseEventString(eventString).forEach(function(keyCombo) { + this._keyBindings[keyCombo.event] = + this._keyBindings[keyCombo.event] || []; + + this._keyBindings[keyCombo.event].push([ + keyCombo, + handlerName + ]); + }, this); + }, + + _resetKeyEventListeners: function() { + this._unlistenKeyEventListeners(); + + if (this.isAttached) { + this._listenKeyEventListeners(); + } + }, + + _listenKeyEventListeners: function() { + Object.keys(this._keyBindings).forEach(function(eventName) { + var keyBindings = this._keyBindings[eventName]; + var boundKeyHandler = this._onKeyBindingEvent.bind(this, keyBindings); + + this._boundKeyHandlers.push([this.keyEventTarget, eventName, boundKeyHandler]); + + this.keyEventTarget.addEventListener(eventName, boundKeyHandler); + }, this); + }, + + _unlistenKeyEventListeners: function() { + var keyHandlerTuple; + var keyEventTarget; + var eventName; + var boundKeyHandler; + + while (this._boundKeyHandlers.length) { + // My kingdom for block-scope binding and destructuring assignment.. + keyHandlerTuple = this._boundKeyHandlers.pop(); + keyEventTarget = keyHandlerTuple[0]; + eventName = keyHandlerTuple[1]; + boundKeyHandler = keyHandlerTuple[2]; + + keyEventTarget.removeEventListener(eventName, boundKeyHandler); + } + }, + + _onKeyBindingEvent: function(keyBindings, event) { + if (this.stopKeyboardEventPropagation) { + event.stopPropagation(); + } + + // if event has been already prevented, don't do anything + if (event.defaultPrevented) { + return; + } + + var eventKey = normalizedKeyForEvent(event); + for (var i = 0; i < keyBindings.length; i++) { + var keyCombo = keyBindings[i][0]; + var handlerName = keyBindings[i][1]; + if (keyComboMatchesEvent(keyCombo, event, eventKey)) { + this._triggerKeyHandler(keyCombo, handlerName, event); + // exit the loop if eventDefault was prevented + if (event.defaultPrevented) { + return; + } + } + } + }, + + _triggerKeyHandler: function(keyCombo, handlerName, keyboardEvent) { + var detail = Object.create(keyCombo); + detail.keyboardEvent = keyboardEvent; + var event = new CustomEvent(keyCombo.event, { + detail: detail, + cancelable: true + }); + this[handlerName].call(this, event); + if (event.defaultPrevented) { + keyboardEvent.preventDefault(); + } + } + }; + })(); +</script><script> + + /** + * @demo demo/index.html + * @polymerBehavior + */ + Polymer.IronControlState = { + + properties: { + + /** + * If true, the element currently has focus. + */ + focused: { + type: Boolean, + value: false, + notify: true, + readOnly: true, + reflectToAttribute: true + }, + + /** + * If true, the user cannot interact with this element. + */ + disabled: { + type: Boolean, + value: false, + notify: true, + observer: '_disabledChanged', + reflectToAttribute: true + }, + + _oldTabIndex: { + type: Number + }, + + _boundFocusBlurHandler: { + type: Function, + value: function() { + return this._focusBlurHandler.bind(this); + } + } + + }, + + observers: [ + '_changedControlState(focused, disabled)' + ], + + ready: function() { + this.addEventListener('focus', this._boundFocusBlurHandler, true); + this.addEventListener('blur', this._boundFocusBlurHandler, true); + }, + + _focusBlurHandler: function(event) { + // NOTE(cdata): if we are in ShadowDOM land, `event.target` will + // eventually become `this` due to retargeting; if we are not in + // ShadowDOM land, `event.target` will eventually become `this` due + // to the second conditional which fires a synthetic event (that is also + // handled). In either case, we can disregard `event.path`. + + if (event.target === this) { + this._setFocused(event.type === 'focus'); + } else if (!this.shadowRoot && !this.isLightDescendant(event.target)) { + this.fire(event.type, {sourceEvent: event}, { + node: this, + bubbles: event.bubbles, + cancelable: event.cancelable + }); + } + }, + + _disabledChanged: function(disabled, old) { + this.setAttribute('aria-disabled', disabled ? 'true' : 'false'); + this.style.pointerEvents = disabled ? 'none' : ''; + if (disabled) { + this._oldTabIndex = this.tabIndex; + this.focused = false; + this.tabIndex = -1; + } else if (this._oldTabIndex !== undefined) { + this.tabIndex = this._oldTabIndex; + } + }, + + _changedControlState: function() { + // _controlStateChanged is abstract, follow-on behaviors may implement it + if (this._controlStateChanged) { + this._controlStateChanged(); + } + } + + }; + +</script><script> + + /** + * @demo demo/index.html + * @polymerBehavior Polymer.IronButtonState + */ + Polymer.IronButtonStateImpl = { + + properties: { + + /** + * If true, the user is currently holding down the button. + */ + pressed: { + type: Boolean, + readOnly: true, + value: false, + reflectToAttribute: true, + observer: '_pressedChanged' + }, + + /** + * If true, the button toggles the active state with each tap or press + * of the spacebar. + */ + toggles: { + type: Boolean, + value: false, + reflectToAttribute: true + }, + + /** + * If true, the button is a toggle and is currently in the active state. + */ + active: { + type: Boolean, + value: false, + notify: true, + reflectToAttribute: true + }, + + /** + * True if the element is currently being pressed by a "pointer," which + * is loosely defined as mouse or touch input (but specifically excluding