From a53bed9e253c188ac46f7a6995bcd39cf8b2ed00 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Tue, 21 May 2013 11:12:01 -0700 Subject: [PATCH 0001/1006] change dir to vulcanize --- .gitignore | 2 + README.md | 6 +++ package.json | 18 +++++++ vulcan.js | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 164 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 package.json create mode 100644 vulcan.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..ad96abfab --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +output.html +node_modules diff --git a/README.md b/README.md new file mode 100644 index 000000000..611f43fb7 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +# Vulcan + +> Concatenate a set of Web Components loaded via HTML Imports into one file + +Named for the [Vulcanization](http://en.wikipedia.org/wiki/Vulcanization) process that turns polymers into more durable +materials. diff --git a/package.json b/package.json new file mode 100644 index 000000000..2d98ec968 --- /dev/null +++ b/package.json @@ -0,0 +1,18 @@ +{ + "name": "vulcanize", + "version": "0.0.0", + "description": "Concat all the components into one output file, with dependencies in the proper order", + "main": "vulcan.js", + "dependencies": { + "cheerio": "~0.11.0", + "nopt": "~2.1.1" + }, + "devDependencies": {}, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": "", + "author": "", + "license": "BSD", + "readmeFilename": "README.md" +} diff --git a/vulcan.js b/vulcan.js new file mode 100644 index 000000000..c023c1891 --- /dev/null +++ b/vulcan.js @@ -0,0 +1,138 @@ +var fs = require('fs'); +var path = require('path'); +var cheerio = require('cheerio'); +var nopt = require('nopt'); + +var options = nopt( + { + 'output': path, + 'input': [path, Array], + 'verbose': Boolean + }, + { + 'o': ['--output'], + 'i': ['--input'], + 'v': ['--verbose'] + } +); + +if (!options.input) { + console.error('No input files given'); + process.exit(1); +} + +if (!options.output) { + console.warn('Default output to output.html'); + options.output = path.resolve('output.html'); +} + +var outputDir = path.dirname(options.output); + +var IMPORTS = 'link[rel="import"][href]'; +var ELEMENTS = 'element'; +var URL_ATTR = ['href', 'src', 'action', 'style']; +var URL_ATTR_SEL = '[' + URL_ATTR.join('],[') + ']'; +var ABS_URL = /(^data:)|(^http[s]?:)|(^\/)/; +var URL = /url\([^)]*\)/g; +var URL_TEMPLATE = '{{.*}}'; + +function concatElement(dir, output, e) { + e = resolveElementPaths(dir, output, e); + buffer.push(e); +} + +function resolveElementPaths(input, output, element) { + var $ = cheerio.load(element); + resolvePaths(input, output, $); + return $.html('element'); +} + +function resolvePaths(input, output, $) { + // resolve attributes + $(URL_ATTR_SEL).each(function() { + var val; + URL_ATTR.forEach(function(a) { + if (val = this.attr(a)) { + if (val.search(URL_TEMPLATE) < 0) { + if (a === 'style') { + this.attr(a, rewriteURL(input, output, val)); + } else { + this.attr(a, rewriteRelPath(input, output, val)); + } + } + } + }, this); + }); + // resolve style elements + $('style').each(function() { + var val = this.html(); + this.html(rewriteURL(input, output, val)); + }); +} + +function rewriteRelPath(inputPath, outputPath, rel) { + if (ABS_URL.test(rel)) { + return rel; + } + var abs = path.resolve(inputPath, rel); + return path.relative(outputPath, abs); +} + +function rewriteURL(inputPath, outputPath, cssText) { + return cssText.replace(URL, function(match) { + var path = match.replace(/["']/g, "").slice(4, -1); + path = rewriteRelPath(inputPath, outputPath, path); + return 'url(' + path + ')'; + }); +} + +function readDocument(docname) { + if (options.verbose) { + console.log('Reading:', docname); + } + var content = fs.readFileSync(docname, 'utf8'); + return cheerio.load(content); +} + +function extractImports($, dir) { + var hrefs = $(IMPORTS).map(function(){ return this.attr('href') }); + return hrefs.map(function(h) { return path.resolve(dir, h) }); +} + +function extractElements($) { + return $(ELEMENTS).map(function(i, e){ return $.html(e) }); +} + +function concat(filename) { + if (!read[filename]) { + read[filename] = true; + var $ = readDocument(filename); + var dir = path.dirname(filename); + var links = extractImports($, dir); + resolve(filename, links); + var es = extractElements($); + es.forEach(concatElement.bind(this, dir, outputDir)); + } else { + if (options.verbose) { + console.log('Dependency deduplicated'); + } + } +} + +function resolve(inName, inDependencies) { + if (inDependencies.length > 0) { + if (options.verbose) { + console.log('Dependencies:', inDependencies); + } + inDependencies.forEach(concat); + } +} + +var buffer = []; +var read = {}; + +options.input.forEach(concat); + +if (buffer.length) { + fs.writeFileSync(options.output, buffer.join('\n'), 'utf8'); +} From 65742e4173ff888b84085d160584c33cceee10ed Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Thu, 30 May 2013 16:35:41 -0700 Subject: [PATCH 0002/1006] use assetpath attribute on to fix resolvePath usage in Polymer elements --- vulcan.js | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/vulcan.js b/vulcan.js index c023c1891..50cea0e2b 100644 --- a/vulcan.js +++ b/vulcan.js @@ -99,8 +99,8 @@ function extractImports($, dir) { return hrefs.map(function(h) { return path.resolve(dir, h) }); } -function extractElements($) { - return $(ELEMENTS).map(function(i, e){ return $.html(e) }); +function extractElements($, assetPath) { + return $(ELEMENTS).map(function(i, e){ this.attr('assetpath', assetPath); return $.html(e) }); } function concat(filename) { @@ -108,9 +108,10 @@ function concat(filename) { read[filename] = true; var $ = readDocument(filename); var dir = path.dirname(filename); + var assetPath = path.relative(outputDir, dir); var links = extractImports($, dir); resolve(filename, links); - var es = extractElements($); + var es = extractElements($, assetPath); es.forEach(concatElement.bind(this, dir, outputDir)); } else { if (options.verbose) { @@ -128,7 +129,28 @@ function resolve(inName, inDependencies) { } } -var buffer = []; +// monkey patch addResolvePath for build +var monkeyPatch = function(proto, element) { + var assetPath = element.getAttribute('assetpath'); + var url = HTMLImports.getDocumentUrl(element.ownerDocument) || ''; + if (url) { + var parts = url.split('/'); + parts.pop(); + if (assetPath) { + parts.push(assetPath); + } + parts.push(''); + url = parts.join('/'); + } + proto.resolvePath = function(path) { + return url + path; + } +}; + +var buffer = [ + '', + '' +]; var read = {}; options.input.forEach(concat); From 7a14a0a2e038031b832e2623e804f73bf3fb1996 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Mon, 10 Jun 2013 11:35:05 -0600 Subject: [PATCH 0003/1006] Much more useful README --- README.md | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 82 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 611f43fb7..af79051b0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,86 @@ # Vulcan -> Concatenate a set of Web Components loaded via HTML Imports into one file +### Concatenate a set of Web Components into one file -Named for the [Vulcanization](http://en.wikipedia.org/wiki/Vulcanization) process that turns polymers into more durable +>Named for the [Vulcanization](http://en.wikipedia.org/wiki/Vulcanization) process that turns polymers into more durable materials. + +## Getting Started +- Install the node dependencies with `npm install` + - Depends on [cheerio](https://github.com/MatthewMueller/cheerio) and [nopt](https://github.com/isaacs/nopt) +- Give some input html files with the `--input` or `-i` flags + - Input html should have `` tags +- Specify an output html file with `--output` or `-o` + - Defaults to `output.html` in the current directory +- URL paths are adjusted for the new output location automatically (execpt ones set in Javascript) +- Once finished, link the final output html into your app page with ``. + +## Example + +Say we have three html files: `index.html`, `x-app.html`, and `x-dep.html`. + +index.html: + +```html + + + +``` + +app.html: + +```html + + + + + +``` + +x-dep.html: + +```html + + + + +``` + +Running vulcan on `index.html`, and specifying `build.html` as the output: + + node vulcan.js -i index.html -o build.html + +Will result in `build.html` that appears as so: + +```html + + + + + + + + +``` + +To use this, make `build.html` the only import in `index.html`: + +```html + + + +``` From 866e28203d75f9b4ce00409268efebcd3cd49c80 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Tue, 16 Jul 2013 03:51:41 -0700 Subject: [PATCH 0004/1006] update for polymer-element --- vulcan.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vulcan.js b/vulcan.js index 50cea0e2b..eda3929ae 100644 --- a/vulcan.js +++ b/vulcan.js @@ -29,7 +29,7 @@ if (!options.output) { var outputDir = path.dirname(options.output); var IMPORTS = 'link[rel="import"][href]'; -var ELEMENTS = 'element'; +var ELEMENTS = 'polymer-element'; var URL_ATTR = ['href', 'src', 'action', 'style']; var URL_ATTR_SEL = '[' + URL_ATTR.join('],[') + ']'; var ABS_URL = /(^data:)|(^http[s]?:)|(^\/)/; @@ -44,7 +44,7 @@ function concatElement(dir, output, e) { function resolveElementPaths(input, output, element) { var $ = cheerio.load(element); resolvePaths(input, output, $); - return $.html('element'); + return $.html(ELEMENTS); } function resolvePaths(input, output, $) { From 42c09030c35b8b2a4eb7177965a04c1707793061 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Tue, 16 Jul 2013 03:58:03 -0700 Subject: [PATCH 0005/1006] Update README for polymer-element --- README.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index af79051b0..492005acd 100644 --- a/README.md +++ b/README.md @@ -31,25 +31,25 @@ app.html: ```html - + - - + + ``` x-dep.html: ```html - + - + ``` Running vulcan on `index.html`, and specifying `build.html` as the output: @@ -59,22 +59,22 @@ Running vulcan on `index.html`, and specifying `build.html` as the output: Will result in `build.html` that appears as so: ```html - + - - + + - + ``` To use this, make `build.html` the only import in `index.html`: From ec2fff7d9700e1295bb753fc3f814c11d41c1e42 Mon Sep 17 00:00:00 2001 From: "Scott J. Miles" Date: Tue, 23 Jul 2013 00:02:39 -0700 Subject: [PATCH 0006/1006] breaking down doc tool for analysis --- viz.html | 180 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 viz.html diff --git a/viz.html b/viz.html new file mode 100644 index 000000000..f406bea7c --- /dev/null +++ b/viz.html @@ -0,0 +1,180 @@ + + + + + + + + +
+
+
x-message.shadowRoot.x-decorate.shadowRoot + +
+
+
+
+
+      <x-turbin></x-turbin>
+        <x-filigree>
+          <content>           </content>
+        </x-filigree>
+      <x-clogs></x-clogs>
+
+
+
+
+ +
+
x-message.shadowRoot.x-decorate + +
+
+
+  <x-decorate>
+    <content>
+
+
+                   
+
+
+    </content>
+  </x-decorate>
+
+ +
+
x-message + +
+
+<x-message>
+
+
+
+
+                   Hello World
+
+
+
+
+</x-message>
+ +
+
+
+ Drag to rotate, then or +
+
+
+
+ + + + From a2fbec807942321f549d8ebaa245296b72e7f1ef Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Wed, 31 Jul 2013 15:58:26 -0700 Subject: [PATCH 0007/1006] Process imports as whole files, no element extraction --- vulcan.js | 44 ++++++++++++++++++-------------------------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/vulcan.js b/vulcan.js index eda3929ae..76ace1c03 100644 --- a/vulcan.js +++ b/vulcan.js @@ -36,18 +36,8 @@ var ABS_URL = /(^data:)|(^http[s]?:)|(^\/)/; var URL = /url\([^)]*\)/g; var URL_TEMPLATE = '{{.*}}'; -function concatElement(dir, output, e) { - e = resolveElementPaths(dir, output, e); - buffer.push(e); -} - -function resolveElementPaths(input, output, element) { - var $ = cheerio.load(element); - resolvePaths(input, output, $); - return $.html(ELEMENTS); -} - -function resolvePaths(input, output, $) { +function resolvePaths($, input, output) { + var assetPath = path.relative(output, input); // resolve attributes $(URL_ATTR_SEL).each(function() { var val; @@ -68,6 +58,9 @@ function resolvePaths(input, output, $) { var val = this.html(); this.html(rewriteURL(input, output, val)); }); + $(ELEMENTS).each(function() { + this.attr('assetpath', assetPath); + }); } function rewriteRelPath(inputPath, outputPath, rel) { @@ -99,20 +92,15 @@ function extractImports($, dir) { return hrefs.map(function(h) { return path.resolve(dir, h) }); } -function extractElements($, assetPath) { - return $(ELEMENTS).map(function(i, e){ this.attr('assetpath', assetPath); return $.html(e) }); -} - function concat(filename) { if (!read[filename]) { read[filename] = true; var $ = readDocument(filename); var dir = path.dirname(filename); - var assetPath = path.relative(outputDir, dir); - var links = extractImports($, dir); - resolve(filename, links); - var es = extractElements($, assetPath); - es.forEach(concatElement.bind(this, dir, outputDir)); + processImports(extractImports($, dir)); + $(IMPORTS).remove(); + resolvePaths($, dir, outputDir); + buffer.push($.html()); } else { if (options.verbose) { console.log('Dependency deduplicated'); @@ -120,12 +108,12 @@ function concat(filename) { } } -function resolve(inName, inDependencies) { - if (inDependencies.length > 0) { +function processImports(imports) { + if (imports.length > 0) { if (options.verbose) { - console.log('Dependencies:', inDependencies); + console.log('Dependencies:', imports); } - inDependencies.forEach(concat); + imports.forEach(concat); } } @@ -153,7 +141,11 @@ var buffer = [ ]; var read = {}; -options.input.forEach(concat); +options.input.forEach(function(i) { + var $ = readDocument(i); + var dir = path.dirname(i); + processImports(extractImports($, dir)); +}); if (buffer.length) { fs.writeFileSync(options.output, buffer.join('\n'), 'utf8'); From a9c94f2c51f5b7f4a41291fba7869c7589f0fa44 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Wed, 31 Jul 2013 16:26:27 -0700 Subject: [PATCH 0008/1006] For CSP, allow an option to separate scripts into a separate file --- .gitignore | 1 + vulcan.js | 37 +++++++++++++++++++++++++++++-------- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index ad96abfab..3e62ded98 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ output.html +output.js node_modules diff --git a/vulcan.js b/vulcan.js index 76ace1c03..6a073a2a2 100644 --- a/vulcan.js +++ b/vulcan.js @@ -7,7 +7,8 @@ var options = nopt( { 'output': path, 'input': [path, Array], - 'verbose': Boolean + 'verbose': Boolean, + 'csp': Boolean }, { 'o': ['--output'], @@ -22,7 +23,7 @@ if (!options.input) { } if (!options.output) { - console.warn('Default output to output.html'); + console.warn('Default output to output.html' + (options.csp ? ' and output.js' : '')); options.output = path.resolve('output.html'); } @@ -117,8 +118,8 @@ function processImports(imports) { } } -// monkey patch addResolvePath for build var monkeyPatch = function(proto, element) { + // monkey patch addResolvePath to use assetpath attribute var assetPath = element.getAttribute('assetpath'); var url = HTMLImports.getDocumentUrl(element.ownerDocument) || ''; if (url) { @@ -132,12 +133,11 @@ var monkeyPatch = function(proto, element) { } proto.resolvePath = function(path) { return url + path; - } + }; }; var buffer = [ - '', - '' + '' ]; var read = {}; @@ -147,6 +147,27 @@ options.input.forEach(function(i) { processImports(extractImports($, dir)); }); -if (buffer.length) { - fs.writeFileSync(options.output, buffer.join('\n'), 'utf8'); +var output = buffer.join('\n'); + +// strip scripts into a separate file +if (options.csp) { + if (options.verbose) { + console.log('Separating scripts into separate file'); + } + var scripts = []; + var $ = cheerio.load(output); + $('script').each(function() { + var src; + if (src = this.attr('src')) { + // external script + scripts.push(fs.readFileSync(src, 'utf8')); + } else { + // inline script + scripts.push(this.text()); + } + }).remove(); + output = $.html(); + fs.writeFileSync(options.output.replace('html', 'js'), scripts.join('\n'), 'utf8'); } + +fs.writeFileSync(options.output, output, 'utf8'); From d0485263bd17d4e589814d7421d1e1b7ab7e415e Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Thu, 1 Aug 2013 10:29:13 -0700 Subject: [PATCH 0009/1006] update README for CSP mode --- README.md | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 492005acd..9e67bc087 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,9 @@ materials. ## Getting Started - Install the node dependencies with `npm install` - Depends on [cheerio](https://github.com/MatthewMueller/cheerio) and [nopt](https://github.com/isaacs/nopt) -- Give some input html files with the `--input` or `-i` flags - - Input html should have `` tags -- Specify an output html file with `--output` or `-o` - - Defaults to `output.html` in the current directory +- Give some input html files with the `--input` or `-i` flags and output file name with the `--output` or `-o` flags. + - Example: `node vulcan.js -i index.html -o build.html` + - Defaults to `output.html` - URL paths are adjusted for the new output location automatically (execpt ones set in Javascript) - Once finished, link the final output html into your app page with ``. @@ -84,3 +83,32 @@ To use this, make `build.html` the only import in `index.html`: ``` + +## Content Security Policy +[Content Security Policy](http://en.wikipedia.org/wiki/Content_Security_Policy), or CSP, is a Javascript security model +that aims to prevent XSS and other attacks. In so doing, it prohibits the use of inline scripts. + +To help automate the use of Polymer element registration with CSP, the `--csp` flag to vulcan will remove all scripts +from the HTML Imports and place their contents into an output javascript file. + +Using the previous example, the output from `node vulcan -i index.html -o build.html` will be + +build.html: +```html + + + + + + +``` + +build.js: +```js +Polymer('x-dep'); +Polymer('x-app'); +``` From ba536e513504bdfa103dfbc678911421593f5e5a Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Tue, 6 Aug 2013 14:28:50 -0700 Subject: [PATCH 0010/1006] add a semicolon to all scripts to prevent weird insertion conditions --- vulcan.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vulcan.js b/vulcan.js index 6a073a2a2..bfdfff2a2 100644 --- a/vulcan.js +++ b/vulcan.js @@ -167,7 +167,8 @@ if (options.csp) { } }).remove(); output = $.html(); - fs.writeFileSync(options.output.replace('html', 'js'), scripts.join('\n'), 'utf8'); + // join scripts with ';' to prevent breakages due to EOF semicolon insertion + fs.writeFileSync(options.output.replace('html', 'js'), scripts.join(';\n'), 'utf8'); } fs.writeFileSync(options.output, output, 'utf8'); From b0590ec4e8d182bfaa609738be8102fa5a970eab Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Tue, 6 Aug 2013 17:28:01 -0700 Subject: [PATCH 0011/1006] vulcanizer will now take in a single main document and produce a built version of that main document. - Absolutely referenced script and imports will be moved into the built document, retaining load order - Absolute imports will be referenced before the vulcanized import - The absolute & vulcanized imports will be placed before the polymer script, both minimized and debug are supported. - CSP mode - Absolute scripts will be referenced before the vulcanized script - The absolule and vulcanized scripts will be placed after the polymer script --- .gitignore | 5 +- test/import-test.html | 9 +++ test/index.html | 13 ++++ vulcan.js | 146 +++++++++++++++++++++++------------------- 4 files changed, 104 insertions(+), 69 deletions(-) create mode 100644 test/import-test.html create mode 100644 test/index.html diff --git a/.gitignore b/.gitignore index 3e62ded98..9b1dab5f3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ -output.html -output.js +test/vulcanized.html +test/vulcanized.js +test/index-vulcanized.html node_modules diff --git a/test/import-test.html b/test/import-test.html new file mode 100644 index 000000000..9a8223c87 --- /dev/null +++ b/test/import-test.html @@ -0,0 +1,9 @@ + + + + + diff --git a/test/index.html b/test/index.html new file mode 100644 index 000000000..74bb3bdbc --- /dev/null +++ b/test/index.html @@ -0,0 +1,13 @@ + + + + + Vulcanizer Test + + + + + Hello Import! + + + diff --git a/vulcan.js b/vulcan.js index bfdfff2a2..421f465e6 100644 --- a/vulcan.js +++ b/vulcan.js @@ -6,7 +6,7 @@ var nopt = require('nopt'); var options = nopt( { 'output': path, - 'input': [path, Array], + 'input': path, 'verbose': Boolean, 'csp': Boolean }, @@ -18,13 +18,14 @@ var options = nopt( ); if (!options.input) { - console.error('No input files given'); + console.error('No input file given!'); process.exit(1); } +var DEFAULT_OUTPUT = 'vulcanized.html'; if (!options.output) { - console.warn('Default output to output.html' + (options.csp ? ' and output.js' : '')); - options.output = path.resolve('output.html'); + console.warn('Default output to index-vulcanized.html,' + (options.csp ? ', vulcanized.js,' : '') + ' and vulcanized.html in the input directory.'); + options.output = path.resolve(path.dirname(options.input), DEFAULT_OUTPUT); } var outputDir = path.dirname(options.output); @@ -36,6 +37,31 @@ var URL_ATTR_SEL = '[' + URL_ATTR.join('],[') + ']'; var ABS_URL = /(^data:)|(^http[s]?:)|(^\/)/; var URL = /url\([^)]*\)/g; var URL_TEMPLATE = '{{.*}}'; +var POLYMER = 'script[src $= "polymer.js"], script[src $= "polymer.min.js"]'; +var MONKEYPATCH_RESOLVEPATH = function(proto, element) { + // monkey patch addResolvePath to use assetpath attribute + var assetPath = element.getAttribute('assetpath'); + var url = HTMLImports.getDocumentUrl(element.ownerDocument) || ''; + if (url) { + var parts = url.split('/'); + parts.pop(); + if (assetPath) { + parts.push(assetPath); + } + parts.push(''); + url = parts.join('/'); + } + proto.resolvePath = function(path) { + return url + path; + }; +}; + +var import_buffer = [ + '' +]; +var imports_before_polymer = []; +var read = {}; + function resolvePaths($, input, output) { var assetPath = path.relative(output, input); @@ -88,20 +114,14 @@ function readDocument(docname) { return cheerio.load(content); } -function extractImports($, dir) { - var hrefs = $(IMPORTS).map(function(){ return this.attr('href') }); - return hrefs.map(function(h) { return path.resolve(dir, h) }); -} - function concat(filename) { if (!read[filename]) { read[filename] = true; var $ = readDocument(filename); var dir = path.dirname(filename); - processImports(extractImports($, dir)); - $(IMPORTS).remove(); + processImports($, dir); resolvePaths($, dir, outputDir); - buffer.push($.html()); + import_buffer.push($.html()); } else { if (options.verbose) { console.log('Dependency deduplicated'); @@ -109,66 +129,58 @@ function concat(filename) { } } -function processImports(imports) { - if (imports.length > 0) { - if (options.verbose) { - console.log('Dependencies:', imports); +function processImports($, prefix) { + $(IMPORTS).each(function() { + var href = this.attr('href'); + if (!ABS_URL.test(href)) { + concat(path.resolve(prefix, href)); + } else { + imports_before_polymer.push(this.html()); } - imports.forEach(concat); - } + }).remove(); } -var monkeyPatch = function(proto, element) { - // monkey patch addResolvePath to use assetpath attribute - var assetPath = element.getAttribute('assetpath'); - var url = HTMLImports.getDocumentUrl(element.ownerDocument) || ''; - if (url) { - var parts = url.split('/'); - parts.pop(); - if (assetPath) { - parts.push(assetPath); +function handleMainDocument() { + var $ = readDocument(options.input); + var dir = path.dirname(options.input); + processImports($, dir); + var output = import_buffer.join('\n'); + + // strip scripts into a separate file + if (options.csp) { + if (options.verbose) { + console.log('Separating scripts into separate file'); } - parts.push(''); - url = parts.join('/'); + var scripts = []; + var scripts_after_polymer = []; + var output = cheerio.load(output); + output('script').each(function() { + var src; + if (src = this.attr('src')) { + // external script + if (!ABS_URL.test(src)) { + scripts.push(fs.readFileSync(src, 'utf8')); + } else { + // put an absolute path script after polymer.js in main document + scripts_after_polymer.push(this.html()); + } + } else { + // inline script + scripts.push(this.text()); + } + }).remove(); + output = output.html(); + // join scripts with ';' to prevent breakages due to EOF semicolon insertion + var script_name = path.relative(outputDir, options.output.replace('html', 'js')); + fs.writeFileSync(script_name, scripts.join(';\n'), 'utf8'); + scripts_after_polymer.push(''); + $(POLYMER).first().after(scripts_after_polymer.join('\n')); } - proto.resolvePath = function(path) { - return url + path; - }; -}; - -var buffer = [ - '' -]; -var read = {}; - -options.input.forEach(function(i) { - var $ = readDocument(i); - var dir = path.dirname(i); - processImports(extractImports($, dir)); -}); -var output = buffer.join('\n'); - -// strip scripts into a separate file -if (options.csp) { - if (options.verbose) { - console.log('Separating scripts into separate file'); - } - var scripts = []; - var $ = cheerio.load(output); - $('script').each(function() { - var src; - if (src = this.attr('src')) { - // external script - scripts.push(fs.readFileSync(src, 'utf8')); - } else { - // inline script - scripts.push(this.text()); - } - }).remove(); - output = $.html(); - // join scripts with ';' to prevent breakages due to EOF semicolon insertion - fs.writeFileSync(options.output.replace('html', 'js'), scripts.join(';\n'), 'utf8'); + fs.writeFileSync(options.output, output, 'utf8'); + imports_before_polymer.push(''); + $(POLYMER).first().before(imports_before_polymer.join('\n')); + fs.writeFileSync(path.resolve(outputDir, 'index-vulcanized.html'), $.html(), 'utf8'); } -fs.writeFileSync(options.output, output, 'utf8'); +handleMainDocument(); From b5f793be9f4d2fc334de5ded37c2bd43d41595dd Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Wed, 7 Aug 2013 10:36:44 -0700 Subject: [PATCH 0012/1006] reflect new functionality in README, fix up newline issues, refactor constants --- README.md | 5 ++-- test/import-test.html | 1 - test/index.html | 1 - vulcan.js | 63 +++++++++++++++++++++---------------------- 4 files changed, 34 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 9e67bc087..e4a979512 100644 --- a/README.md +++ b/README.md @@ -8,11 +8,12 @@ materials. ## Getting Started - Install the node dependencies with `npm install` - Depends on [cheerio](https://github.com/MatthewMueller/cheerio) and [nopt](https://github.com/isaacs/nopt) -- Give some input html files with the `--input` or `-i` flags and output file name with the `--output` or `-o` flags. +- Give a main input html file with the `--input` or `-i` flags and output file name with the `--output` or `-o` flags. - Example: `node vulcan.js -i index.html -o build.html` - Defaults to `output.html` - URL paths are adjusted for the new output location automatically (execpt ones set in Javascript) -- Once finished, link the final output html into your app page with ``. +- When finished, `index-vulcanized.js` will be placed in the output location + with the vulcanized imports and scripts included. ## Example diff --git a/test/import-test.html b/test/import-test.html index 9a8223c87..43b6611a4 100644 --- a/test/import-test.html +++ b/test/import-test.html @@ -1,4 +1,3 @@ - + + + + + + + diff --git a/test/test.js b/test/test.js index 43a950344..12135c67a 100644 --- a/test/test.js +++ b/test/test.js @@ -484,6 +484,20 @@ suite('Vulcan', function() { }); }); + test('comment removal', function(done) { + var options = {input: 'test/html/comments.html', output: outputPath, strip: true}; + process(options, function(outputs) { + var vulcanized = outputs[outputPath]; + assert(vulcanized); + assert.equal(vulcanized.indexOf('comment 1'), -1, 'comment in body removed'); + assert.equal(vulcanized.indexOf('comment 2'), -1, 'comment in template removed'); + assert.equal(vulcanized.indexOf('comment 3'), -1, 'comment in style in template removed'); + assert.equal(vulcanized.indexOf('comment 4'), -1, 'comment in polymer-element removed'); + assert.equal(vulcanized.indexOf('comment 5'), -1, 'comment in script removed'); + done(); + }); + }); + }); test('Multiple Polymer Invocations', function(done) { From 3773178f28c5fbb92d740e7e14a56c15fc86f1c4 Mon Sep 17 00:00:00 2001 From: Trevor Dixon Date: Wed, 10 Dec 2014 12:59:50 -0800 Subject: [PATCH 0193/1006] Test that license comment at top of file is removed. --- test/test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/test.js b/test/test.js index 12135c67a..f0be88023 100644 --- a/test/test.js +++ b/test/test.js @@ -489,6 +489,7 @@ suite('Vulcan', function() { process(options, function(outputs) { var vulcanized = outputs[outputPath]; assert(vulcanized); + assert.equal(vulcanized.indexOf('@license'), -1, 'license comment at top removed'); assert.equal(vulcanized.indexOf('comment 1'), -1, 'comment in body removed'); assert.equal(vulcanized.indexOf('comment 2'), -1, 'comment in template removed'); assert.equal(vulcanized.indexOf('comment 3'), -1, 'comment in style in template removed'); From 1ac0b16fe3e98c19fca632a2b8aafbe0dfbb6f6b Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Thu, 11 Dec 2014 15:06:00 -0800 Subject: [PATCH 0194/1006] add version bump notes --- CHANGELOG | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index c8b0232de..854f0fcbc 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +### 0.7.2 +- Disable css number rounding for crazy-sad flexbox hacks in IE 10 +- Add charset=utf-8 to all scripts +- Better comment removal codepath ### 0.7.1 - Support for mobile URL Schemes "tel:" and "sms:" - Better reporting of javascript error messages with `--strip` From 0e13ffb43e942e9d3cb5c4be18954a7e42abb143 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Thu, 11 Dec 2014 15:06:31 -0800 Subject: [PATCH 0195/1006] 0.7.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 89c066d87..c6ae43653 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vulcanize", - "version": "0.7.1", + "version": "0.7.2", "description": "Process Web Components into one output file", "main": "lib/vulcan.js", "bin": { From 2423e7117b9ddf2619eaf5a2ede888cae3378c2c Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Tue, 16 Dec 2014 11:03:49 -0800 Subject: [PATCH 0196/1006] Replace clean-css with cssom Third strike, and clean-css is out (polyfill-next-selector!) --- lib/vulcan.js | 5 +++-- package.json | 2 +- test/test.js | 27 ++++++++++++++++++++------- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/lib/vulcan.js b/lib/vulcan.js index 527b53f1e..14d275821 100644 --- a/lib/vulcan.js +++ b/lib/vulcan.js @@ -10,7 +10,7 @@ // jshint node: true -var cleancss = require('clean-css'); +var cssom = require('cssom'); var fs = require('fs'); var path = require('path'); var uglify = require('uglify-js'); @@ -215,7 +215,8 @@ function removeCommentsAndWhitespace($) { } } else if (node.type == 'style') { content = getTextContent(node); - setTextContent(node, new cleancss({advanced: false, aggressiveMerging: false, roundingPrecision: 10}).minify(content)); + var ast = cssom.parse(content); + setTextContent(node, ast.toString().replace(/[\r\n]/g, '')); } else if ((c = node.children)) { for (var i = 0; i < c.length; i++) { // since .remove() will modify this array, decrement `i` on successful comment removal diff --git a/package.json b/package.json index c6ae43653..50274611f 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "vulcanize": "bin/vulcanize" }, "dependencies": { - "clean-css": "^2.2.11", + "cssom": "^0.2.3", "nopt": "^3.0.1", "uglify-js": "^2.4.15", "whacko": "0.17.2" diff --git a/test/test.js b/test/test.js index f0be88023..e14532ace 100644 --- a/test/test.js +++ b/test/test.js @@ -461,7 +461,7 @@ suite('Vulcan', function() { suite('Strip', function() { - test('uglify', function(done) { + test('script', function(done) { var options = {input: 'test/html/broken-js.html', strip: true}; vulcan.setOptions(options, function(err) { assert.ifError(err); @@ -475,12 +475,25 @@ suite('Vulcan', function() { }); }); - test('cleancss', function(done) { - process({inputSrc: '', output: outputPath, strip: true}, function(outputs) { - var vulcanized = outputs[outputPath]; - assert(vulcanized); - assert(vulcanized.indexOf('.0000000001px') > -1, 'precision is correct'); - done(); + suite('css', function() { + + test('precsision', function(done) { + process({inputSrc: '', output: outputPath, strip: true}, function(outputs) { + var vulcanized = outputs[outputPath]; + assert(vulcanized); + assert(vulcanized.indexOf('.0000000001px') > -1, 'precision is correct'); + done(); + }); + }); + + test('polyfill-next-selector', function(done) { + process({inputSrc: '', output: outputPath, strip: true}, function(outputs) { + var vulcanized = outputs[outputPath]; + assert(vulcanized); + console.log(vulcanized); + assert(vulcanized.indexOf('', output: outputPath, strip: true}, function(outputs) { var vulcanized = outputs[outputPath]; assert(vulcanized); - console.log(vulcanized); assert(vulcanized.indexOf(''; + process({inputSrc: input, output: outputPath, strip: true}, function(outputs) { + var vulcanized = outputs[outputPath]; + assert(vulcanized); + assert(vulcanized.indexOf(input.replace(/[\r\n]/g, '')) > -1, 'newlines removed at least'); + done(); + }); + }); }); test('comment removal', function(done) { From 6fa4c8d401937313138c1b9ee91316fce96e43a1 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Tue, 16 Dec 2014 15:33:19 -0800 Subject: [PATCH 0200/1006] 0.7.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f40d83eaf..336a2dff5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vulcanize", - "version": "0.7.3", + "version": "0.7.4", "description": "Process Web Components into one output file", "main": "lib/vulcan.js", "bin": { From 0fec0042d0e9b9599cb918b1803c742bf365880e Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Fri, 19 Dec 2014 15:37:00 -0800 Subject: [PATCH 0201/1006] Drop cssom due to removing fallback cases All of the available css parsers are either too cumbersome to use (css), or make bad assumptions (cssom, clean-css) Just use some simple regexes to remove extra whitespace and css comments Fixes #122 vulcanize 0.7.4 strip option break flex definition in layout.html file --- lib/vulcan.js | 21 +++++++-------------- package.json | 1 - test/test.js | 12 ++++++++++++ 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/lib/vulcan.js b/lib/vulcan.js index 0d7e230ad..82c396925 100644 --- a/lib/vulcan.js +++ b/lib/vulcan.js @@ -10,7 +10,6 @@ // jshint node: true -var cssom = require('cssom'); var fs = require('fs'); var path = require('path'); var uglify = require('uglify-js'); @@ -200,19 +199,13 @@ function compressJS(content, inline) { } function compressCSS(content) { - var out; - try { - var ast = cssom.parse(content); - out = ast.toString(); - } catch (e) { - if (options.verbose) { - console.log('Error parsing CSS:', e.toString()); - console.log('Falling back to removing newlines only'); - } - out = content; - } finally { - return out.replace(/[\r\n]/g, ''); - } + // remove newlines + var out = content.replace(/[\r\n]/g, ''); + // remove css comments (/* ... */) + out = out.replace(/\/\*(.+?)\*\//g, ''); + // remove duplicate whitespace + out = out.replace(/\s{2,}/g, ' '); + return out; } function removeCommentsAndWhitespace($) { diff --git a/package.json b/package.json index 336a2dff5..af8c1b4ed 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,6 @@ "vulcanize": "bin/vulcanize" }, "dependencies": { - "cssom": "^0.2.3", "nopt": "^3.0.1", "uglify-js": "^2.4.15", "whacko": "0.17.2" diff --git a/test/test.js b/test/test.js index 60c011de2..4e8a3832b 100644 --- a/test/test.js +++ b/test/test.js @@ -500,6 +500,7 @@ suite('Vulcan', function() { process({inputSrc: input, output: outputPath, strip: true}, function(outputs) { var vulcanized = outputs[outputPath]; assert(vulcanized); + assert(vulcanized.indexOf('{{ foo }}') > -1, 'braces kept'); assert(vulcanized.indexOf(input.replace(/[\r\n]/g, '')) > -1, 'newlines removed at least'); done(); }); @@ -521,6 +522,17 @@ suite('Vulcan', function() { }); }); + test('keep fallback declarations', function(done) { + var options = {inputSrc: '', output: outputPath, strip: true}; + process(options, function(outputs) { + var vulcanized = outputs[outputPath]; + assert(vulcanized); + assert(vulcanized.indexOf('display: flex') > -1, 'keep flex'); + assert(vulcanized.indexOf('display: -webkit-flex') > -1, 'keep -webkit-flex'); + done(); + }); + }); + }); test('Multiple Polymer Invocations', function(done) { From fadf0429f2e6ee191907ed47d5a4b9396b4f2114 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Fri, 19 Dec 2014 15:40:36 -0800 Subject: [PATCH 0202/1006] 0.7.5 --- CHANGELOG | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 7b4da84d7..b1b8d99ba 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,5 @@ +### 0.7.5 +- Remove cssom, just use regexes ### 0.7.4 - Workaround for cssom not liking '{{ }}' bindings in ', + '', + '', + '' + ].join('\n'); + + var expectedBase = [ + '', + '', + '', + '', + '' + ].join('\n'); + var actual; var whacko = require('whacko'); var $ = whacko.load(html); @@ -167,6 +190,13 @@ suite('Path Resolver', function() { actual = $.html(); assert.equal(actual, expected2, 'absolute'); + + $ = whacko.load(htmlBase); + + pathresolver.resolvePaths($, inputPath, outputPath); + + actual = $.html(); + // assert.equal(actual, expectedBase, 'base'); }); }); @@ -552,4 +582,18 @@ suite('Vulcan', function() { }); }); + test('Handle tag', function(done) { + var options = {input: 'test/html/base.html', output: outputPath}; + process(options, function(outputs) { + var vulcanized = outputs[outputPath]; + assert(vulcanized); + var $ = require('whacko').load(vulcanized); + var spanHref = $('span').attr('href'); + assert.equal('imports/hello', spanHref, ' accounted for'); + var divHref = $('a').attr('href'); + assert.equal('imports/sub-base/sub-base.html', divHref); + done(); + }); + }); + }); From 5f7ac0c29de731a456f271268c92c21ca288531d Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Mon, 26 Jan 2015 12:36:49 -0800 Subject: [PATCH 0206/1006] Respect in CSS url rewrite as well Fix tests Related #94 --- lib/pathresolver.js | 32 ++++++++++++++++++++++---------- test/test.js | 11 ++++++----- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/lib/pathresolver.js b/lib/pathresolver.js index 8e58bfa0a..3d77e3bac 100644 --- a/lib/pathresolver.js +++ b/lib/pathresolver.js @@ -19,26 +19,33 @@ var getTextContent = utils.getTextContent; var searchAll = utils.searchAll; function resolvePaths($, input, output, abspath) { + // honor tag + var baseEl = $('base'); + var baseUrl = ""; + + if (baseEl.length) { + var baseHref = baseEl.attr('href'); + if (baseHref) { + baseUrl = baseHref + '/'; + } + baseEl.remove(); + } + var assetPath; if (abspath) { assetPath = rebasePath(input, abspath); } else { assetPath = path.relative(output, input); } + // make sure assetpath is a folder, but not root! if (assetPath) { assetPath = utils.unixPath(assetPath) + '/'; } - // honor tag - var baseEl = $('base'); - var baseUrl = ""; - if (baseEl.length) { - var baseHref = baseEl.attr('href'); - if (baseHref) { - baseUrl = baseHref + '/'; - } - baseEl.remove(); + if (baseUrl) { + // assetPath is backwards; the URL resolution is assetPath + baseUrl + input + assetPath = url.resolve(assetPath, baseUrl); } // resolve attributes @@ -60,7 +67,12 @@ function resolvePaths($, input, output, abspath) { }); searchAll($, constants.CSS).each(function() { var el = $(this); - var text = rewriteURL(input, output, getTextContent(el), abspath); + var text = getTextContent(el); + if (baseUrl) { + // baseHref should be added to input path + input = url.resolve(input + '/', baseHref); + } + text = rewriteURL(input, output, text, abspath); setTextContent(el, text); }); searchAll($, constants.ELEMENTS).each(function() { diff --git a/test/test.js b/test/test.js index 458162749..1946728e2 100644 --- a/test/test.js +++ b/test/test.js @@ -165,11 +165,12 @@ suite('Path Resolver', function() { ].join('\n'); var expectedBase = [ - '', - '', - '', + '', + '', + '', + '', '', '' @@ -196,7 +197,7 @@ suite('Path Resolver', function() { pathresolver.resolvePaths($, inputPath, outputPath); actual = $.html(); - // assert.equal(actual, expectedBase, 'base'); + assert.equal(actual, expectedBase, 'base'); }); }); From dd69e98f79260b59a658490c52228e9829a5763c Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Mon, 26 Jan 2015 16:24:58 -0800 Subject: [PATCH 0207/1006] Ignore non-critical files from npm --- .npmignore | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .npmignore diff --git a/.npmignore b/.npmignore new file mode 100644 index 000000000..4bbc63a70 --- /dev/null +++ b/.npmignore @@ -0,0 +1,8 @@ +node_modules + + +# npmignore +example +CHANGELOG +util +test \ No newline at end of file From 6cb74c2b90520ffadb55063ff6113767459b0d5a Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Mon, 26 Jan 2015 16:48:48 -0800 Subject: [PATCH 0208/1006] Better URL rewriting detection for schema urls Addresses https://github.com/Polymer/vulcanize/issues/44#issuecomment-71427558 --- lib/constants.js | 4 ++-- test/test.js | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/constants.js b/lib/constants.js index 8812df9d2..cef9858ca 100644 --- a/lib/constants.js +++ b/lib/constants.js @@ -15,8 +15,8 @@ module.exports = { EOL: require('os').EOL, ELEMENTS: 'polymer-element:not([assetpath])', ELEMENTS_NOSCRIPT: 'polymer-element[noscript]', - ABS_URL: /(^data:)|(^http[s]?:)|(^\/)|(^mailto:)|(^tel:)|(^sms:)|(^#)/, - REMOTE_ABS_URL: /(^http[s]?\:)|(^\/\/)/, + ABS_URL: /(^\/)|(^#)|(^\w*:)/, + REMOTE_ABS_URL: /(^http[s]?:)|(^\/\/)/, IMPORTS: 'link[rel="import"][href]', URL: /url\([^)]*\)/g, URL_ATTR: URL_ATTR, diff --git a/test/test.js b/test/test.js index 1946728e2..5d2dcb3f8 100644 --- a/test/test.js +++ b/test/test.js @@ -26,6 +26,9 @@ suite('constants', function() { assert(abs.test('https://foo.com'), 'https'); assert(abs.test('mailto:foo@bar.com'), 'mailto'); assert(abs.test('tel:+49123123456'), 'phonecall'); + // jshint -W107 + assert(abs.test('javascript:;'), 'javascript'); + // jshint +W107 assert(abs.test('sms:1-123-123456'), 'sms'); assert(abs.test('//foo.com'), 'protocol-free'); assert(abs.test('/components/'), '/'); From 4bf3e46907ab3531f9b7788be862c1cc5a4bc235 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Tue, 27 Jan 2015 14:10:46 -0800 Subject: [PATCH 0209/1006] Support more schemas, with dashes and numbers --- lib/constants.js | 2 +- test/test.js | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/constants.js b/lib/constants.js index cef9858ca..05b59e72d 100644 --- a/lib/constants.js +++ b/lib/constants.js @@ -15,7 +15,7 @@ module.exports = { EOL: require('os').EOL, ELEMENTS: 'polymer-element:not([assetpath])', ELEMENTS_NOSCRIPT: 'polymer-element[noscript]', - ABS_URL: /(^\/)|(^#)|(^\w*:)/, + ABS_URL: /(^\/)|(^#)|(^[\w-\d]*:)/, REMOTE_ABS_URL: /(^http[s]?:)|(^\/\/)/, IMPORTS: 'link[rel="import"][href]', URL: /url\([^)]*\)/g, diff --git a/test/test.js b/test/test.js index 5d2dcb3f8..6fd201239 100644 --- a/test/test.js +++ b/test/test.js @@ -30,6 +30,10 @@ suite('constants', function() { assert(abs.test('javascript:;'), 'javascript'); // jshint +W107 assert(abs.test('sms:1-123-123456'), 'sms'); + assert(abs.test('chrome-search:'), 'chrome search'); + assert(abs.test('about:blank'), 'about'); + assert(abs.test('wss://'), 'web socket'); + assert(abs.test('b2:'), 'custom protocol'); assert(abs.test('//foo.com'), 'protocol-free'); assert(abs.test('/components/'), '/'); assert(abs.test('#foo'), 'hash url'); From f77ee429eca023dded94f8cf347bd554bf86b4c1 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Tue, 27 Jan 2015 17:45:42 -0800 Subject: [PATCH 0210/1006] update-notifier 0.3, use new api --- bin/vulcanize | 3 +-- package.json | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/bin/vulcanize b/bin/vulcanize index 73fcc4c96..44dcceb1b 100755 --- a/bin/vulcanize +++ b/bin/vulcanize @@ -89,8 +89,7 @@ if (options['update-notifier'] !== false) { (function() { try { require('update-notifier')({ - packageName: pkg.name, - packageVersion: pkg.version + pkg: pkg }).notify(); } catch(_) {} })(); diff --git a/package.json b/package.json index ea1a62360..348d78076 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,6 @@ "url": "https://github.com/Polymer/vulcanize/issues" }, "optionalDependencies": { - "update-notifier": "^0.2.2" + "update-notifier": "^0.3.0" } } From b12ba8084f96b3211a003ffdd523bd911673ffe8 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Mon, 2 Feb 2015 17:40:56 -0800 Subject: [PATCH 0211/1006] v0.7.7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 348d78076..fa0d70789 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vulcanize", - "version": "0.7.6", + "version": "0.7.7", "description": "Process Web Components into one output file", "main": "lib/vulcan.js", "bin": { From 1de0c21d9f0e7344518fc7341e83fa9372ea8bad Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Thu, 5 Feb 2015 11:18:20 -0800 Subject: [PATCH 0212/1006] Use whacko 0.17.3 Fixes #127 Form closing tag is moved to the end of the template --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fa0d70789..a3d0b2af7 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "dependencies": { "nopt": "^3.0.1", "uglify-js": "^2.4.15", - "whacko": "0.17.2" + "whacko": "0.17.3" }, "devDependencies": { "jshint": "^2.5.6", From 806d5c37554345b6c5f2e9ec0dcb025cd299237e Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Thu, 5 Feb 2015 11:18:56 -0800 Subject: [PATCH 0213/1006] v0.7.8 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a3d0b2af7..b45673fb1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vulcanize", - "version": "0.7.7", + "version": "0.7.8", "description": "Process Web Components into one output file", "main": "lib/vulcan.js", "bin": { From 9af7f57b0bdfed72ef2e36ce570b3a8fdc3f6bf4 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Thu, 5 Feb 2015 14:44:20 -0800 Subject: [PATCH 0214/1006] Make explicit that excludes will strip urls by default Highlight how to disable strip-includes in config Fixes #130 Exclude option doesnt work as described in readme --- README.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3b42d23e0..95a584337 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,9 @@ vulcan.setOptions({inputSrc: input, outputHandler: outputHandler}, function(err) ## Config > JSON file for additional options -- Excludes: Remove the selected urls from the vulcanized bundle: +- Excludes: Remove the selected urls completely from the vulcanized bundle: + - Use the `--no-strip-excludes` command line flag, or set `"strip-excludes": false` + in the config to keep excluded urls in the output bundle. ### Example Config ```json @@ -107,6 +109,18 @@ vulcan.setOptions({inputSrc: input, outputHandler: outputHandler}, function(err) } ``` +### Keep excludes config +```json +{ + "excludes": { + "imports": [ + "regex-to-exclude" + ] + }, + "strip-excludes": false +} +``` + ## Example Usage Say we have three html files: `index.html`, `x-app.html`, and `x-dep.html`. From e20c0ce2c94ef658bc6a93fb566b3e71e3f6aa25 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Mon, 9 Feb 2015 12:19:57 -0800 Subject: [PATCH 0215/1006] Fix url resolution for inline styles Push bashUrl into rewriteRelPath, url resolving on all attributes will result in escaped values in style Fixes #133 Style display none being shown --- lib/pathresolver.js | 15 +++++++++------ test/test.js | 13 ++++++++----- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/lib/pathresolver.js b/lib/pathresolver.js index 3d77e3bac..a7d140bcf 100644 --- a/lib/pathresolver.js +++ b/lib/pathresolver.js @@ -55,11 +55,10 @@ function resolvePaths($, input, output, abspath) { var val = el.attr(a); if (val) { if (val.search(constants.URL_TEMPLATE) < 0) { - val = url.resolve(baseUrl, val); if (a === 'style') { - el.attr(a, rewriteURL(input, output, val, abspath)); + el.attr(a, rewriteURL(input, output, val, abspath, baseUrl)); } else { - el.attr(a, rewriteRelPath(input, output, val, abspath)); + el.attr(a, rewriteRelPath(input, output, val, abspath, baseUrl)); } } } @@ -85,11 +84,15 @@ function rebasePath(absolutePath, baselinePath) { return absolutePath.replace(absBase, ''); } -function rewriteRelPath(inputPath, outputPath, rel, abspath) { +function rewriteRelPath(inputPath, outputPath, rel, abspath, baseUrl) { if (constants.ABS_URL.test(rel)) { return rel; } + if (baseUrl) { + rel = url.resolve(baseUrl, rel); + } + var abs = path.resolve(inputPath, rel); if (abspath) { @@ -100,10 +103,10 @@ function rewriteRelPath(inputPath, outputPath, rel, abspath) { return utils.unixPath(relPath); } -function rewriteURL(inputPath, outputPath, cssText, abspath) { +function rewriteURL(inputPath, outputPath, cssText, abspath, baseUrl) { return cssText.replace(constants.URL, function(match) { var path = match.replace(/["']/g, "").slice(4, -1); - path = rewriteRelPath(inputPath, outputPath, path, abspath); + path = rewriteRelPath(inputPath, outputPath, path, abspath, baseUrl); return 'url("' + path + '")'; }); } diff --git a/test/test.js b/test/test.js index 6fd201239..95245e235 100644 --- a/test/test.js +++ b/test/test.js @@ -132,8 +132,9 @@ suite('Path Resolver', function() { '', '', + '', '' ].join('\n'); @@ -143,8 +144,9 @@ suite('Path Resolver', function() { '', '', + '', '' ].join('\n'); @@ -154,8 +156,9 @@ suite('Path Resolver', function() { '', '', + '', '' ].join('\n'); @@ -166,8 +169,8 @@ suite('Path Resolver', function() { '', '', + '', '' ].join('\n'); @@ -178,8 +181,8 @@ suite('Path Resolver', function() { '', '', + '', '' ].join('\n'); From 03b08a4e354d2a41d4fa47d856439b8681818742 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Mon, 9 Feb 2015 12:22:07 -0800 Subject: [PATCH 0216/1006] v0.7.9 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b45673fb1..c611400ac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vulcanize", - "version": "0.7.8", + "version": "0.7.9", "description": "Process Web Components into one output file", "main": "lib/vulcan.js", "bin": { From 6c0bcb112de74aae81cfb8480acd854c454d0e06 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Wed, 11 Feb 2015 15:29:36 -0800 Subject: [PATCH 0217/1006] Keep license comments Deduplicate between html and javascript in one consistent map Fixes #134 Keep License Headers --- lib/commentmap.js | 40 +++++++++++++++++++++++++++ lib/vulcan.js | 24 ++++++++++++++--- test/test.js | 69 ++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 128 insertions(+), 5 deletions(-) create mode 100644 lib/commentmap.js diff --git a/lib/commentmap.js b/lib/commentmap.js new file mode 100644 index 000000000..68831b332 --- /dev/null +++ b/lib/commentmap.js @@ -0,0 +1,40 @@ +/** + * @license + * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. + * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt + * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt + * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt + * Code distributed by Google as part of the polymer project is also + * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt + */ + +// jshint node: true + +function CommentMap() { + this.commentMap = Object.create(null); +} + +CommentMap.prototype = { + has: function(comment) { + var c = this.normalize(comment); + return !!this.commentMap[c]; + }, + set: function(comment) { + var c = this.normalize(comment); + this.commentMap[c] = 1; + }, + normalize: function (comment) { + var c = comment; + // remove leading slashes + c = c.replace(/^\/*/, ''); + // remove leading stars + c = c.replace(/^\s*[*]*/gm, ''); + // remove trailing stars and slash + c = c.replace(/[*]*\s*\/?$/, ''); + // remove all whitespace + c = c.replace(/\s/g, ''); + return c; + } +}; + +module.exports = CommentMap; diff --git a/lib/vulcan.js b/lib/vulcan.js index 82c396925..3d322c292 100644 --- a/lib/vulcan.js +++ b/lib/vulcan.js @@ -23,9 +23,11 @@ var utils = require('./utils'); var setTextContent = utils.setTextContent; var getTextContent = utils.getTextContent; var searchAll = utils.searchAll; +var CommentMap = require('./commentmap.js'); var read = {}; var options = {}; +var comments; // validate options with boolean return function setOptions(optHash, callback) { @@ -174,18 +176,31 @@ function findScriptLocation($) { } function isCommentOrEmptyTextNode(node) { - if (node.type === 'comment'){ - return true; + var d = node.data; + if (node.type === 'comment') { + var keep = (/@license/.test(d)); + if (keep && (keep = !comments.has(d))) { + comments.set(d); + } + return !keep; } else if (node.type === 'text') { // return true if the node is only whitespace - return !((/\S/).test(node.data)); + return !((/\S/).test(d)); } } function compressJS(content, inline) { + var keepComment = function(node, token) { + var d = token.value; + var keep = (/@license/.test(d)); + if (keep && (keep = !comments.has(d))) { + comments.set(d); + } + return keep; + }; try { var ast = uglify.parse(content); - return ast.print_to_string({inline_script: inline}); + return ast.print_to_string({inline_script: inline, comments: keepComment}); } catch (e) { // return a useful error var js_err = new Error('Compress JS Error'); @@ -250,6 +265,7 @@ function writeFileSync(filename, data, eop) { function handleMainDocument() { // reset shared buffers read = {}; + comments = new CommentMap(); var content = options.inputSrc ? options.inputSrc.toString() : readFile(options.input); var $ = whacko.load(content); var dir = path.dirname(options.input); diff --git a/test/test.js b/test/test.js index 95245e235..b29311d4b 100644 --- a/test/test.js +++ b/test/test.js @@ -79,6 +79,63 @@ suite('constants', function() { }); +suite('CommentMap', function() { + var CommentMap = require('../lib/commentmap.js'); + + suite('Normalize', function() { + test('whitespace', function() { + var c = new CommentMap(); + var s = [ + 'Hi', + 'There' + ].join('\n'); + var e = 'HiThere'; + + assert.equal(c.normalize(s), e); + }); + + test('single comment', function() { + var c = new CommentMap(); + var s = '// foo'; + var e = 'foo'; + + assert.equal(c.normalize(s), e); + }); + + test('multiline comment', function() { + var c = new CommentMap(); + var s = [ + '/**', + ' * foo', + ' */' + ].join('\n'); + var e = 'foo'; + + assert.equal(c.normalize(s), e); + }); + }); + + suite('Set and Has', function() { + + test('Plain', function() { + var c = new CommentMap(); + var s = 'Test'; + + c.set(s); + assert.ok(c.has(s)); + }); + + test('Strip Comments', function() { + var c = new CommentMap(); + var m = '/** foo */'; + c.set(m); + var s = '// foo'; + assert.ok(c.has(s)); + }); + + }); +}); + suite('Path Resolver', function() { var pathresolver = require('../lib/pathresolver.js'); var inputPath = '/foo/bar/my-element'; @@ -555,7 +612,7 @@ suite('Vulcan', function() { process(options, function(outputs) { var vulcanized = outputs[outputPath]; assert(vulcanized); - assert.equal(vulcanized.indexOf('@license'), -1, 'license comment at top removed'); + assert(vulcanized.indexOf('@license') > -1, 'license comment at top kept'); assert.equal(vulcanized.indexOf('comment 1'), -1, 'comment in body removed'); assert.equal(vulcanized.indexOf('comment 2'), -1, 'comment in template removed'); assert.equal(vulcanized.indexOf('comment 3'), -1, 'comment in style in template removed'); @@ -565,6 +622,16 @@ suite('Vulcan', function() { }); }); + test('License deduplicated', function(done) { + var options = {inputSrc: '', output: outputPath, strip: true}; + process(options, function(outputs) { + var vulcanized = outputs[outputPath]; + assert(vulcanized); + assert.equal(vulcanized.indexOf('foo'), vulcanized.lastIndexOf('foo')); + done(); + }); + }); + test('keep fallback declarations', function(done) { var options = {inputSrc: '', output: outputPath, strip: true}; process(options, function(outputs) { From 5e70af28f633c8881c64c14d839186df7fa1bf14 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Fri, 20 Feb 2015 12:41:00 -0800 Subject: [PATCH 0218/1006] Adapt to polymer 0.8 elements - Look for `` elements instead of `` - Polymer invocations now require dom-module name, remove invocation injection code --- lib/constants.js | 2 +- lib/utils.js | 17 ---- lib/vulcan.js | 28 ------- test/html/imports/simple-import.html | 9 ++- test/html/multiple.html | 12 --- test/test.js | 114 +++++---------------------- 6 files changed, 29 insertions(+), 153 deletions(-) delete mode 100644 test/html/multiple.html diff --git a/lib/constants.js b/lib/constants.js index 05b59e72d..cadc28892 100644 --- a/lib/constants.js +++ b/lib/constants.js @@ -13,7 +13,7 @@ var URL_ATTR = ['href', 'src', 'action', 'style']; module.exports = { EOL: require('os').EOL, - ELEMENTS: 'polymer-element:not([assetpath])', + ELEMENTS: 'dom-module:not([assetpath])', ELEMENTS_NOSCRIPT: 'polymer-element[noscript]', ABS_URL: /(^\/)|(^#)|(^[\w-\d]*:)/, REMOTE_ABS_URL: /(^http[s]?:)|(^\/\/)/, diff --git a/lib/utils.js b/lib/utils.js index e7d078c40..d0024233f 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -53,23 +53,6 @@ module.exports = { } return inpath; }, - processPolymerInvocation: function(elementName, invocation) { - var name = invocation[1] || ''; - var split = invocation[2] || ''; - var trailing = invocation[3]; - var nameIsString = /^['"]/.test(name); - if (!split) { - // assume "name" is actually the prototype if it is not a string literal - if (!name || (name && !nameIsString)) { - trailing = name + trailing; - name = '\'' + elementName + '\''; - } - if (trailing !== ')') { - split = ','; - } - } - return 'Polymer(' + name + split + trailing; - }, searchAll: function($, query) { var matches = []; concatTemplates($, null, query, matches); diff --git a/lib/vulcan.js b/lib/vulcan.js index 3d322c292..6143764ca 100644 --- a/lib/vulcan.js +++ b/lib/vulcan.js @@ -279,34 +279,6 @@ function handleMainDocument() { inlineScripts($, options.outputDir); } - searchAll($, constants.JS_INLINE).each(function() { - var el = $(this); - var content = getTextContent(el); - // find ancestor polymer-element node - var parentElement = el.closest('polymer-element').get(0); - if (parentElement) { - var match = constants.POLYMER_INVOCATION.exec(content); - var elementName = $(parentElement).attr('name'); - if (match) { - var invocation = utils.processPolymerInvocation(elementName, match); - content = content.replace(match[0], invocation); - setTextContent(el, content); - } - } - }); - - // strip noscript from elements, and instead inject explicit Polymer() invocation - // script, so registration order is preserved - searchAll($, constants.ELEMENTS_NOSCRIPT).each(function() { - var el = $(this); - var name = el.attr('name'); - if (options.verbose) { - console.log('Injecting explicit Polymer invocation for noscript element "' + name + '"'); - } - el.append(''); - el.attr('noscript', null); - }); - // strip scripts into a separate file if (options.csp) { if (options.verbose) { diff --git a/test/html/imports/simple-import.html b/test/html/imports/simple-import.html index 7f6a8cfc2..044ff38ae 100644 --- a/test/html/imports/simple-import.html +++ b/test/html/imports/simple-import.html @@ -7,7 +7,7 @@ Code distributed by Google as part of the polymer project is also subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt --> - + - + + diff --git a/test/html/multiple.html b/test/html/multiple.html deleted file mode 100644 index 447b9ba51..000000000 --- a/test/html/multiple.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - diff --git a/test/test.js b/test/test.js index b29311d4b..4ca7e5b64 100644 --- a/test/test.js +++ b/test/test.js @@ -62,21 +62,6 @@ suite('constants', function() { }); - test('Polymer Invocation', function() { - var polymer = constants.POLYMER_INVOCATION; - - function test(invocation, msg) { - var matches = polymer.exec(invocation); - assert(matches, 'polymer invocation found', msg); - } - - test('Polymer(\'core-input\', {})', 'full'); - test('Polymer(\'core-input\')', 'name-only'); - test('Polymer()', 'none'); - test('Polymer({})', 'object-only'); - test('Polymer(p)', 'indirect'); - }); - }); suite('CommentMap', function() { @@ -186,61 +171,61 @@ suite('Path Resolver', function() { var html = [ '', '', - '', + '', '', - '', - '' + '', + '' ].join('\n'); var expected = [ '', '', - '', + '', '', - '', - '' + '', + '' ].join('\n'); var expected2 = [ '', '', - '', + '', '', - '', - '' + '', + '' ].join('\n'); var htmlBase = [ '', '', '', - '', + '', '', - '', - '' + '', + '' ].join('\n'); var expectedBase = [ '', '', '', - '', + '', '', - '', - '' + '', + '' ].join('\n'); var actual; @@ -307,46 +292,6 @@ suite('Utils', function() { assert.equal(actual, 'foo\\/bar\\/baz', 'absolute path'); }); - test('Polymer Invocation', function() { - var polymer = constants.POLYMER_INVOCATION; - - function test(invocation, expected, msg) { - var matches = polymer.exec(invocation); - assert(matches, 'polymer invocation found'); - var replacement = utils.processPolymerInvocation('core-input', matches); - var actual = invocation.replace(matches[0], replacement); - assert.strictEqual(actual, expected, msg); - } - - test('Polymer(\'core-input\', {})', 'Polymer(\'core-input\', {})', 'full'); - test('Polymer(\'core-input\')', 'Polymer(\'core-input\')', 'name-only'); - test('Polymer()', 'Polymer(\'core-input\')', 'none'); - test('Polymer({})', 'Polymer(\'core-input\',{})', 'object-only'); - test('Polymer(p)', 'Polymer(\'core-input\',p)', 'indirect'); - - }); - - test('#82', function() { - var whacko = require('whacko'); - var $ = whacko.load(''); - $(constants.JS_INLINE).each(function() { - var el = $(this); - var content = utils.getTextContent(el); - assert(content); - var parentElement = el.closest('polymer-element').get(0); - if (parentElement) { - var match = constants.POLYMER_INVOCATION.exec(content); - var elementName = $(parentElement).attr('name'); - if (match) { - var invocation = utils.processPolymerInvocation(elementName, match); - content = content.replace(match[0], invocation); - utils.setTextContent(el, content); - } - } - assert.equal(utils.getTextContent(el), '(function(){ Polymer(\'paper-button-base\',p);}()'); - }); - }); - test('searchAll', function() { var searchAll = utils.searchAll; var whacko = require('whacko'); @@ -496,13 +441,11 @@ suite('Vulcan', function() { var $ = require('whacko').load(vulcanized); assert.equal(searchAll($, 'body > div[hidden]').length, 1, 'only one div[hidden]'); assert.equal(searchAll($, 'head > link[rel="import"]:not([href^="http://"])').length, 0, 'all relative imports removed'); - assert.equal(searchAll($, 'polymer-element').length, 1, 'imports were deduplicated'); - assert.equal(searchAll($, 'polymer-element').attr('noscript'), null, 'noscript removed'); - assert.equal(getTextContent(searchAll($, 'polymer-element > script')), 'Polymer(\'my-element\');', 'polymer script included'); - assert.equal($('link', $('polymer-element > template').get(0).children[0]).length, 0, 'external styles removed'); - assert.equal($('style', $('polymer-element > template').get(0).children[0]).length, 1, 'styles inlined'); - assert.equal($('svg > *', $('polymer-element > template').get(0).children[0]).length, 6, 'svg children propery nested'); - assert.equal(searchAll($, 'polymer-element').attr('assetpath'), 'imports/', 'assetpath set'); + assert.equal(searchAll($, 'dom-module').length, 1, 'imports were deduplicated'); + assert.equal($('link', $('dom-module > template').get(0).children[0]).length, 0, 'external styles removed'); + assert.equal($('style', $('dom-module > template').get(0).children[0]).length, 1, 'styles inlined'); + assert.equal($('svg > *', $('dom-module > template').get(0).children[0]).length, 6, 'svg children propery nested'); + assert.equal(searchAll($, 'dom-module').attr('assetpath'), 'imports/', 'assetpath set'); done(); }); }); @@ -518,7 +461,7 @@ suite('Vulcan', function() { var $ = require('whacko').load(vulcanized); assert(searchAll($, 'body > script[src="actual.js"]'), 'vulcanized script in body'); assert.equal(searchAll($, 'body script:not([src])').length, 0, 'inline scripts removed'); - assert.equal(vulcanizedJS, 'Polymer(\'my-element\');', 'csp element script'); + assert.equal(vulcanizedJS.trim(), 'Polymer({\n is: \'my-element\'\n });', 'csp element script'); done(); }); }); @@ -645,21 +588,6 @@ suite('Vulcan', function() { }); - test('Multiple Polymer Invocations', function(done) { - var options = {input: 'test/html/multiple.html', output: outputPath}; - process(options, function(outputs) { - var vulcanized = outputs[outputPath]; - assert(vulcanized); - var $ = require('whacko').load(vulcanized); - var getText = require('../lib/utils.js').getTextContent; - var xa = $('polymer-element[name="x-a"] > script'); - var xb = $('polymer-element[name="x-b"] > script'); - assert.equal(getText(xa), 'Polymer(\'x-a\',{})'); - assert.equal(getText(xb), 'Polymer(\'x-b\',{})'); - done(); - }); - }); - test('Handle tag', function(done) { var options = {input: 'test/html/base.html', output: outputPath}; process(options, function(outputs) { From e583b4faebb6e49bf54c86c0f01f28714e679830 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Mon, 23 Feb 2015 10:36:37 -0800 Subject: [PATCH 0219/1006] Add application/javascript as a valid mimetype Fixes #137 Inlining scripts with type `application/javascript` --- lib/constants.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/constants.js b/lib/constants.js index 05b59e72d..da7fbf95b 100644 --- a/lib/constants.js +++ b/lib/constants.js @@ -8,7 +8,7 @@ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt */ -var JS = 'script:not([type]), script[type="text/javascript"]'; +var JS = 'script:not([type]), script[type="text/javascript"], script[type="application/javascript"]'; var URL_ATTR = ['href', 'src', 'action', 'style']; module.exports = { From 311384a9d4ca809a08362090337da661cf8bc528 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Fri, 27 Feb 2015 11:51:16 -0800 Subject: [PATCH 0220/1006] handle [[ ]] in urls --- lib/constants.js | 2 +- test/test.js | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/constants.js b/lib/constants.js index cadc28892..f7cdeaa55 100644 --- a/lib/constants.js +++ b/lib/constants.js @@ -21,7 +21,7 @@ module.exports = { URL: /url\([^)]*\)/g, URL_ATTR: URL_ATTR, URL_ATTR_SEL: '[' + URL_ATTR.join('],[') + ']', - URL_TEMPLATE: '{{.*}}', + URL_TEMPLATE: '{{.*}}|\\[\\[.*\\]\\]', JS: JS, JS_SRC: JS.split(',').map(function(s){ return s + '[src]'; }).join(','), JS_INLINE: JS.split(',').map(function(s) { return s + ':not([src])'; }).join(','), diff --git a/test/test.js b/test/test.js index 4ca7e5b64..67ebf3c62 100644 --- a/test/test.js +++ b/test/test.js @@ -252,6 +252,24 @@ suite('Path Resolver', function() { assert.equal(actual, expectedBase, 'base'); }); + test('Leave Templated Urls', function() { + var base = [ + '', + '', + '', + '' + ].join('\n'); + + var actual; + var whacko = require('whacko'); + var $ = whacko.load(base); + + pathresolver.resolvePaths($, inputPath, outputPath); + + actual = $.html(); + assert.equal(actual, base, 'templated urls'); + }); + }); suite('Utils', function() { From aff64370b39d6b3bd3281ea9f72b8a7b30f79495 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Wed, 11 Mar 2015 12:12:52 -0700 Subject: [PATCH 0221/1006] port out of hydrolysis branch --- bin/demo | 118 + example/.gitignore | 2 - example/absolutes.html | 12 - example/bower_components/polymer/.bower.json | 34 + example/bower_components/polymer/PRIMER.md | 1383 ++++ example/bower_components/polymer/README.md | 330 + example/bower_components/polymer/bower.json | 24 + example/bower_components/polymer/build.bat | 2 + .../bower_components/polymer/docs/index.html | 48 + .../polymer/explainer/data-bind.png | Bin 0 -> 34533 bytes .../polymer/explainer/data-bind.vsdx | Bin 0 -> 38379 bytes .../polymer/explainer/samples.html | 50 + .../polymer/polymer-micro.html | 35 + .../polymer/polymer-mini.html | 45 + example/bower_components/polymer/polymer.html | 55 + .../polymer/src/expr/focus.html | 22 + .../polymer/src/expr/gestures.html | 1 + .../polymer/src/expr/log.html | 21 + .../polymer/src/expr/polymer-expr.html | 57 + .../polymer/src/expr/sinspect.html | 235 + .../polymer/src/expr/x-styling-defaults.html | 61 + .../polymer/src/expr/x-styling.html | 283 + .../src/features/micro/attributes.html | 176 + .../src/features/micro/constructor.html | 74 + .../polymer/src/features/micro/extends.html | 79 + .../polymer/src/features/micro/mixins.html | 40 + .../src/features/micro/properties.html | 96 + .../polymer/src/features/mini/ready.html | 120 + .../polymer/src/features/mini/shadow.html | 41 + .../polymer/src/features/mini/shady.html | 339 + .../polymer/src/features/mini/template.html | 60 + .../src/features/standard/annotations.html | 194 + .../src/features/standard/configure.html | 162 + .../src/features/standard/effects.html | 149 + .../polymer/src/features/standard/events.html | 114 + .../src/features/standard/notify-path.html | 266 + .../src/features/standard/resolveUrl.html | 27 + .../src/features/standard/styling.html | 149 + .../polymer/src/features/standard/utils.html | 139 + .../src/lib/annotations/annotations.html | 273 + .../src/lib/annotations/demo/app-chrome.html | 60 + .../polymer/src/lib/array-observe.html | 115 + .../polymer/src/lib/array-splice.html | 262 + .../polymer/src/lib/async.html | 68 + .../polymer/src/lib/base.html | 117 + .../src/lib/bind/bind-annotations.html | 74 + .../polymer/src/lib/bind/bind-effects.html | 188 + .../polymer/src/lib/bind/bind.html | 218 + .../polymer/src/lib/bind/demo/app-chrome.html | 28 + .../polymer/src/lib/bind/demo/app.html | 29 + .../bind/demo/src/annotations-bind-demo.html | 76 + .../src/lib/bind/demo/src/bind-demo.html | 83 + .../polymer/src/lib/collection.html | 164 + .../polymer/src/lib/css-parse.html | 131 + .../polymer/src/lib/debounce.html | 69 + .../polymer/src/lib/dom-api.html | 393 ++ .../polymer/src/lib/dom-module.html | 50 + .../polymer/src/lib/lang.html | 21 + .../polymer/src/lib/module.html | 56 + .../polymer/src/lib/polymer.html | 78 + .../polymer/src/lib/resolve-url.html | 82 + .../polymer/src/lib/settings.html | 48 + .../polymer/src/lib/style-transformer.html | 166 + .../polymer/src/lib/style-util.html | 77 + .../polymer/src/lib/template/templatizer.html | 117 + .../src/lib/template/x-array-selector.html | 94 + .../polymer/src/lib/template/x-autobind.html | 36 + .../polymer/src/lib/template/x-repeat.html | 389 ++ .../polymer/src/lib/template/x-template.html | 39 + .../bower_components/polymer/src/polymer.html | 14 + example/bower_components/polymer/wct.conf.js | 3 + .../webcomponentsjs/.bower.json | 24 + .../webcomponentsjs/CustomElements.js | 634 ++ .../webcomponentsjs/CustomElements.min.js | 11 + .../webcomponentsjs/HTMLImports.js | 764 ++ .../webcomponentsjs/HTMLImports.min.js | 11 + .../webcomponentsjs/README.md | 73 + .../webcomponentsjs/ShadowDOM.js | 4277 ++++++++++++ .../webcomponentsjs/ShadowDOM.min.js | 13 + .../webcomponentsjs/bower.json | 14 + .../webcomponentsjs/package.json | 31 + .../webcomponentsjs/webcomponents-lite.js | 1728 +++++ .../webcomponentsjs/webcomponents-lite.min.js | 11 + .../webcomponentsjs/webcomponents.js | 6114 +++++++++++++++++ .../webcomponentsjs/webcomponents.min.js | 14 + example/config.json | 5 - example/empty.css | 10 - example/foo.html | 1 + example/import-test.css | 15 - example/import-test.html | 58 - example/index.html | 39 +- example/sub-import/sub-import.html | 23 - example/sub/import.html | 13 + package.json | 5 +- 94 files changed, 22397 insertions(+), 152 deletions(-) create mode 100755 bin/demo delete mode 100644 example/.gitignore delete mode 100644 example/absolutes.html create mode 100644 example/bower_components/polymer/.bower.json create mode 100644 example/bower_components/polymer/PRIMER.md create mode 100644 example/bower_components/polymer/README.md create mode 100644 example/bower_components/polymer/bower.json create mode 100644 example/bower_components/polymer/build.bat create mode 100644 example/bower_components/polymer/docs/index.html create mode 100644 example/bower_components/polymer/explainer/data-bind.png create mode 100644 example/bower_components/polymer/explainer/data-bind.vsdx create mode 100644 example/bower_components/polymer/explainer/samples.html create mode 100644 example/bower_components/polymer/polymer-micro.html create mode 100644 example/bower_components/polymer/polymer-mini.html create mode 100644 example/bower_components/polymer/polymer.html create mode 100644 example/bower_components/polymer/src/expr/focus.html create mode 100644 example/bower_components/polymer/src/expr/gestures.html create mode 100644 example/bower_components/polymer/src/expr/log.html create mode 100644 example/bower_components/polymer/src/expr/polymer-expr.html create mode 100644 example/bower_components/polymer/src/expr/sinspect.html create mode 100644 example/bower_components/polymer/src/expr/x-styling-defaults.html create mode 100644 example/bower_components/polymer/src/expr/x-styling.html create mode 100644 example/bower_components/polymer/src/features/micro/attributes.html create mode 100644 example/bower_components/polymer/src/features/micro/constructor.html create mode 100644 example/bower_components/polymer/src/features/micro/extends.html create mode 100644 example/bower_components/polymer/src/features/micro/mixins.html create mode 100644 example/bower_components/polymer/src/features/micro/properties.html create mode 100644 example/bower_components/polymer/src/features/mini/ready.html create mode 100644 example/bower_components/polymer/src/features/mini/shadow.html create mode 100644 example/bower_components/polymer/src/features/mini/shady.html create mode 100644 example/bower_components/polymer/src/features/mini/template.html create mode 100644 example/bower_components/polymer/src/features/standard/annotations.html create mode 100644 example/bower_components/polymer/src/features/standard/configure.html create mode 100644 example/bower_components/polymer/src/features/standard/effects.html create mode 100644 example/bower_components/polymer/src/features/standard/events.html create mode 100644 example/bower_components/polymer/src/features/standard/notify-path.html create mode 100644 example/bower_components/polymer/src/features/standard/resolveUrl.html create mode 100644 example/bower_components/polymer/src/features/standard/styling.html create mode 100644 example/bower_components/polymer/src/features/standard/utils.html create mode 100644 example/bower_components/polymer/src/lib/annotations/annotations.html create mode 100644 example/bower_components/polymer/src/lib/annotations/demo/app-chrome.html create mode 100644 example/bower_components/polymer/src/lib/array-observe.html create mode 100644 example/bower_components/polymer/src/lib/array-splice.html create mode 100644 example/bower_components/polymer/src/lib/async.html create mode 100644 example/bower_components/polymer/src/lib/base.html create mode 100644 example/bower_components/polymer/src/lib/bind/bind-annotations.html create mode 100644 example/bower_components/polymer/src/lib/bind/bind-effects.html create mode 100644 example/bower_components/polymer/src/lib/bind/bind.html create mode 100644 example/bower_components/polymer/src/lib/bind/demo/app-chrome.html create mode 100644 example/bower_components/polymer/src/lib/bind/demo/app.html create mode 100644 example/bower_components/polymer/src/lib/bind/demo/src/annotations-bind-demo.html create mode 100644 example/bower_components/polymer/src/lib/bind/demo/src/bind-demo.html create mode 100644 example/bower_components/polymer/src/lib/collection.html create mode 100644 example/bower_components/polymer/src/lib/css-parse.html create mode 100644 example/bower_components/polymer/src/lib/debounce.html create mode 100644 example/bower_components/polymer/src/lib/dom-api.html create mode 100644 example/bower_components/polymer/src/lib/dom-module.html create mode 100644 example/bower_components/polymer/src/lib/lang.html create mode 100644 example/bower_components/polymer/src/lib/module.html create mode 100644 example/bower_components/polymer/src/lib/polymer.html create mode 100644 example/bower_components/polymer/src/lib/resolve-url.html create mode 100644 example/bower_components/polymer/src/lib/settings.html create mode 100644 example/bower_components/polymer/src/lib/style-transformer.html create mode 100644 example/bower_components/polymer/src/lib/style-util.html create mode 100644 example/bower_components/polymer/src/lib/template/templatizer.html create mode 100644 example/bower_components/polymer/src/lib/template/x-array-selector.html create mode 100644 example/bower_components/polymer/src/lib/template/x-autobind.html create mode 100644 example/bower_components/polymer/src/lib/template/x-repeat.html create mode 100644 example/bower_components/polymer/src/lib/template/x-template.html create mode 100644 example/bower_components/polymer/src/polymer.html create mode 100644 example/bower_components/polymer/wct.conf.js create mode 100644 example/bower_components/webcomponentsjs/.bower.json create mode 100644 example/bower_components/webcomponentsjs/CustomElements.js create mode 100644 example/bower_components/webcomponentsjs/CustomElements.min.js create mode 100644 example/bower_components/webcomponentsjs/HTMLImports.js create mode 100644 example/bower_components/webcomponentsjs/HTMLImports.min.js create mode 100644 example/bower_components/webcomponentsjs/README.md create mode 100644 example/bower_components/webcomponentsjs/ShadowDOM.js create mode 100644 example/bower_components/webcomponentsjs/ShadowDOM.min.js create mode 100644 example/bower_components/webcomponentsjs/bower.json create mode 100644 example/bower_components/webcomponentsjs/package.json create mode 100644 example/bower_components/webcomponentsjs/webcomponents-lite.js create mode 100644 example/bower_components/webcomponentsjs/webcomponents-lite.min.js create mode 100644 example/bower_components/webcomponentsjs/webcomponents.js create mode 100644 example/bower_components/webcomponentsjs/webcomponents.min.js delete mode 100644 example/config.json delete mode 100644 example/empty.css create mode 100644 example/foo.html delete mode 100644 example/import-test.css delete mode 100644 example/import-test.html delete mode 100644 example/sub-import/sub-import.html create mode 100644 example/sub/import.html diff --git a/bin/demo b/bin/demo new file mode 100755 index 000000000..77cba90da --- /dev/null +++ b/bin/demo @@ -0,0 +1,118 @@ +#!/usr/bin/env node + +// jshint node: true +'use strict'; + +var path = require('path'); +var url = require('url'); +var hyd = require('hydrolysis'); +var p5u = require('parse5-utils/parse5-utils.js'); +var loader = new hyd.loader(); +loader.addResolver(new hyd.fsResolver({})); + +function isUniqueImport(importNode) { + return Boolean(importNode.url); +} + +var headFinder = p5u.predicates.hasTagName('head'); +var bodyFinder = p5u.predicates.hasTagName('body'); +var attrs = ['action', 'href', 'src', 'style', 'assetpath']; +var attrMatcher = p5u.predicates.OR(attrs.map(function(attr) { + return p5u.predicates.hasAttr(attr); +})); +var elementMatcher = p5u.predicates.AND([ + p5u.predicates.hasTagName('dom-module'), + p5u.predicates.hasAttr('id'), + p5u.predicates.NOT( + p5u.predicates.hasAttr('assetpath') + ) +]); +function reparent(newParent) { + return function(node) { + node.parentNode = newParent; + }; +} + +// make two absolute urls relative to each other +function relativeTo(from, to) { + var parsedFrom = url.parse(from); + var parsedTo = url.parse(to); + if (parsedFrom.protocol === parsedTo.protocol && parsedFrom.host === parsedTo.host) { + var pathname = path.relative(path.dirname(parsedFrom.pathname), parsedTo.pathname); + return url.format({ + pathname: pathname, + search: parsedTo.search, + hash: parsedTo.hash + }); + } + return to; +} + +function flatten(tree) { + var doc = tree.html.ast; + var imports = tree.imports; + var head = p5u.query(doc, headFinder); + var body = p5u.query(doc, bodyFinder); + var importNodes = tree.html.import; + var importDoc, importHead, importBody, importHeadChildren, importBodyChildren; + if (imports) { + for (var i = 0, im; i < imports.length; i++) { + im = imports[i]; + if (!isUniqueImport(im)) { + p5u.remove(importNodes[i]); + continue; + } + importDoc = flatten(im); + importHead = p5u.query(importDoc, headFinder); + importBody = p5u.query(importDoc, bodyFinder); + // rewrite urls + p5u.queryAll(importDoc, attrMatcher).forEach(function(node) { + attrs.forEach(function(attr) { + var attrValue = p5u.getAttribute(node, attr); + if (attrValue) { + var absUrl = url.resolve(im.url, attrValue); + var relUrl = relativeTo(tree.url, absUrl); + if (attr === 'assetpath') { + relUrl += '/'; + } + p5u.setAttribute(node, attr, relUrl); + } + }); + }); + p5u.queryAll(importDoc, elementMatcher).forEach(function(el) { + var rel = relativeTo(tree.url, im.url); + rel = path.dirname(rel) + '/'; + p5u.setAttribute(el, 'assetpath', rel); + }); + // merge head and body tags for imports into main document + importHeadChildren = importHead.childNodes; + importBodyChildren = importBody.childNodes; + importHeadChildren.forEach(reparent(head)); + importBodyChildren.forEach(reparent(body)); + // replace import node with importHeadChildren + var idx = head.childNodes.indexOf(importNodes[i]); + head.childNodes = [].concat(head.childNodes.slice(0, idx), importHeadChildren, head.childNodes.slice(idx + 1)); + // prepend import body to document body + body.childNodes = importBodyChildren.concat(body.childNodes); + } + } + return doc; +} + +var target = process.argv[2]; + +if (!target) { + console.error('no target!'); + process.exit(1); +} + +loader.request(target).then(function(content) { + return hyd.hydrolyze(content, true, target, loader); +}).then(function(tree) { + var flatDoc = flatten(tree); + var serializer = new (require('parse5').Serializer)(); + console.log(serializer.serialize(flatDoc)); +}).catch(function(err) { + console.log(err); + process.exit(1); +}); diff --git a/example/.gitignore b/example/.gitignore deleted file mode 100644 index ea7615259..000000000 --- a/example/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -bower_components -vulcanized* diff --git a/example/absolutes.html b/example/absolutes.html deleted file mode 100644 index 9fc1e6477..000000000 --- a/example/absolutes.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - diff --git a/example/bower_components/polymer/.bower.json b/example/bower_components/polymer/.bower.json new file mode 100644 index 000000000..f82219d89 --- /dev/null +++ b/example/bower_components/polymer/.bower.json @@ -0,0 +1,34 @@ +{ + "name": "polymer", + "main": [ + "polymer.html" + ], + "license": "http://polymer.github.io/LICENSE.txt", + "ignore": [ + "/.*", + "/test/" + ], + "authors": [ + "The Polymer Authors (http://polymer.github.io/AUTHORS.txt)" + ], + "repository": { + "type": "git", + "url": "https://github.com/Polymer/polymer.git" + }, + "devDependencies": { + "web-component-tester": "*", + "webcomponentsjs": "webcomponents/webcomponentsjs#master" + }, + "private": true, + "homepage": "https://github.com/Polymer/polymer", + "_release": "860ce4cc9a", + "_resolution": { + "type": "branch", + "branch": "0.8-preview", + "commit": "860ce4cc9aebe8bc69018ae3a0dacd20258a11bc" + }, + "_source": "git://github.com/Polymer/polymer.git", + "_target": "0.8-preview", + "_originalSource": "Polymer/polymer", + "_direct": true +} \ No newline at end of file diff --git a/example/bower_components/polymer/PRIMER.md b/example/bower_components/polymer/PRIMER.md new file mode 100644 index 000000000..31b20c89f --- /dev/null +++ b/example/bower_components/polymer/PRIMER.md @@ -0,0 +1,1383 @@ +# Polymer 0.8 Primer + +**
Polymer 0.8 and this document are a WORK IN PROGRESS and APIs are subject to change.
** + +Table of Contents: + +* [Feature list](#feature-list) +* [Migration notes](#migration-notes) + +# Feature list + + +Below is a description of the current Polymer features, followed by individual feature guides. + + +Bare-minum Custom Element sugaring + +| Feature | Usage +|---------|------- +| [Custom element constructor](#element-constructor) | Polymer.Class({ … }); +| [Custom element registration](#register-element) | Polymer({ is: ‘...’, … }}; +| [Bespoke constructor support](#bespoke-constructor) | constructor: function() { … } +| [Basic lifecycle callbacks](#basic-callbacks) | created, attached, detached, attributeChanged +| [Native HTML element extension](#type-extension) | extends: ‘…’ +| [Configure properties](#property-config) | properties: { … } +| [Attribute deserialization to property](#attribute-deserialization) | properties: { \: \ } +| [Prototype Mixins](#prototype-mixins) | mixins: [ … ] + + +Template content stamped into "local DOM" and tree lifecycle + +| Feature | Usage +|---------|------- +| [Template stamping into local DOM](#template-stamping) | \\\ +| [DOM (re-)distribution](#dom-distribution) | \ +| [DOM API](#dom-api) | Polymer.dom +| [Configuring default values](#configure-values) | properties: \: { value: \\|\ } +| [Bottom-up callback after configuration](#ready-method) | ready: function() { … } + + +Declarative data binding, events, and property nofication + +| Feature | Usage +|---------|------- +| [Local node marshalling](#node-marshalling) | this.$.\ +| [Event listener setup](#event-listeners)| listeners: { ‘\.\’: ‘function’, ... } +| [Annotated event listener setup](#annotated-listeners) | \ +| [Property change callbacks](#change-callbacks) | properties: \: { observer: ‘function’ } +| [Declarative property binding](#property-binding) | \ +| [Property change notification](#property-notification) | properties: { \: { notify: true } } +| [Binding to structured data](#path-binding) | \ +| [Path change notification](#set-path) | setPathValue(\, \) +| [Declarative attribute binding](#attribute-binding) | \ +| [Reflecting properties to attributes](#attribute-reflection) | properties: \: { reflect: true } } +| [Computed properties](#computed-properties) | computed: { \: ‘function(\)’ } +| [Read-only properties](#read-only) | properties: { \: { readOnly: true } } +| [Utility functions](#utility-functions) | toggleClass, toggleAttribute, fire, async, … +| [Scoped styling](#scoped-styling) | \ + + + + + + + +``` + +Note: Remote stylesheets (``) are not currently supported for providing scoped styles. This may be added in future versions. See below for workarounds. + + +### Sharing stylesheets + +Styles can be shared between elements by defining ``'s containing styles to be shared, and referencing shared styles to be included in a given element by listing the `dom-module` id in an array of `styleModules`. + +Example: + +```html + + + +``` + +```js +Polymer({ + is: 'element-one' + styleModules: ['common-styles'] +}); + +Polymer({ + is: 'element-two' + styleModules: ['common-styles'] +}); +``` + + +## Global Polymer settings + +Document-level global Polymer settings can be set before loading by setting a `Polymer` object on window as the first script in the main document: + +```html + + + + + + + + + + ... + +``` + +Settings can also be switched on the URL query string: + +``` +http://myserver.com/test-app/index.html?dom=shadow +``` + +Available settings: + +* `dom` - options: + * `shady` - all local DOM will be rendered using Shady DOM (even where shadow-DOM supported (current default) + * `shadow` - local DOM will be rendered using Shadow DOM where supported (this will be made default soon) + + + +## Feature layering + +Polymer 0.8 is currently layered into 3 sets of features provided as 3 discrete HTML imports, such that an individual element developer can depend on a version of Polymer whose feature set matches their tastes/needs. For authors who opt out of the more opinionated local DOM or data-binding features, their element's dependencies would not be payload- or runtime-burdened by these higher-level features, to the extent that a user didn't depend on other elements using those features on that page. That said, all features are designed to have low runtime cost when unused by a given element. + +Higher layers depend on lower layers, and elements requiring lower layers will actually be imbued with features of the highest-level version of Polymer used on the page (those elements would simply not use/take advantage of those features). This provides a good tradeoff between element authors being able to avoid direct dependencies on unused features when their element is used standalone, while also allowing end users to mix-and-match elements created with different layers on the same page. + +* polymer-micro.html: [Polymer micro features](#polymer-micro) +* polymer-mini.html: [Polymer mini features](#polymer-mini) +* polymer.html: [Polymer standard features](#polymer-standard) + +--- + + +# Migration Notes + +This section covers how to deal with yet-unimplemented and/or de-scoped features in Polymer 0.8 as compared to 0.5. Many of these are simply un-implemented; that is, we will likely have a final "solution" that addresses the need, we just haven't tackled that feature yet as we address items in priority order. Other solutions in 0.8 may be lower-level as compared to 0.5, and will be explained here. + +As the final 0.8 API solidifies, this section will be updated accordingly. As such, this section should be considered answers "how do I solve problem xyz TODAY", rather than a representation of the final Polymer 0.8 API. + +## Property casing + +TL;DR: When binding to camel-cased properties, use "dash-case" attribute names to indicate the "camelCase" property to bind to. + +Example: bind `this.myValue` to `.thatValue`: + +BEFORE: 0.5 + +```html + +``` + +AFTER: 0.8 + +```html + +``` + +In 0.5, binding annotations were allowed to mixed-case properties (despite the fact that attribute names always get converted to lower-case by the HTML parser), and the Node.bind implementation at the "receiving end" of the binding automatically inferred the mixed-case property it was assumed to refer to at instance time. + +In 0.8, "binding" is done at prorotype time before the type of the element being bound to is known, hence knowing the exact JS property to bind to allows better efficiency. + +## Binding limitations + +Current limitations that are on the backlog for evaluation/improvement are listed below, with current workarounds: + +* Sub-textContent/property binding + * You cannot currrently do any of the following: + + ```html +
stuff here: {{stuff}}
+
+ + ``` + + * Instead, use ``'s to break up textContent into discrete elements: + + ```html +
stuff here: {{stuff}}
+ ``` + + * Use computed properties for concatenating into properties/attributes: + + ```html +
+ + ``` + +* CSS class binding: + * May bind entire class list from one property to `class` _attribute_: + `
` + * Otherwise, `this.classList.add/remove` from change handlers +* CSS inline-style binding: + * May bind entire inline style from one property to `style` _property_: + `
` + * Otherwise, assign `this.style.props` from change handlers + +## Structured data and path notification + +To notify non-bound structured data changes changes, use `setPathValue` and `notifyPath`: + +```js +this.setPathValue('user.manager', 'Matt'); +``` + +Which is equivalent to: + +```js +this.user.manager = 'Matt'; +this.notifyPath('user.manager', this.user.manager); +``` + +## Repeating elements + +Repeating templates is moved to a custom element (HTMLTemplateElement type extension called `x-repeat`): + +```html + +``` + +## Array notification + +This area is in high flux. Arrays bound to `x-repeat` are currently observed using `Array.observe` (or equivalent shim) and `x-repeat` will reflect changes to array mutations (push, pop, shift, unshift, splice) asynchronously. + +**In-place sort of array is not supported**. Sorting/filtering will likely be provided as a feature of `x-repeat` (and possibly other array-aware elements such as `x-list`) in the future. + +Implementation and usage details will likely change, stay tuned. + + +## Mixins / Inheritance + +TODO - use composition for now + +## Gesture support + +TODO - use standard DOM for now until gesture support is ported diff --git a/example/bower_components/polymer/README.md b/example/bower_components/polymer/README.md new file mode 100644 index 000000000..950836318 --- /dev/null +++ b/example/bower_components/polymer/README.md @@ -0,0 +1,330 @@ +# Polymer 0.8 Preview + +Authors interested in learning the core concepts in 0.8 may be interested in our [primer](https://github.com/Polymer/polymer/blob/0.8-preview/PRIMER.md). + +## From The Ground Up + +Let us begin this tale with a short stroll through the layers that Polymer is +built upon, and some of the rationale of how we got there. + +### Raw Custom Elements + +Custom Elements are a powerful emerging web standard that allows developers to create their own elements by attaching a class to a tag-name. + +#### document.registerElement + +The native API is very simple, it looks something like this: + +```js +document.registerElement(, {prototype: Object[, extends: String]}); +``` + +#### Typical Boilerplate + +There is a little bit of work one has to do to set up the class with the right prototypes and so on to construct a Custom Element. Here is an typical example (using ES5 syntax): + +```js +var ctor = function() { + return document.createElement('x-custom'); +}; +ctor.prototype = Object.create(HTMLElement.prototype); +ctor.prototype.constructor = ctor; +ctor.prototype.createdCallback = function() { + this.innerHTML = 'Hello World, I am a Custom Element!'; +} +document.registerElement('x-custom', ctor); +``` + +### Reluctant Polymer() Abstraction + +By principle, Polymer team tries to avoid abstracting DOM APIs, especially new ones. But in this case we finally decided the ergonomic benefit was worth it. By wrapping `registerElement` in our own function, we can reduce the above boilerplate to: + +```js +var ctor = Polymer({ + is: 'x-custom', + created: function() { + this.innerHTML = 'Hello World, I am a Custom Element!'; + } +}); +``` + +### Polymer() Does a Bit More + +You might notice the `Polymer()` invocation defines `created` instead of `createdCallback`. This is a feature of `Polymer.Base`, a tiny prototype that `Polymer()` adds to your prototype chain as it's handling the boilerplate above. `Polymer.Base` hooks the standard Custom Element lifecycle callbacks to provide helper implementations. The hooks in turn call shorter-named lifecycle methods on your prototype. + +- `created` instead of `createdCallback` +- `attached` instead of `attachedCallback` +- `detached` instead of `detachedCallback` +- `attributeChanged` instead of `attributeChangedCallback` + +You can always fallback to using the low-level methods if you wish (iow, you could simply implement `createdCallback` in your prototype). + +`Polymer.Base` also implements `registerCallback` on your prototype. `Polymer()` calls `registerCallback` which allows `Polymer.Base` to supply a layering system for Polymer abstractions so that no element needs to pay for features it doesn't use. + +## Features + +By default, the default Polymer distribution include several features. Although `Polymer.Base` itself is tiny, if you examine `Polymer.Base` you will probably see several methods that have been plugged-in to that prototype by feature definitions. The next few sections will explain these features and why we include them in the default set. Keep in mind that it's entirely possible to construct custom feature sets, or even use a trivial, featureless form of `Polymer()`. + +### Feature: _property-config_ + +The first feature implements support for the `properties` property. By placing a object-valued `properties` property on your prototype, let's you define various aspects of your custom-elements public API. + +By itself, the `properties` feature **doesn't do anything**. It only provides API for asking questions about these special properties (see [link to docs] for details). + +```js +Polymer({ + + is: 'x-custom', + + properties: { + user: String, + isHappy: Boolean, + count: { + type: Number, + readOnly: true, + notify: true + } + }, + + created: function() { + this.innerHTML = 'Hello World, I am a Custom Element!'; + } + +}); +``` + +Remember that the fields assigned to `count`, such as `readOnly` and `notify` don't do anything by themselves, it requires other features to give them life. + +### Feature: _attributes_ + +Many custom elements want to support configuration using HTML attributes. Custom Elements provides the `attributeChanged` callback gives us the raw API for this ability, but then we have to deal with initialization and type conversion (attributes are always strings). Here is an example of a custom element that supports a `user` attribute using the raw API. + +```js + Polymer({ + + is: 'x-custom', + + created: function() { + // handle any initial value + this.attributeChanged('user'); + // render + this.innerHTML = 'Hello World, my user is ' + (this.user || 'nobody') + '.'; + }, + + attributeChanged: function(name) { + switch(name) { + case 'user': + // pretty easy since user is a String, for other types + // we have to do more work + if (this.hasAttribute('user')) { + this.user = this.getAttribute('user'); + } + break; + } + } + + }); +``` + +Although it's relatively simple, having to write this code becomes annoying when working with multiple attributes or non-String types. It's also not very DRY. + +Instead, Polymer's `attributes` feature handles this work for you (using the `properties` feature data). If an attribute is set that matches a property listed in the `properties` object, the value is captured into the matching property. Strings are automatically converted to the specified type. + +The type system includes support for Object values expressed as JSON, or Date objects expressed as any Date-parsable string representation. Boolean properties are mapped to Boolean attributes, in other words, if the attribute exists at all, its value is true, regardless of its string-value (and the value is only false if the attribute does not exist). + +Here is the equivalent of the above code, taking advantage of the `attributes` feature. + +```html + + + +``` + +### [ToDoc] attributes:hostAttributes + +### Feature: _template_ + +HTML templates are an emerging web standard that we like to consider part of the Web Components family. Templates are a great way to provide archetypal DOM content for your custom element, and this is where the `template` feature comes in. + +As usual, we started by writing basic template support by hand. It generally looks something like this: + +```html + + + +``` + +Again, it's simple, but it's a common pattern, so the `template` feature does it automatically. By default it looks for a template as the first element before the script, so our code can look like this: + +```html + + + +``` + +### Feature: _annotations_ + +Most elements need to customize the DOM instanced from a template. For this reason, it's handy to encode markers into your template to indicate special nodes, attributes, or text. Polymer calls these markers _annotations_. The `annotations` feature scans the template (once per element, at registration time) and builds a data-structure into the prototype that identifies markers it finds in the DOM (see [link to docs] for details). Normally you do not need to work with this data directly, Polymer does it for you. + +### Feature: _annotations-nodes_ + +Traditionally, modifying DOM is done by querying for elements to manipulate. Here is an example: + +```html + + + +``` + +This example is very simple. But in real projects, repeating queries is inefficient, so query results are often stored (memoized). Also, as DOM composition becomes more tricky, crafting correct queries can be difficult. For these reasons, automatically capturing nodes makes a good feature. + +The `annotations-nodes` feature builds a map of instance nodes by `id` in `this.$` (using the `annotations` feature data). Here is how the `annotations-nodes` feature simplifies the above example. + +```html + + + +``` + +### Feature: _annotations-events_ + +Most elements also need to listen for events. The standard DOM method `addEventListener` provides the low-level support: + +```html + + + +``` + +Again, this is pretty simple, but it's so common that it's worth making even simpler. The `annotations-events` feature supports declaring event listeners directly in our template. + +Declaring listeners in the template is convenient, and also helps us decouple view from behavior. + +```html + + + +``` + +Notice that the `kickAction` method doesn't know anything about `button`. If we decided that kicking should be performed by a key-press, or a menu-item, the element code doesn't need to know. We can change the UI however we want. Also notice that by attaching the event declaratively, we have removed the need to give the button an id. + +### [ToDoc] events feature + +### [ToDoc] keys feature + +### [ToDoc] content feature + + diff --git a/example/bower_components/polymer/bower.json b/example/bower_components/polymer/bower.json new file mode 100644 index 000000000..f7cd3ac5e --- /dev/null +++ b/example/bower_components/polymer/bower.json @@ -0,0 +1,24 @@ +{ + "name": "polymer", + "version": "0.8", + "main": [ + "polymer.html" + ], + "license": "http://polymer.github.io/LICENSE.txt", + "ignore": [ + "/.*", + "/test/" + ], + "authors": [ + "The Polymer Authors (http://polymer.github.io/AUTHORS.txt)" + ], + "repository": { + "type": "git", + "url": "https://github.com/Polymer/polymer.git" + }, + "devDependencies": { + "web-component-tester": "*", + "webcomponentsjs": "webcomponents/webcomponentsjs#master" + }, + "private": true +} diff --git a/example/bower_components/polymer/build.bat b/example/bower_components/polymer/build.bat new file mode 100644 index 000000000..12479f7da --- /dev/null +++ b/example/bower_components/polymer/build.bat @@ -0,0 +1,2 @@ +START /B vulcanize polymer-simplex.html --inline --strip -output dist/polymer-simplex.html +START /B vulcanize polymer.html --inline --strip -output dist/polymer.html diff --git a/example/bower_components/polymer/docs/index.html b/example/bower_components/polymer/docs/index.html new file mode 100644 index 000000000..b2fa01610 --- /dev/null +++ b/example/bower_components/polymer/docs/index.html @@ -0,0 +1,48 @@ + + + + + + x-doc-viewer + + + + + + + + + + + + + + + + + + + + + diff --git a/example/bower_components/polymer/explainer/data-bind.png b/example/bower_components/polymer/explainer/data-bind.png new file mode 100644 index 0000000000000000000000000000000000000000..c55816df3ea7fabc3a64f90425be3a346f431bbd GIT binary patch literal 34533 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 literal 0 HcmV?d00001 diff --git a/example/bower_components/polymer/explainer/data-bind.vsdx b/example/bower_components/polymer/explainer/data-bind.vsdx new file mode 100644 index 0000000000000000000000000000000000000000..e699a26bb30541b189fcd7d811b2d138d2ccb6c0 GIT binary patch literal 38379 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 Pu_6qKz$yBY2_PN-g`tXp literal 0 HcmV?d00001 diff --git a/example/bower_components/polymer/explainer/samples.html b/example/bower_components/polymer/explainer/samples.html new file mode 100644 index 000000000..7a22c3108 --- /dev/null +++ b/example/bower_components/polymer/explainer/samples.html @@ -0,0 +1,50 @@ + + + + + + Explainer Samples + + + + + + + + + + + + + + + + + diff --git a/example/bower_components/polymer/polymer-micro.html b/example/bower_components/polymer/polymer-micro.html new file mode 100644 index 000000000..4acbc14ee --- /dev/null +++ b/example/bower_components/polymer/polymer-micro.html @@ -0,0 +1,35 @@ + + + + + + + + + + + diff --git a/example/bower_components/polymer/polymer-mini.html b/example/bower_components/polymer/polymer-mini.html new file mode 100644 index 000000000..50b089bf7 --- /dev/null +++ b/example/bower_components/polymer/polymer-mini.html @@ -0,0 +1,45 @@ + + + + + + + + + + + + diff --git a/example/bower_components/polymer/polymer.html b/example/bower_components/polymer/polymer.html new file mode 100644 index 000000000..114fa8317 --- /dev/null +++ b/example/bower_components/polymer/polymer.html @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + diff --git a/example/bower_components/polymer/src/expr/focus.html b/example/bower_components/polymer/src/expr/focus.html new file mode 100644 index 000000000..d02e74e61 --- /dev/null +++ b/example/bower_components/polymer/src/expr/focus.html @@ -0,0 +1,22 @@ + + diff --git a/example/bower_components/polymer/src/expr/gestures.html b/example/bower_components/polymer/src/expr/gestures.html new file mode 100644 index 000000000..0c4560412 --- /dev/null +++ b/example/bower_components/polymer/src/expr/gestures.html @@ -0,0 +1 @@ + diff --git a/example/bower_components/polymer/src/expr/log.html b/example/bower_components/polymer/src/expr/log.html new file mode 100644 index 000000000..05d8fceea --- /dev/null +++ b/example/bower_components/polymer/src/expr/log.html @@ -0,0 +1,21 @@ + + diff --git a/example/bower_components/polymer/src/expr/polymer-expr.html b/example/bower_components/polymer/src/expr/polymer-expr.html new file mode 100644 index 000000000..226374470 --- /dev/null +++ b/example/bower_components/polymer/src/expr/polymer-expr.html @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/example/bower_components/polymer/src/expr/sinspect.html b/example/bower_components/polymer/src/expr/sinspect.html new file mode 100644 index 000000000..009653a26 --- /dev/null +++ b/example/bower_components/polymer/src/expr/sinspect.html @@ -0,0 +1,235 @@ + + diff --git a/example/bower_components/polymer/src/expr/x-styling-defaults.html b/example/bower_components/polymer/src/expr/x-styling-defaults.html new file mode 100644 index 000000000..4c986c8a0 --- /dev/null +++ b/example/bower_components/polymer/src/expr/x-styling-defaults.html @@ -0,0 +1,61 @@ + + + diff --git a/example/bower_components/polymer/src/expr/x-styling.html b/example/bower_components/polymer/src/expr/x-styling.html new file mode 100644 index 000000000..8ec72e092 --- /dev/null +++ b/example/bower_components/polymer/src/expr/x-styling.html @@ -0,0 +1,283 @@ + + + + + + diff --git a/example/bower_components/polymer/src/features/micro/attributes.html b/example/bower_components/polymer/src/features/micro/attributes.html new file mode 100644 index 000000000..17e5e3ea2 --- /dev/null +++ b/example/bower_components/polymer/src/features/micro/attributes.html @@ -0,0 +1,176 @@ + + + + + diff --git a/example/bower_components/polymer/src/features/micro/constructor.html b/example/bower_components/polymer/src/features/micro/constructor.html new file mode 100644 index 000000000..b7e656eef --- /dev/null +++ b/example/bower_components/polymer/src/features/micro/constructor.html @@ -0,0 +1,74 @@ + + diff --git a/example/bower_components/polymer/src/features/micro/extends.html b/example/bower_components/polymer/src/features/micro/extends.html new file mode 100644 index 000000000..53805f425 --- /dev/null +++ b/example/bower_components/polymer/src/features/micro/extends.html @@ -0,0 +1,79 @@ + + diff --git a/example/bower_components/polymer/src/features/micro/mixins.html b/example/bower_components/polymer/src/features/micro/mixins.html new file mode 100644 index 000000000..fa1114fc5 --- /dev/null +++ b/example/bower_components/polymer/src/features/micro/mixins.html @@ -0,0 +1,40 @@ + + diff --git a/example/bower_components/polymer/src/features/micro/properties.html b/example/bower_components/polymer/src/features/micro/properties.html new file mode 100644 index 000000000..85d005029 --- /dev/null +++ b/example/bower_components/polymer/src/features/micro/properties.html @@ -0,0 +1,96 @@ + + diff --git a/example/bower_components/polymer/src/features/mini/ready.html b/example/bower_components/polymer/src/features/mini/ready.html new file mode 100644 index 000000000..91341b9a5 --- /dev/null +++ b/example/bower_components/polymer/src/features/mini/ready.html @@ -0,0 +1,120 @@ + + diff --git a/example/bower_components/polymer/src/features/mini/shadow.html b/example/bower_components/polymer/src/features/mini/shadow.html new file mode 100644 index 000000000..ebcb8c098 --- /dev/null +++ b/example/bower_components/polymer/src/features/mini/shadow.html @@ -0,0 +1,41 @@ + + + diff --git a/example/bower_components/polymer/src/features/mini/shady.html b/example/bower_components/polymer/src/features/mini/shady.html new file mode 100644 index 000000000..25763e2be --- /dev/null +++ b/example/bower_components/polymer/src/features/mini/shady.html @@ -0,0 +1,339 @@ + + + + diff --git a/example/bower_components/polymer/src/features/mini/template.html b/example/bower_components/polymer/src/features/mini/template.html new file mode 100644 index 000000000..d0655d8b6 --- /dev/null +++ b/example/bower_components/polymer/src/features/mini/template.html @@ -0,0 +1,60 @@ + + diff --git a/example/bower_components/polymer/src/features/standard/annotations.html b/example/bower_components/polymer/src/features/standard/annotations.html new file mode 100644 index 000000000..9c2fb2c02 --- /dev/null +++ b/example/bower_components/polymer/src/features/standard/annotations.html @@ -0,0 +1,194 @@ + + + + + + + diff --git a/example/bower_components/polymer/src/features/standard/configure.html b/example/bower_components/polymer/src/features/standard/configure.html new file mode 100644 index 000000000..266bd0ebe --- /dev/null +++ b/example/bower_components/polymer/src/features/standard/configure.html @@ -0,0 +1,162 @@ + + + \ No newline at end of file diff --git a/example/bower_components/polymer/src/features/standard/effects.html b/example/bower_components/polymer/src/features/standard/effects.html new file mode 100644 index 000000000..ad61d5556 --- /dev/null +++ b/example/bower_components/polymer/src/features/standard/effects.html @@ -0,0 +1,149 @@ + + + + + + + diff --git a/example/bower_components/polymer/src/features/standard/events.html b/example/bower_components/polymer/src/features/standard/events.html new file mode 100644 index 000000000..a7b9d929b --- /dev/null +++ b/example/bower_components/polymer/src/features/standard/events.html @@ -0,0 +1,114 @@ + + diff --git a/example/bower_components/polymer/src/features/standard/notify-path.html b/example/bower_components/polymer/src/features/standard/notify-path.html new file mode 100644 index 000000000..097d35b29 --- /dev/null +++ b/example/bower_components/polymer/src/features/standard/notify-path.html @@ -0,0 +1,266 @@ + + diff --git a/example/bower_components/polymer/src/features/standard/resolveUrl.html b/example/bower_components/polymer/src/features/standard/resolveUrl.html new file mode 100644 index 000000000..f715f9bd1 --- /dev/null +++ b/example/bower_components/polymer/src/features/standard/resolveUrl.html @@ -0,0 +1,27 @@ + + diff --git a/example/bower_components/polymer/src/features/standard/styling.html b/example/bower_components/polymer/src/features/standard/styling.html new file mode 100644 index 000000000..ed3f8d12a --- /dev/null +++ b/example/bower_components/polymer/src/features/standard/styling.html @@ -0,0 +1,149 @@ + + + + + + + + diff --git a/example/bower_components/polymer/src/features/standard/utils.html b/example/bower_components/polymer/src/features/standard/utils.html new file mode 100644 index 000000000..57bafccf9 --- /dev/null +++ b/example/bower_components/polymer/src/features/standard/utils.html @@ -0,0 +1,139 @@ + + + + + + diff --git a/example/bower_components/polymer/src/lib/annotations/annotations.html b/example/bower_components/polymer/src/lib/annotations/annotations.html new file mode 100644 index 000000000..226d65a13 --- /dev/null +++ b/example/bower_components/polymer/src/lib/annotations/annotations.html @@ -0,0 +1,273 @@ + + + + diff --git a/example/bower_components/polymer/src/lib/annotations/demo/app-chrome.html b/example/bower_components/polymer/src/lib/annotations/demo/app-chrome.html new file mode 100644 index 000000000..48030ab6d --- /dev/null +++ b/example/bower_components/polymer/src/lib/annotations/demo/app-chrome.html @@ -0,0 +1,60 @@ + + + + + + + Template Test + + + + + + + + + + + + + + + + + + +

+
+  
+
+  
+
+
+
diff --git a/example/bower_components/polymer/src/lib/array-observe.html b/example/bower_components/polymer/src/lib/array-observe.html
new file mode 100644
index 000000000..a99d01f29
--- /dev/null
+++ b/example/bower_components/polymer/src/lib/array-observe.html
@@ -0,0 +1,115 @@
+
+
+
+
diff --git a/example/bower_components/polymer/src/lib/array-splice.html b/example/bower_components/polymer/src/lib/array-splice.html
new file mode 100644
index 000000000..f51279a71
--- /dev/null
+++ b/example/bower_components/polymer/src/lib/array-splice.html
@@ -0,0 +1,262 @@
+
+
\ No newline at end of file
diff --git a/example/bower_components/polymer/src/lib/async.html b/example/bower_components/polymer/src/lib/async.html
new file mode 100644
index 000000000..652bf53c8
--- /dev/null
+++ b/example/bower_components/polymer/src/lib/async.html
@@ -0,0 +1,68 @@
+
+
diff --git a/example/bower_components/polymer/src/lib/base.html b/example/bower_components/polymer/src/lib/base.html
new file mode 100644
index 000000000..a195eaecf
--- /dev/null
+++ b/example/bower_components/polymer/src/lib/base.html
@@ -0,0 +1,117 @@
+
+
diff --git a/example/bower_components/polymer/src/lib/bind/bind-annotations.html b/example/bower_components/polymer/src/lib/bind/bind-annotations.html
new file mode 100644
index 000000000..84e280cb3
--- /dev/null
+++ b/example/bower_components/polymer/src/lib/bind/bind-annotations.html
@@ -0,0 +1,74 @@
+
+
+
diff --git a/example/bower_components/polymer/src/lib/bind/bind-effects.html b/example/bower_components/polymer/src/lib/bind/bind-effects.html
new file mode 100644
index 000000000..652e5fd00
--- /dev/null
+++ b/example/bower_components/polymer/src/lib/bind/bind-effects.html
@@ -0,0 +1,188 @@
+
+
diff --git a/example/bower_components/polymer/src/lib/bind/bind.html b/example/bower_components/polymer/src/lib/bind/bind.html
new file mode 100644
index 000000000..20b5051f9
--- /dev/null
+++ b/example/bower_components/polymer/src/lib/bind/bind.html
@@ -0,0 +1,218 @@
+
+
diff --git a/example/bower_components/polymer/src/lib/bind/demo/app-chrome.html b/example/bower_components/polymer/src/lib/bind/demo/app-chrome.html
new file mode 100644
index 000000000..d5be36edb
--- /dev/null
+++ b/example/bower_components/polymer/src/lib/bind/demo/app-chrome.html
@@ -0,0 +1,28 @@
+
+
+
+
+  Bind Test
+
+  
+  
+
+  
+
+  
+  
+
+
+
+
+  

+
+  

+
+
+
diff --git a/example/bower_components/polymer/src/lib/bind/demo/app.html b/example/bower_components/polymer/src/lib/bind/demo/app.html
new file mode 100644
index 000000000..fe7d2160b
--- /dev/null
+++ b/example/bower_components/polymer/src/lib/bind/demo/app.html
@@ -0,0 +1,29 @@
+
+
+
+
+  Bind Test
+
+  
+  
+
+  
+
+  
+
+  
+  
+
+
+
+
+  

+  

+
+
+
diff --git a/example/bower_components/polymer/src/lib/bind/demo/src/annotations-bind-demo.html b/example/bower_components/polymer/src/lib/bind/demo/src/annotations-bind-demo.html
new file mode 100644
index 000000000..747ba0899
--- /dev/null
+++ b/example/bower_components/polymer/src/lib/bind/demo/src/annotations-bind-demo.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/example/bower_components/polymer/src/lib/bind/demo/src/bind-demo.html b/example/bower_components/polymer/src/lib/bind/demo/src/bind-demo.html
new file mode 100644
index 000000000..dcb9e9cdb
--- /dev/null
+++ b/example/bower_components/polymer/src/lib/bind/demo/src/bind-demo.html
@@ -0,0 +1,83 @@
+
+
+
+  
+
\ No newline at end of file
diff --git a/example/bower_components/polymer/src/lib/collection.html b/example/bower_components/polymer/src/lib/collection.html
new file mode 100644
index 000000000..5717b1aec
--- /dev/null
+++ b/example/bower_components/polymer/src/lib/collection.html
@@ -0,0 +1,164 @@
+
+
+
+
+
+
diff --git a/example/bower_components/polymer/src/lib/css-parse.html b/example/bower_components/polymer/src/lib/css-parse.html
new file mode 100644
index 000000000..97deac195
--- /dev/null
+++ b/example/bower_components/polymer/src/lib/css-parse.html
@@ -0,0 +1,131 @@
+
\ No newline at end of file
diff --git a/example/bower_components/polymer/src/lib/debounce.html b/example/bower_components/polymer/src/lib/debounce.html
new file mode 100644
index 000000000..f78767017
--- /dev/null
+++ b/example/bower_components/polymer/src/lib/debounce.html
@@ -0,0 +1,69 @@
+
+
diff --git a/example/bower_components/polymer/src/lib/dom-api.html b/example/bower_components/polymer/src/lib/dom-api.html
new file mode 100644
index 000000000..34338eee5
--- /dev/null
+++ b/example/bower_components/polymer/src/lib/dom-api.html
@@ -0,0 +1,393 @@
+
+
+
diff --git a/example/bower_components/polymer/src/lib/dom-module.html b/example/bower_components/polymer/src/lib/dom-module.html
new file mode 100644
index 000000000..e97de14f5
--- /dev/null
+++ b/example/bower_components/polymer/src/lib/dom-module.html
@@ -0,0 +1,50 @@
+
\ No newline at end of file
diff --git a/example/bower_components/polymer/src/lib/lang.html b/example/bower_components/polymer/src/lib/lang.html
new file mode 100644
index 000000000..d80e8fd1b
--- /dev/null
+++ b/example/bower_components/polymer/src/lib/lang.html
@@ -0,0 +1,21 @@
+
+
diff --git a/example/bower_components/polymer/src/lib/module.html b/example/bower_components/polymer/src/lib/module.html
new file mode 100644
index 000000000..4bbd6b384
--- /dev/null
+++ b/example/bower_components/polymer/src/lib/module.html
@@ -0,0 +1,56 @@
+
+
diff --git a/example/bower_components/polymer/src/lib/polymer.html b/example/bower_components/polymer/src/lib/polymer.html
new file mode 100644
index 000000000..1819f42da
--- /dev/null
+++ b/example/bower_components/polymer/src/lib/polymer.html
@@ -0,0 +1,78 @@
+
+
+
diff --git a/example/bower_components/polymer/src/lib/resolve-url.html b/example/bower_components/polymer/src/lib/resolve-url.html
new file mode 100644
index 000000000..9d6e18684
--- /dev/null
+++ b/example/bower_components/polymer/src/lib/resolve-url.html
@@ -0,0 +1,82 @@
+
+
\ No newline at end of file
diff --git a/example/bower_components/polymer/src/lib/settings.html b/example/bower_components/polymer/src/lib/settings.html
new file mode 100644
index 000000000..f7ae9c5b8
--- /dev/null
+++ b/example/bower_components/polymer/src/lib/settings.html
@@ -0,0 +1,48 @@
+
+
\ No newline at end of file
diff --git a/example/bower_components/polymer/src/lib/style-transformer.html b/example/bower_components/polymer/src/lib/style-transformer.html
new file mode 100644
index 000000000..e39833c20
--- /dev/null
+++ b/example/bower_components/polymer/src/lib/style-transformer.html
@@ -0,0 +1,166 @@
+
+
+
+
+
diff --git a/example/bower_components/polymer/src/lib/style-util.html b/example/bower_components/polymer/src/lib/style-util.html
new file mode 100644
index 000000000..b9634e43a
--- /dev/null
+++ b/example/bower_components/polymer/src/lib/style-util.html
@@ -0,0 +1,77 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/example/bower_components/polymer/src/lib/template/templatizer.html b/example/bower_components/polymer/src/lib/template/templatizer.html
new file mode 100644
index 000000000..bab1c06f9
--- /dev/null
+++ b/example/bower_components/polymer/src/lib/template/templatizer.html
@@ -0,0 +1,117 @@
+
+
+
\ No newline at end of file
diff --git a/example/bower_components/polymer/src/lib/template/x-array-selector.html b/example/bower_components/polymer/src/lib/template/x-array-selector.html
new file mode 100644
index 000000000..9d90cd304
--- /dev/null
+++ b/example/bower_components/polymer/src/lib/template/x-array-selector.html
@@ -0,0 +1,94 @@
+
+
+
diff --git a/example/bower_components/polymer/src/lib/template/x-autobind.html b/example/bower_components/polymer/src/lib/template/x-autobind.html
new file mode 100644
index 000000000..5e78eb657
--- /dev/null
+++ b/example/bower_components/polymer/src/lib/template/x-autobind.html
@@ -0,0 +1,36 @@
+
+
+
diff --git a/example/bower_components/polymer/src/lib/template/x-repeat.html b/example/bower_components/polymer/src/lib/template/x-repeat.html
new file mode 100644
index 000000000..ce85afabb
--- /dev/null
+++ b/example/bower_components/polymer/src/lib/template/x-repeat.html
@@ -0,0 +1,389 @@
+
+
+
+
+
+
+
diff --git a/example/bower_components/polymer/src/lib/template/x-template.html b/example/bower_components/polymer/src/lib/template/x-template.html
new file mode 100644
index 000000000..da2430c2e
--- /dev/null
+++ b/example/bower_components/polymer/src/lib/template/x-template.html
@@ -0,0 +1,39 @@
+
+
+
+
+
diff --git a/example/bower_components/polymer/src/polymer.html b/example/bower_components/polymer/src/polymer.html
new file mode 100644
index 000000000..e4627ca77
--- /dev/null
+++ b/example/bower_components/polymer/src/polymer.html
@@ -0,0 +1,14 @@
+
+
+
+
+
+
diff --git a/example/bower_components/polymer/wct.conf.js b/example/bower_components/polymer/wct.conf.js
new file mode 100644
index 000000000..111deea50
--- /dev/null
+++ b/example/bower_components/polymer/wct.conf.js
@@ -0,0 +1,3 @@
+module.exports = {
+  suites: ['test/runner.html'], 
+};
diff --git a/example/bower_components/webcomponentsjs/.bower.json b/example/bower_components/webcomponentsjs/.bower.json
new file mode 100644
index 000000000..afd9ea954
--- /dev/null
+++ b/example/bower_components/webcomponentsjs/.bower.json
@@ -0,0 +1,24 @@
+{
+  "name": "webcomponentsjs",
+  "main": "webcomponents.js",
+  "version": "0.5.5",
+  "homepage": "http://webcomponents.org",
+  "authors": [
+    "The Polymer Authors"
+  ],
+  "keywords": [
+    "webcomponents"
+  ],
+  "license": "BSD",
+  "ignore": [],
+  "_release": "0.5.5",
+  "_resolution": {
+    "type": "version",
+    "tag": "0.5.5",
+    "commit": "46f8f2665f7b91e3f248bc9bdb20a29b91f921b5"
+  },
+  "_source": "git://github.com/webcomponents/webcomponentsjs.git",
+  "_target": "~0.5.5",
+  "_originalSource": "webcomponents/webcomponentsjs",
+  "_direct": true
+}
\ No newline at end of file
diff --git a/example/bower_components/webcomponentsjs/CustomElements.js b/example/bower_components/webcomponentsjs/CustomElements.js
new file mode 100644
index 000000000..8ec15f6b8
--- /dev/null
+++ b/example/bower_components/webcomponentsjs/CustomElements.js
@@ -0,0 +1,634 @@
+/**
+ * @license
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// @version 0.5.5
+if (typeof WeakMap === "undefined") {
+  (function() {
+    var defineProperty = Object.defineProperty;
+    var counter = Date.now() % 1e9;
+    var WeakMap = function() {
+      this.name = "__st" + (Math.random() * 1e9 >>> 0) + (counter++ + "__");
+    };
+    WeakMap.prototype = {
+      set: function(key, value) {
+        var entry = key[this.name];
+        if (entry && entry[0] === key) entry[1] = value; else defineProperty(key, this.name, {
+          value: [ key, value ],
+          writable: true
+        });
+        return this;
+      },
+      get: function(key) {
+        var entry;
+        return (entry = key[this.name]) && entry[0] === key ? entry[1] : undefined;
+      },
+      "delete": function(key) {
+        var entry = key[this.name];
+        if (!entry || entry[0] !== key) return false;
+        entry[0] = entry[1] = undefined;
+        return true;
+      },
+      has: function(key) {
+        var entry = key[this.name];
+        if (!entry) return false;
+        return entry[0] === key;
+      }
+    };
+    window.WeakMap = WeakMap;
+  })();
+}
+
+window.CustomElements = window.CustomElements || {
+  flags: {}
+};
+
+(function(scope) {
+  var flags = scope.flags;
+  var modules = [];
+  var addModule = function(module) {
+    modules.push(module);
+  };
+  var initializeModules = function() {
+    modules.forEach(function(module) {
+      module(scope);
+    });
+  };
+  scope.addModule = addModule;
+  scope.initializeModules = initializeModules;
+  scope.hasNative = Boolean(document.registerElement);
+  scope.useNative = !flags.register && scope.hasNative && !window.ShadowDOMPolyfill && (!window.HTMLImports || HTMLImports.useNative);
+})(CustomElements);
+
+CustomElements.addModule(function(scope) {
+  var IMPORT_LINK_TYPE = window.HTMLImports ? HTMLImports.IMPORT_LINK_TYPE : "none";
+  function forSubtree(node, cb) {
+    findAllElements(node, function(e) {
+      if (cb(e)) {
+        return true;
+      }
+      forRoots(e, cb);
+    });
+    forRoots(node, cb);
+  }
+  function findAllElements(node, find, data) {
+    var e = node.firstElementChild;
+    if (!e) {
+      e = node.firstChild;
+      while (e && e.nodeType !== Node.ELEMENT_NODE) {
+        e = e.nextSibling;
+      }
+    }
+    while (e) {
+      if (find(e, data) !== true) {
+        findAllElements(e, find, data);
+      }
+      e = e.nextElementSibling;
+    }
+    return null;
+  }
+  function forRoots(node, cb) {
+    var root = node.shadowRoot;
+    while (root) {
+      forSubtree(root, cb);
+      root = root.olderShadowRoot;
+    }
+  }
+  var processingDocuments;
+  function forDocumentTree(doc, cb) {
+    processingDocuments = [];
+    _forDocumentTree(doc, cb);
+    processingDocuments = null;
+  }
+  function _forDocumentTree(doc, cb) {
+    doc = wrap(doc);
+    if (processingDocuments.indexOf(doc) >= 0) {
+      return;
+    }
+    processingDocuments.push(doc);
+    var imports = doc.querySelectorAll("link[rel=" + IMPORT_LINK_TYPE + "]");
+    for (var i = 0, l = imports.length, n; i < l && (n = imports[i]); i++) {
+      if (n.import) {
+        _forDocumentTree(n.import, cb);
+      }
+    }
+    cb(doc);
+  }
+  scope.forDocumentTree = forDocumentTree;
+  scope.forSubtree = forSubtree;
+});
+
+CustomElements.addModule(function(scope) {
+  var flags = scope.flags;
+  var forSubtree = scope.forSubtree;
+  var forDocumentTree = scope.forDocumentTree;
+  function addedNode(node) {
+    return added(node) || addedSubtree(node);
+  }
+  function added(node) {
+    if (scope.upgrade(node)) {
+      return true;
+    }
+    attached(node);
+  }
+  function addedSubtree(node) {
+    forSubtree(node, function(e) {
+      if (added(e)) {
+        return true;
+      }
+    });
+  }
+  function attachedNode(node) {
+    attached(node);
+    if (inDocument(node)) {
+      forSubtree(node, function(e) {
+        attached(e);
+      });
+    }
+  }
+  var hasPolyfillMutations = !window.MutationObserver || window.MutationObserver === window.JsMutationObserver;
+  scope.hasPolyfillMutations = hasPolyfillMutations;
+  var isPendingMutations = false;
+  var pendingMutations = [];
+  function deferMutation(fn) {
+    pendingMutations.push(fn);
+    if (!isPendingMutations) {
+      isPendingMutations = true;
+      setTimeout(takeMutations);
+    }
+  }
+  function takeMutations() {
+    isPendingMutations = false;
+    var $p = pendingMutations;
+    for (var i = 0, l = $p.length, p; i < l && (p = $p[i]); i++) {
+      p();
+    }
+    pendingMutations = [];
+  }
+  function attached(element) {
+    if (hasPolyfillMutations) {
+      deferMutation(function() {
+        _attached(element);
+      });
+    } else {
+      _attached(element);
+    }
+  }
+  function _attached(element) {
+    if (element.__upgraded__ && (element.attachedCallback || element.detachedCallback)) {
+      if (!element.__attached && inDocument(element)) {
+        element.__attached = true;
+        if (element.attachedCallback) {
+          element.attachedCallback();
+        }
+      }
+    }
+  }
+  function detachedNode(node) {
+    detached(node);
+    forSubtree(node, function(e) {
+      detached(e);
+    });
+  }
+  function detached(element) {
+    if (hasPolyfillMutations) {
+      deferMutation(function() {
+        _detached(element);
+      });
+    } else {
+      _detached(element);
+    }
+  }
+  function _detached(element) {
+    if (element.__upgraded__ && (element.attachedCallback || element.detachedCallback)) {
+      if (element.__attached && !inDocument(element)) {
+        element.__attached = false;
+        if (element.detachedCallback) {
+          element.detachedCallback();
+        }
+      }
+    }
+  }
+  function inDocument(element) {
+    var p = element;
+    var doc = wrap(document);
+    while (p) {
+      if (p == doc) {
+        return true;
+      }
+      p = p.parentNode || p.host;
+    }
+  }
+  function watchShadow(node) {
+    if (node.shadowRoot && !node.shadowRoot.__watched) {
+      flags.dom && console.log("watching shadow-root for: ", node.localName);
+      var root = node.shadowRoot;
+      while (root) {
+        observe(root);
+        root = root.olderShadowRoot;
+      }
+    }
+  }
+  function handler(mutations) {
+    if (flags.dom) {
+      var mx = mutations[0];
+      if (mx && mx.type === "childList" && mx.addedNodes) {
+        if (mx.addedNodes) {
+          var d = mx.addedNodes[0];
+          while (d && d !== document && !d.host) {
+            d = d.parentNode;
+          }
+          var u = d && (d.URL || d._URL || d.host && d.host.localName) || "";
+          u = u.split("/?").shift().split("/").pop();
+        }
+      }
+      console.group("mutations (%d) [%s]", mutations.length, u || "");
+    }
+    mutations.forEach(function(mx) {
+      if (mx.type === "childList") {
+        forEach(mx.addedNodes, function(n) {
+          if (!n.localName) {
+            return;
+          }
+          addedNode(n);
+        });
+        forEach(mx.removedNodes, function(n) {
+          if (!n.localName) {
+            return;
+          }
+          detachedNode(n);
+        });
+      }
+    });
+    flags.dom && console.groupEnd();
+  }
+  function takeRecords(node) {
+    node = wrap(node);
+    if (!node) {
+      node = wrap(document);
+    }
+    while (node.parentNode) {
+      node = node.parentNode;
+    }
+    var observer = node.__observer;
+    if (observer) {
+      handler(observer.takeRecords());
+      takeMutations();
+    }
+  }
+  var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);
+  function observe(inRoot) {
+    if (inRoot.__observer) {
+      return;
+    }
+    var observer = new MutationObserver(handler);
+    observer.observe(inRoot, {
+      childList: true,
+      subtree: true
+    });
+    inRoot.__observer = observer;
+  }
+  function upgradeDocument(doc) {
+    doc = wrap(doc);
+    flags.dom && console.group("upgradeDocument: ", doc.baseURI.split("/").pop());
+    addedNode(doc);
+    observe(doc);
+    flags.dom && console.groupEnd();
+  }
+  function upgradeDocumentTree(doc) {
+    forDocumentTree(doc, upgradeDocument);
+  }
+  var originalCreateShadowRoot = Element.prototype.createShadowRoot;
+  if (originalCreateShadowRoot) {
+    Element.prototype.createShadowRoot = function() {
+      var root = originalCreateShadowRoot.call(this);
+      CustomElements.watchShadow(this);
+      return root;
+    };
+  }
+  scope.watchShadow = watchShadow;
+  scope.upgradeDocumentTree = upgradeDocumentTree;
+  scope.upgradeSubtree = addedSubtree;
+  scope.upgradeAll = addedNode;
+  scope.attachedNode = attachedNode;
+  scope.takeRecords = takeRecords;
+});
+
+CustomElements.addModule(function(scope) {
+  var flags = scope.flags;
+  function upgrade(node) {
+    if (!node.__upgraded__ && node.nodeType === Node.ELEMENT_NODE) {
+      var is = node.getAttribute("is");
+      var definition = scope.getRegisteredDefinition(is || node.localName);
+      if (definition) {
+        if (is && definition.tag == node.localName) {
+          return upgradeWithDefinition(node, definition);
+        } else if (!is && !definition.extends) {
+          return upgradeWithDefinition(node, definition);
+        }
+      }
+    }
+  }
+  function upgradeWithDefinition(element, definition) {
+    flags.upgrade && console.group("upgrade:", element.localName);
+    if (definition.is) {
+      element.setAttribute("is", definition.is);
+    }
+    implementPrototype(element, definition);
+    element.__upgraded__ = true;
+    created(element);
+    scope.attachedNode(element);
+    scope.upgradeSubtree(element);
+    flags.upgrade && console.groupEnd();
+    return element;
+  }
+  function implementPrototype(element, definition) {
+    if (Object.__proto__) {
+      element.__proto__ = definition.prototype;
+    } else {
+      customMixin(element, definition.prototype, definition.native);
+      element.__proto__ = definition.prototype;
+    }
+  }
+  function customMixin(inTarget, inSrc, inNative) {
+    var used = {};
+    var p = inSrc;
+    while (p !== inNative && p !== HTMLElement.prototype) {
+      var keys = Object.getOwnPropertyNames(p);
+      for (var i = 0, k; k = keys[i]; i++) {
+        if (!used[k]) {
+          Object.defineProperty(inTarget, k, Object.getOwnPropertyDescriptor(p, k));
+          used[k] = 1;
+        }
+      }
+      p = Object.getPrototypeOf(p);
+    }
+  }
+  function created(element) {
+    if (element.createdCallback) {
+      element.createdCallback();
+    }
+  }
+  scope.upgrade = upgrade;
+  scope.upgradeWithDefinition = upgradeWithDefinition;
+  scope.implementPrototype = implementPrototype;
+});
+
+CustomElements.addModule(function(scope) {
+  var upgradeDocumentTree = scope.upgradeDocumentTree;
+  var upgrade = scope.upgrade;
+  var upgradeWithDefinition = scope.upgradeWithDefinition;
+  var implementPrototype = scope.implementPrototype;
+  var useNative = scope.useNative;
+  function register(name, options) {
+    var definition = options || {};
+    if (!name) {
+      throw new Error("document.registerElement: first argument `name` must not be empty");
+    }
+    if (name.indexOf("-") < 0) {
+      throw new Error("document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '" + String(name) + "'.");
+    }
+    if (isReservedTag(name)) {
+      throw new Error("Failed to execute 'registerElement' on 'Document': Registration failed for type '" + String(name) + "'. The type name is invalid.");
+    }
+    if (getRegisteredDefinition(name)) {
+      throw new Error("DuplicateDefinitionError: a type with name '" + String(name) + "' is already registered");
+    }
+    if (!definition.prototype) {
+      definition.prototype = Object.create(HTMLElement.prototype);
+    }
+    definition.__name = name.toLowerCase();
+    definition.lifecycle = definition.lifecycle || {};
+    definition.ancestry = ancestry(definition.extends);
+    resolveTagName(definition);
+    resolvePrototypeChain(definition);
+    overrideAttributeApi(definition.prototype);
+    registerDefinition(definition.__name, definition);
+    definition.ctor = generateConstructor(definition);
+    definition.ctor.prototype = definition.prototype;
+    definition.prototype.constructor = definition.ctor;
+    if (scope.ready) {
+      upgradeDocumentTree(document);
+    }
+    return definition.ctor;
+  }
+  function overrideAttributeApi(prototype) {
+    if (prototype.setAttribute._polyfilled) {
+      return;
+    }
+    var setAttribute = prototype.setAttribute;
+    prototype.setAttribute = function(name, value) {
+      changeAttribute.call(this, name, value, setAttribute);
+    };
+    var removeAttribute = prototype.removeAttribute;
+    prototype.removeAttribute = function(name) {
+      changeAttribute.call(this, name, null, removeAttribute);
+    };
+    prototype.setAttribute._polyfilled = true;
+  }
+  function changeAttribute(name, value, operation) {
+    name = name.toLowerCase();
+    var oldValue = this.getAttribute(name);
+    operation.apply(this, arguments);
+    var newValue = this.getAttribute(name);
+    if (this.attributeChangedCallback && newValue !== oldValue) {
+      this.attributeChangedCallback(name, oldValue, newValue);
+    }
+  }
+  function isReservedTag(name) {
+    for (var i = 0; i < reservedTagList.length; i++) {
+      if (name === reservedTagList[i]) {
+        return true;
+      }
+    }
+  }
+  var reservedTagList = [ "annotation-xml", "color-profile", "font-face", "font-face-src", "font-face-uri", "font-face-format", "font-face-name", "missing-glyph" ];
+  function ancestry(extnds) {
+    var extendee = getRegisteredDefinition(extnds);
+    if (extendee) {
+      return ancestry(extendee.extends).concat([ extendee ]);
+    }
+    return [];
+  }
+  function resolveTagName(definition) {
+    var baseTag = definition.extends;
+    for (var i = 0, a; a = definition.ancestry[i]; i++) {
+      baseTag = a.is && a.tag;
+    }
+    definition.tag = baseTag || definition.__name;
+    if (baseTag) {
+      definition.is = definition.__name;
+    }
+  }
+  function resolvePrototypeChain(definition) {
+    if (!Object.__proto__) {
+      var nativePrototype = HTMLElement.prototype;
+      if (definition.is) {
+        var inst = document.createElement(definition.tag);
+        var expectedPrototype = Object.getPrototypeOf(inst);
+        if (expectedPrototype === definition.prototype) {
+          nativePrototype = expectedPrototype;
+        }
+      }
+      var proto = definition.prototype, ancestor;
+      while (proto && proto !== nativePrototype) {
+        ancestor = Object.getPrototypeOf(proto);
+        proto.__proto__ = ancestor;
+        proto = ancestor;
+      }
+      definition.native = nativePrototype;
+    }
+  }
+  function instantiate(definition) {
+    return upgradeWithDefinition(domCreateElement(definition.tag), definition);
+  }
+  var registry = {};
+  function getRegisteredDefinition(name) {
+    if (name) {
+      return registry[name.toLowerCase()];
+    }
+  }
+  function registerDefinition(name, definition) {
+    registry[name] = definition;
+  }
+  function generateConstructor(definition) {
+    return function() {
+      return instantiate(definition);
+    };
+  }
+  var HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
+  function createElementNS(namespace, tag, typeExtension) {
+    if (namespace === HTML_NAMESPACE) {
+      return createElement(tag, typeExtension);
+    } else {
+      return domCreateElementNS(namespace, tag);
+    }
+  }
+  function createElement(tag, typeExtension) {
+    var definition = getRegisteredDefinition(typeExtension || tag);
+    if (definition) {
+      if (tag == definition.tag && typeExtension == definition.is) {
+        return new definition.ctor();
+      }
+      if (!typeExtension && !definition.is) {
+        return new definition.ctor();
+      }
+    }
+    var element;
+    if (typeExtension) {
+      element = createElement(tag);
+      element.setAttribute("is", typeExtension);
+      return element;
+    }
+    element = domCreateElement(tag);
+    if (tag.indexOf("-") >= 0) {
+      implementPrototype(element, HTMLElement);
+    }
+    return element;
+  }
+  function cloneNode(deep) {
+    var n = domCloneNode.call(this, deep);
+    upgrade(n);
+    return n;
+  }
+  var domCreateElement = document.createElement.bind(document);
+  var domCreateElementNS = document.createElementNS.bind(document);
+  var domCloneNode = Node.prototype.cloneNode;
+  var isInstance;
+  if (!Object.__proto__ && !useNative) {
+    isInstance = function(obj, ctor) {
+      var p = obj;
+      while (p) {
+        if (p === ctor.prototype) {
+          return true;
+        }
+        p = p.__proto__;
+      }
+      return false;
+    };
+  } else {
+    isInstance = function(obj, base) {
+      return obj instanceof base;
+    };
+  }
+  document.registerElement = register;
+  document.createElement = createElement;
+  document.createElementNS = createElementNS;
+  Node.prototype.cloneNode = cloneNode;
+  scope.registry = registry;
+  scope.instanceof = isInstance;
+  scope.reservedTagList = reservedTagList;
+  scope.getRegisteredDefinition = getRegisteredDefinition;
+  document.register = document.registerElement;
+});
+
+(function(scope) {
+  var useNative = scope.useNative;
+  var initializeModules = scope.initializeModules;
+  var isIE11OrOlder = /Trident/.test(navigator.userAgent);
+  if (useNative) {
+    var nop = function() {};
+    scope.watchShadow = nop;
+    scope.upgrade = nop;
+    scope.upgradeAll = nop;
+    scope.upgradeDocumentTree = nop;
+    scope.upgradeSubtree = nop;
+    scope.takeRecords = nop;
+    scope.instanceof = function(obj, base) {
+      return obj instanceof base;
+    };
+  } else {
+    initializeModules();
+  }
+  var upgradeDocumentTree = scope.upgradeDocumentTree;
+  if (!window.wrap) {
+    if (window.ShadowDOMPolyfill) {
+      window.wrap = ShadowDOMPolyfill.wrapIfNeeded;
+      window.unwrap = ShadowDOMPolyfill.unwrapIfNeeded;
+    } else {
+      window.wrap = window.unwrap = function(node) {
+        return node;
+      };
+    }
+  }
+  function bootstrap() {
+    upgradeDocumentTree(wrap(document));
+    if (window.HTMLImports) {
+      HTMLImports.__importsParsingHook = function(elt) {
+        upgradeDocumentTree(wrap(elt.import));
+      };
+    }
+    CustomElements.ready = true;
+    setTimeout(function() {
+      CustomElements.readyTime = Date.now();
+      if (window.HTMLImports) {
+        CustomElements.elapsed = CustomElements.readyTime - HTMLImports.readyTime;
+      }
+      document.dispatchEvent(new CustomEvent("WebComponentsReady", {
+        bubbles: true
+      }));
+    });
+  }
+  if (isIE11OrOlder && typeof window.CustomEvent !== "function") {
+    window.CustomEvent = function(inType, params) {
+      params = params || {};
+      var e = document.createEvent("CustomEvent");
+      e.initCustomEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable), params.detail);
+      return e;
+    };
+    window.CustomEvent.prototype = window.Event.prototype;
+  }
+  if (document.readyState === "complete" || scope.flags.eager) {
+    bootstrap();
+  } else if (document.readyState === "interactive" && !window.attachEvent && (!window.HTMLImports || window.HTMLImports.ready)) {
+    bootstrap();
+  } else {
+    var loadEvent = window.HTMLImports && !HTMLImports.ready ? "HTMLImportsLoaded" : "DOMContentLoaded";
+    window.addEventListener(loadEvent, bootstrap);
+  }
+})(window.CustomElements);
\ No newline at end of file
diff --git a/example/bower_components/webcomponentsjs/CustomElements.min.js b/example/bower_components/webcomponentsjs/CustomElements.min.js
new file mode 100644
index 000000000..c29c57e3f
--- /dev/null
+++ b/example/bower_components/webcomponentsjs/CustomElements.min.js
@@ -0,0 +1,11 @@
+/**
+ * @license
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// @version 0.5.5
+"undefined"==typeof WeakMap&&!function(){var e=Object.defineProperty,t=Date.now()%1e9,o=function(){this.name="__st"+(1e9*Math.random()>>>0)+(t++ +"__")};o.prototype={set:function(t,o){var n=t[this.name];return n&&n[0]===t?n[1]=o:e(t,this.name,{value:[t,o],writable:!0}),this},get:function(e){var t;return(t=e[this.name])&&t[0]===e?t[1]:void 0},"delete":function(e){var t=e[this.name];return t&&t[0]===e?(t[0]=t[1]=void 0,!0):!1},has:function(e){var t=e[this.name];return t?t[0]===e:!1}},window.WeakMap=o}(),window.CustomElements=window.CustomElements||{flags:{}},function(e){var t=e.flags,o=[],n=function(e){o.push(e)},r=function(){o.forEach(function(t){t(e)})};e.addModule=n,e.initializeModules=r,e.hasNative=Boolean(document.registerElement),e.useNative=!t.register&&e.hasNative&&!window.ShadowDOMPolyfill&&(!window.HTMLImports||HTMLImports.useNative)}(CustomElements),CustomElements.addModule(function(e){function t(e,t){o(e,function(e){return t(e)?!0:void n(e,t)}),n(e,t)}function o(e,t,n){var r=e.firstElementChild;if(!r)for(r=e.firstChild;r&&r.nodeType!==Node.ELEMENT_NODE;)r=r.nextSibling;for(;r;)t(r,n)!==!0&&o(r,t,n),r=r.nextElementSibling;return null}function n(e,o){for(var n=e.shadowRoot;n;)t(n,o),n=n.olderShadowRoot}function r(e,t){i=[],a(e,t),i=null}function a(e,t){if(e=wrap(e),!(i.indexOf(e)>=0)){i.push(e);for(var o,n=e.querySelectorAll("link[rel="+u+"]"),r=0,d=n.length;d>r&&(o=n[r]);r++)o["import"]&&a(o["import"],t);t(e)}}var i,u=window.HTMLImports?HTMLImports.IMPORT_LINK_TYPE:"none";e.forDocumentTree=r,e.forSubtree=t}),CustomElements.addModule(function(e){function t(e){return o(e)||n(e)}function o(t){return e.upgrade(t)?!0:void u(t)}function n(e){y(e,function(e){return o(e)?!0:void 0})}function r(e){u(e),f(e)&&y(e,function(e){u(e)})}function a(e){M.push(e),C||(C=!0,setTimeout(i))}function i(){C=!1;for(var e,t=M,o=0,n=t.length;n>o&&(e=t[o]);o++)e();M=[]}function u(e){E?a(function(){d(e)}):d(e)}function d(e){e.__upgraded__&&(e.attachedCallback||e.detachedCallback)&&!e.__attached&&f(e)&&(e.__attached=!0,e.attachedCallback&&e.attachedCallback())}function c(e){s(e),y(e,function(e){s(e)})}function s(e){E?a(function(){l(e)}):l(e)}function l(e){e.__upgraded__&&(e.attachedCallback||e.detachedCallback)&&e.__attached&&!f(e)&&(e.__attached=!1,e.detachedCallback&&e.detachedCallback())}function f(e){for(var t=e,o=wrap(document);t;){if(t==o)return!0;t=t.parentNode||t.host}}function p(e){if(e.shadowRoot&&!e.shadowRoot.__watched){_.dom&&console.log("watching shadow-root for: ",e.localName);for(var t=e.shadowRoot;t;)h(t),t=t.olderShadowRoot}}function m(e){if(_.dom){var o=e[0];if(o&&"childList"===o.type&&o.addedNodes&&o.addedNodes){for(var n=o.addedNodes[0];n&&n!==document&&!n.host;)n=n.parentNode;var r=n&&(n.URL||n._URL||n.host&&n.host.localName)||"";r=r.split("/?").shift().split("/").pop()}console.group("mutations (%d) [%s]",e.length,r||"")}e.forEach(function(e){"childList"===e.type&&(N(e.addedNodes,function(e){e.localName&&t(e)}),N(e.removedNodes,function(e){e.localName&&c(e)}))}),_.dom&&console.groupEnd()}function w(e){for(e=wrap(e),e||(e=wrap(document));e.parentNode;)e=e.parentNode;var t=e.__observer;t&&(m(t.takeRecords()),i())}function h(e){if(!e.__observer){var t=new MutationObserver(m);t.observe(e,{childList:!0,subtree:!0}),e.__observer=t}}function g(e){e=wrap(e),_.dom&&console.group("upgradeDocument: ",e.baseURI.split("/").pop()),t(e),h(e),_.dom&&console.groupEnd()}function v(e){b(e,g)}var _=e.flags,y=e.forSubtree,b=e.forDocumentTree,E=!window.MutationObserver||window.MutationObserver===window.JsMutationObserver;e.hasPolyfillMutations=E;var C=!1,M=[],N=Array.prototype.forEach.call.bind(Array.prototype.forEach),T=Element.prototype.createShadowRoot;T&&(Element.prototype.createShadowRoot=function(){var e=T.call(this);return CustomElements.watchShadow(this),e}),e.watchShadow=p,e.upgradeDocumentTree=v,e.upgradeSubtree=n,e.upgradeAll=t,e.attachedNode=r,e.takeRecords=w}),CustomElements.addModule(function(e){function t(t){if(!t.__upgraded__&&t.nodeType===Node.ELEMENT_NODE){var n=t.getAttribute("is"),r=e.getRegisteredDefinition(n||t.localName);if(r){if(n&&r.tag==t.localName)return o(t,r);if(!n&&!r["extends"])return o(t,r)}}}function o(t,o){return i.upgrade&&console.group("upgrade:",t.localName),o.is&&t.setAttribute("is",o.is),n(t,o),t.__upgraded__=!0,a(t),e.attachedNode(t),e.upgradeSubtree(t),i.upgrade&&console.groupEnd(),t}function n(e,t){Object.__proto__?e.__proto__=t.prototype:(r(e,t.prototype,t["native"]),e.__proto__=t.prototype)}function r(e,t,o){for(var n={},r=t;r!==o&&r!==HTMLElement.prototype;){for(var a,i=Object.getOwnPropertyNames(r),u=0;a=i[u];u++)n[a]||(Object.defineProperty(e,a,Object.getOwnPropertyDescriptor(r,a)),n[a]=1);r=Object.getPrototypeOf(r)}}function a(e){e.createdCallback&&e.createdCallback()}var i=e.flags;e.upgrade=t,e.upgradeWithDefinition=o,e.implementPrototype=n}),CustomElements.addModule(function(e){function t(t,n){var d=n||{};if(!t)throw new Error("document.registerElement: first argument `name` must not be empty");if(t.indexOf("-")<0)throw new Error("document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '"+String(t)+"'.");if(r(t))throw new Error("Failed to execute 'registerElement' on 'Document': Registration failed for type '"+String(t)+"'. The type name is invalid.");if(c(t))throw new Error("DuplicateDefinitionError: a type with name '"+String(t)+"' is already registered");return d.prototype||(d.prototype=Object.create(HTMLElement.prototype)),d.__name=t.toLowerCase(),d.lifecycle=d.lifecycle||{},d.ancestry=a(d["extends"]),i(d),u(d),o(d.prototype),s(d.__name,d),d.ctor=l(d),d.ctor.prototype=d.prototype,d.prototype.constructor=d.ctor,e.ready&&h(document),d.ctor}function o(e){if(!e.setAttribute._polyfilled){var t=e.setAttribute;e.setAttribute=function(e,o){n.call(this,e,o,t)};var o=e.removeAttribute;e.removeAttribute=function(e){n.call(this,e,null,o)},e.setAttribute._polyfilled=!0}}function n(e,t,o){e=e.toLowerCase();var n=this.getAttribute(e);o.apply(this,arguments);var r=this.getAttribute(e);this.attributeChangedCallback&&r!==n&&this.attributeChangedCallback(e,n,r)}function r(e){for(var t=0;t=0&&_(n,HTMLElement),n)}function m(e){var t=T.call(this,e);return g(t),t}var w,h=e.upgradeDocumentTree,g=e.upgrade,v=e.upgradeWithDefinition,_=e.implementPrototype,y=e.useNative,b=["annotation-xml","color-profile","font-face","font-face-src","font-face-uri","font-face-format","font-face-name","missing-glyph"],E={},C="http://www.w3.org/1999/xhtml",M=document.createElement.bind(document),N=document.createElementNS.bind(document),T=Node.prototype.cloneNode;w=Object.__proto__||y?function(e,t){return e instanceof t}:function(e,t){for(var o=e;o;){if(o===t.prototype)return!0;o=o.__proto__}return!1},document.registerElement=t,document.createElement=p,document.createElementNS=f,Node.prototype.cloneNode=m,e.registry=E,e["instanceof"]=w,e.reservedTagList=b,e.getRegisteredDefinition=c,document.register=document.registerElement}),function(e){function t(){i(wrap(document)),window.HTMLImports&&(HTMLImports.__importsParsingHook=function(e){i(wrap(e["import"]))}),CustomElements.ready=!0,setTimeout(function(){CustomElements.readyTime=Date.now(),window.HTMLImports&&(CustomElements.elapsed=CustomElements.readyTime-HTMLImports.readyTime),document.dispatchEvent(new CustomEvent("WebComponentsReady",{bubbles:!0}))})}var o=e.useNative,n=e.initializeModules,r=/Trident/.test(navigator.userAgent);if(o){var a=function(){};e.watchShadow=a,e.upgrade=a,e.upgradeAll=a,e.upgradeDocumentTree=a,e.upgradeSubtree=a,e.takeRecords=a,e["instanceof"]=function(e,t){return e instanceof t}}else n();var i=e.upgradeDocumentTree;if(window.wrap||(window.ShadowDOMPolyfill?(window.wrap=ShadowDOMPolyfill.wrapIfNeeded,window.unwrap=ShadowDOMPolyfill.unwrapIfNeeded):window.wrap=window.unwrap=function(e){return e}),r&&"function"!=typeof window.CustomEvent&&(window.CustomEvent=function(e,t){t=t||{};var o=document.createEvent("CustomEvent");return o.initCustomEvent(e,Boolean(t.bubbles),Boolean(t.cancelable),t.detail),o},window.CustomEvent.prototype=window.Event.prototype),"complete"===document.readyState||e.flags.eager)t();else if("interactive"!==document.readyState||window.attachEvent||window.HTMLImports&&!window.HTMLImports.ready){var u=window.HTMLImports&&!HTMLImports.ready?"HTMLImportsLoaded":"DOMContentLoaded";window.addEventListener(u,t)}else t()}(window.CustomElements);
\ No newline at end of file
diff --git a/example/bower_components/webcomponentsjs/HTMLImports.js b/example/bower_components/webcomponentsjs/HTMLImports.js
new file mode 100644
index 000000000..9a194e144
--- /dev/null
+++ b/example/bower_components/webcomponentsjs/HTMLImports.js
@@ -0,0 +1,764 @@
+/**
+ * @license
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// @version 0.5.5
+if (typeof WeakMap === "undefined") {
+  (function() {
+    var defineProperty = Object.defineProperty;
+    var counter = Date.now() % 1e9;
+    var WeakMap = function() {
+      this.name = "__st" + (Math.random() * 1e9 >>> 0) + (counter++ + "__");
+    };
+    WeakMap.prototype = {
+      set: function(key, value) {
+        var entry = key[this.name];
+        if (entry && entry[0] === key) entry[1] = value; else defineProperty(key, this.name, {
+          value: [ key, value ],
+          writable: true
+        });
+        return this;
+      },
+      get: function(key) {
+        var entry;
+        return (entry = key[this.name]) && entry[0] === key ? entry[1] : undefined;
+      },
+      "delete": function(key) {
+        var entry = key[this.name];
+        if (!entry || entry[0] !== key) return false;
+        entry[0] = entry[1] = undefined;
+        return true;
+      },
+      has: function(key) {
+        var entry = key[this.name];
+        if (!entry) return false;
+        return entry[0] === key;
+      }
+    };
+    window.WeakMap = WeakMap;
+  })();
+}
+
+window.HTMLImports = window.HTMLImports || {
+  flags: {}
+};
+
+(function(scope) {
+  var IMPORT_LINK_TYPE = "import";
+  var useNative = Boolean(IMPORT_LINK_TYPE in document.createElement("link"));
+  var hasShadowDOMPolyfill = Boolean(window.ShadowDOMPolyfill);
+  var wrap = function(node) {
+    return hasShadowDOMPolyfill ? ShadowDOMPolyfill.wrapIfNeeded(node) : node;
+  };
+  var rootDocument = wrap(document);
+  var currentScriptDescriptor = {
+    get: function() {
+      var script = HTMLImports.currentScript || document.currentScript || (document.readyState !== "complete" ? document.scripts[document.scripts.length - 1] : null);
+      return wrap(script);
+    },
+    configurable: true
+  };
+  Object.defineProperty(document, "_currentScript", currentScriptDescriptor);
+  Object.defineProperty(rootDocument, "_currentScript", currentScriptDescriptor);
+  var isIE = /Trident|Edge/.test(navigator.userAgent);
+  function whenReady(callback, doc) {
+    doc = doc || rootDocument;
+    whenDocumentReady(function() {
+      watchImportsLoad(callback, doc);
+    }, doc);
+  }
+  var requiredReadyState = isIE ? "complete" : "interactive";
+  var READY_EVENT = "readystatechange";
+  function isDocumentReady(doc) {
+    return doc.readyState === "complete" || doc.readyState === requiredReadyState;
+  }
+  function whenDocumentReady(callback, doc) {
+    if (!isDocumentReady(doc)) {
+      var checkReady = function() {
+        if (doc.readyState === "complete" || doc.readyState === requiredReadyState) {
+          doc.removeEventListener(READY_EVENT, checkReady);
+          whenDocumentReady(callback, doc);
+        }
+      };
+      doc.addEventListener(READY_EVENT, checkReady);
+    } else if (callback) {
+      callback();
+    }
+  }
+  function markTargetLoaded(event) {
+    event.target.__loaded = true;
+  }
+  function watchImportsLoad(callback, doc) {
+    var imports = doc.querySelectorAll("link[rel=import]");
+    var loaded = 0, l = imports.length;
+    function checkDone(d) {
+      if (loaded == l && callback) {
+        callback();
+      }
+    }
+    function loadedImport(e) {
+      markTargetLoaded(e);
+      loaded++;
+      checkDone();
+    }
+    if (l) {
+      for (var i = 0, imp; i < l && (imp = imports[i]); i++) {
+        if (isImportLoaded(imp)) {
+          loadedImport.call(imp, {
+            target: imp
+          });
+        } else {
+          imp.addEventListener("load", loadedImport);
+          imp.addEventListener("error", loadedImport);
+        }
+      }
+    } else {
+      checkDone();
+    }
+  }
+  function isImportLoaded(link) {
+    return useNative ? link.__loaded || link.import && link.import.readyState !== "loading" : link.__importParsed;
+  }
+  if (useNative) {
+    new MutationObserver(function(mxns) {
+      for (var i = 0, l = mxns.length, m; i < l && (m = mxns[i]); i++) {
+        if (m.addedNodes) {
+          handleImports(m.addedNodes);
+        }
+      }
+    }).observe(document.head, {
+      childList: true
+    });
+    function handleImports(nodes) {
+      for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {
+        if (isImport(n)) {
+          handleImport(n);
+        }
+      }
+    }
+    function isImport(element) {
+      return element.localName === "link" && element.rel === "import";
+    }
+    function handleImport(element) {
+      var loaded = element.import;
+      if (loaded) {
+        markTargetLoaded({
+          target: element
+        });
+      } else {
+        element.addEventListener("load", markTargetLoaded);
+        element.addEventListener("error", markTargetLoaded);
+      }
+    }
+    (function() {
+      if (document.readyState === "loading") {
+        var imports = document.querySelectorAll("link[rel=import]");
+        for (var i = 0, l = imports.length, imp; i < l && (imp = imports[i]); i++) {
+          handleImport(imp);
+        }
+      }
+    })();
+  }
+  whenReady(function() {
+    HTMLImports.ready = true;
+    HTMLImports.readyTime = new Date().getTime();
+    var evt = rootDocument.createEvent("CustomEvent");
+    evt.initCustomEvent("HTMLImportsLoaded", true, true, {});
+    rootDocument.dispatchEvent(evt);
+  });
+  scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;
+  scope.useNative = useNative;
+  scope.rootDocument = rootDocument;
+  scope.whenReady = whenReady;
+  scope.isIE = isIE;
+})(HTMLImports);
+
+(function(scope) {
+  var modules = [];
+  var addModule = function(module) {
+    modules.push(module);
+  };
+  var initializeModules = function() {
+    modules.forEach(function(module) {
+      module(scope);
+    });
+  };
+  scope.addModule = addModule;
+  scope.initializeModules = initializeModules;
+})(HTMLImports);
+
+HTMLImports.addModule(function(scope) {
+  var CSS_URL_REGEXP = /(url\()([^)]*)(\))/g;
+  var CSS_IMPORT_REGEXP = /(@import[\s]+(?!url\())([^;]*)(;)/g;
+  var path = {
+    resolveUrlsInStyle: function(style) {
+      var doc = style.ownerDocument;
+      var resolver = doc.createElement("a");
+      style.textContent = this.resolveUrlsInCssText(style.textContent, resolver);
+      return style;
+    },
+    resolveUrlsInCssText: function(cssText, urlObj) {
+      var r = this.replaceUrls(cssText, urlObj, CSS_URL_REGEXP);
+      r = this.replaceUrls(r, urlObj, CSS_IMPORT_REGEXP);
+      return r;
+    },
+    replaceUrls: function(text, urlObj, regexp) {
+      return text.replace(regexp, function(m, pre, url, post) {
+        var urlPath = url.replace(/["']/g, "");
+        urlObj.href = urlPath;
+        urlPath = urlObj.href;
+        return pre + "'" + urlPath + "'" + post;
+      });
+    }
+  };
+  scope.path = path;
+});
+
+HTMLImports.addModule(function(scope) {
+  var xhr = {
+    async: true,
+    ok: function(request) {
+      return request.status >= 200 && request.status < 300 || request.status === 304 || request.status === 0;
+    },
+    load: function(url, next, nextContext) {
+      var request = new XMLHttpRequest();
+      if (scope.flags.debug || scope.flags.bust) {
+        url += "?" + Math.random();
+      }
+      request.open("GET", url, xhr.async);
+      request.addEventListener("readystatechange", function(e) {
+        if (request.readyState === 4) {
+          var locationHeader = request.getResponseHeader("Location");
+          var redirectedUrl = null;
+          if (locationHeader) {
+            var redirectedUrl = locationHeader.substr(0, 1) === "/" ? location.origin + locationHeader : locationHeader;
+          }
+          next.call(nextContext, !xhr.ok(request) && request, request.response || request.responseText, redirectedUrl);
+        }
+      });
+      request.send();
+      return request;
+    },
+    loadDocument: function(url, next, nextContext) {
+      this.load(url, next, nextContext).responseType = "document";
+    }
+  };
+  scope.xhr = xhr;
+});
+
+HTMLImports.addModule(function(scope) {
+  var xhr = scope.xhr;
+  var flags = scope.flags;
+  var Loader = function(onLoad, onComplete) {
+    this.cache = {};
+    this.onload = onLoad;
+    this.oncomplete = onComplete;
+    this.inflight = 0;
+    this.pending = {};
+  };
+  Loader.prototype = {
+    addNodes: function(nodes) {
+      this.inflight += nodes.length;
+      for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {
+        this.require(n);
+      }
+      this.checkDone();
+    },
+    addNode: function(node) {
+      this.inflight++;
+      this.require(node);
+      this.checkDone();
+    },
+    require: function(elt) {
+      var url = elt.src || elt.href;
+      elt.__nodeUrl = url;
+      if (!this.dedupe(url, elt)) {
+        this.fetch(url, elt);
+      }
+    },
+    dedupe: function(url, elt) {
+      if (this.pending[url]) {
+        this.pending[url].push(elt);
+        return true;
+      }
+      var resource;
+      if (this.cache[url]) {
+        this.onload(url, elt, this.cache[url]);
+        this.tail();
+        return true;
+      }
+      this.pending[url] = [ elt ];
+      return false;
+    },
+    fetch: function(url, elt) {
+      flags.load && console.log("fetch", url, elt);
+      if (!url) {
+        setTimeout(function() {
+          this.receive(url, elt, {
+            error: "href must be specified"
+          }, null);
+        }.bind(this), 0);
+      } else if (url.match(/^data:/)) {
+        var pieces = url.split(",");
+        var header = pieces[0];
+        var body = pieces[1];
+        if (header.indexOf(";base64") > -1) {
+          body = atob(body);
+        } else {
+          body = decodeURIComponent(body);
+        }
+        setTimeout(function() {
+          this.receive(url, elt, null, body);
+        }.bind(this), 0);
+      } else {
+        var receiveXhr = function(err, resource, redirectedUrl) {
+          this.receive(url, elt, err, resource, redirectedUrl);
+        }.bind(this);
+        xhr.load(url, receiveXhr);
+      }
+    },
+    receive: function(url, elt, err, resource, redirectedUrl) {
+      this.cache[url] = resource;
+      var $p = this.pending[url];
+      for (var i = 0, l = $p.length, p; i < l && (p = $p[i]); i++) {
+        this.onload(url, p, resource, err, redirectedUrl);
+        this.tail();
+      }
+      this.pending[url] = null;
+    },
+    tail: function() {
+      --this.inflight;
+      this.checkDone();
+    },
+    checkDone: function() {
+      if (!this.inflight) {
+        this.oncomplete();
+      }
+    }
+  };
+  scope.Loader = Loader;
+});
+
+HTMLImports.addModule(function(scope) {
+  var Observer = function(addCallback) {
+    this.addCallback = addCallback;
+    this.mo = new MutationObserver(this.handler.bind(this));
+  };
+  Observer.prototype = {
+    handler: function(mutations) {
+      for (var i = 0, l = mutations.length, m; i < l && (m = mutations[i]); i++) {
+        if (m.type === "childList" && m.addedNodes.length) {
+          this.addedNodes(m.addedNodes);
+        }
+      }
+    },
+    addedNodes: function(nodes) {
+      if (this.addCallback) {
+        this.addCallback(nodes);
+      }
+      for (var i = 0, l = nodes.length, n, loading; i < l && (n = nodes[i]); i++) {
+        if (n.children && n.children.length) {
+          this.addedNodes(n.children);
+        }
+      }
+    },
+    observe: function(root) {
+      this.mo.observe(root, {
+        childList: true,
+        subtree: true
+      });
+    }
+  };
+  scope.Observer = Observer;
+});
+
+HTMLImports.addModule(function(scope) {
+  var path = scope.path;
+  var rootDocument = scope.rootDocument;
+  var flags = scope.flags;
+  var isIE = scope.isIE;
+  var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;
+  var IMPORT_SELECTOR = "link[rel=" + IMPORT_LINK_TYPE + "]";
+  var importParser = {
+    documentSelectors: IMPORT_SELECTOR,
+    importsSelectors: [ IMPORT_SELECTOR, "link[rel=stylesheet]", "style", "script:not([type])", 'script[type="text/javascript"]' ].join(","),
+    map: {
+      link: "parseLink",
+      script: "parseScript",
+      style: "parseStyle"
+    },
+    dynamicElements: [],
+    parseNext: function() {
+      var next = this.nextToParse();
+      if (next) {
+        this.parse(next);
+      }
+    },
+    parse: function(elt) {
+      if (this.isParsed(elt)) {
+        flags.parse && console.log("[%s] is already parsed", elt.localName);
+        return;
+      }
+      var fn = this[this.map[elt.localName]];
+      if (fn) {
+        this.markParsing(elt);
+        fn.call(this, elt);
+      }
+    },
+    parseDynamic: function(elt, quiet) {
+      this.dynamicElements.push(elt);
+      if (!quiet) {
+        this.parseNext();
+      }
+    },
+    markParsing: function(elt) {
+      flags.parse && console.log("parsing", elt);
+      this.parsingElement = elt;
+    },
+    markParsingComplete: function(elt) {
+      elt.__importParsed = true;
+      this.markDynamicParsingComplete(elt);
+      if (elt.__importElement) {
+        elt.__importElement.__importParsed = true;
+        this.markDynamicParsingComplete(elt.__importElement);
+      }
+      this.parsingElement = null;
+      flags.parse && console.log("completed", elt);
+    },
+    markDynamicParsingComplete: function(elt) {
+      var i = this.dynamicElements.indexOf(elt);
+      if (i >= 0) {
+        this.dynamicElements.splice(i, 1);
+      }
+    },
+    parseImport: function(elt) {
+      if (HTMLImports.__importsParsingHook) {
+        HTMLImports.__importsParsingHook(elt);
+      }
+      if (elt.import) {
+        elt.import.__importParsed = true;
+      }
+      this.markParsingComplete(elt);
+      if (elt.__resource && !elt.__error) {
+        elt.dispatchEvent(new CustomEvent("load", {
+          bubbles: false
+        }));
+      } else {
+        elt.dispatchEvent(new CustomEvent("error", {
+          bubbles: false
+        }));
+      }
+      if (elt.__pending) {
+        var fn;
+        while (elt.__pending.length) {
+          fn = elt.__pending.shift();
+          if (fn) {
+            fn({
+              target: elt
+            });
+          }
+        }
+      }
+      this.parseNext();
+    },
+    parseLink: function(linkElt) {
+      if (nodeIsImport(linkElt)) {
+        this.parseImport(linkElt);
+      } else {
+        linkElt.href = linkElt.href;
+        this.parseGeneric(linkElt);
+      }
+    },
+    parseStyle: function(elt) {
+      var src = elt;
+      elt = cloneStyle(elt);
+      elt.__importElement = src;
+      this.parseGeneric(elt);
+    },
+    parseGeneric: function(elt) {
+      this.trackElement(elt);
+      this.addElementToDocument(elt);
+    },
+    rootImportForElement: function(elt) {
+      var n = elt;
+      while (n.ownerDocument.__importLink) {
+        n = n.ownerDocument.__importLink;
+      }
+      return n;
+    },
+    addElementToDocument: function(elt) {
+      var port = this.rootImportForElement(elt.__importElement || elt);
+      port.parentNode.insertBefore(elt, port);
+    },
+    trackElement: function(elt, callback) {
+      var self = this;
+      var done = function(e) {
+        if (callback) {
+          callback(e);
+        }
+        self.markParsingComplete(elt);
+        self.parseNext();
+      };
+      elt.addEventListener("load", done);
+      elt.addEventListener("error", done);
+      if (isIE && elt.localName === "style") {
+        var fakeLoad = false;
+        if (elt.textContent.indexOf("@import") == -1) {
+          fakeLoad = true;
+        } else if (elt.sheet) {
+          fakeLoad = true;
+          var csr = elt.sheet.cssRules;
+          var len = csr ? csr.length : 0;
+          for (var i = 0, r; i < len && (r = csr[i]); i++) {
+            if (r.type === CSSRule.IMPORT_RULE) {
+              fakeLoad = fakeLoad && Boolean(r.styleSheet);
+            }
+          }
+        }
+        if (fakeLoad) {
+          elt.dispatchEvent(new CustomEvent("load", {
+            bubbles: false
+          }));
+        }
+      }
+    },
+    parseScript: function(scriptElt) {
+      var script = document.createElement("script");
+      script.__importElement = scriptElt;
+      script.src = scriptElt.src ? scriptElt.src : generateScriptDataUrl(scriptElt);
+      scope.currentScript = scriptElt;
+      this.trackElement(script, function(e) {
+        script.parentNode.removeChild(script);
+        scope.currentScript = null;
+      });
+      this.addElementToDocument(script);
+    },
+    nextToParse: function() {
+      this._mayParse = [];
+      return !this.parsingElement && (this.nextToParseInDoc(rootDocument) || this.nextToParseDynamic());
+    },
+    nextToParseInDoc: function(doc, link) {
+      if (doc && this._mayParse.indexOf(doc) < 0) {
+        this._mayParse.push(doc);
+        var nodes = doc.querySelectorAll(this.parseSelectorsForNode(doc));
+        for (var i = 0, l = nodes.length, p = 0, n; i < l && (n = nodes[i]); i++) {
+          if (!this.isParsed(n)) {
+            if (this.hasResource(n)) {
+              return nodeIsImport(n) ? this.nextToParseInDoc(n.import, n) : n;
+            } else {
+              return;
+            }
+          }
+        }
+      }
+      return link;
+    },
+    nextToParseDynamic: function() {
+      return this.dynamicElements[0];
+    },
+    parseSelectorsForNode: function(node) {
+      var doc = node.ownerDocument || node;
+      return doc === rootDocument ? this.documentSelectors : this.importsSelectors;
+    },
+    isParsed: function(node) {
+      return node.__importParsed;
+    },
+    needsDynamicParsing: function(elt) {
+      return this.dynamicElements.indexOf(elt) >= 0;
+    },
+    hasResource: function(node) {
+      if (nodeIsImport(node) && node.import === undefined) {
+        return false;
+      }
+      return true;
+    }
+  };
+  function nodeIsImport(elt) {
+    return elt.localName === "link" && elt.rel === IMPORT_LINK_TYPE;
+  }
+  function generateScriptDataUrl(script) {
+    var scriptContent = generateScriptContent(script);
+    return "data:text/javascript;charset=utf-8," + encodeURIComponent(scriptContent);
+  }
+  function generateScriptContent(script) {
+    return script.textContent + generateSourceMapHint(script);
+  }
+  function generateSourceMapHint(script) {
+    var owner = script.ownerDocument;
+    owner.__importedScripts = owner.__importedScripts || 0;
+    var moniker = script.ownerDocument.baseURI;
+    var num = owner.__importedScripts ? "-" + owner.__importedScripts : "";
+    owner.__importedScripts++;
+    return "\n//# sourceURL=" + moniker + num + ".js\n";
+  }
+  function cloneStyle(style) {
+    var clone = style.ownerDocument.createElement("style");
+    clone.textContent = style.textContent;
+    path.resolveUrlsInStyle(clone);
+    return clone;
+  }
+  scope.parser = importParser;
+  scope.IMPORT_SELECTOR = IMPORT_SELECTOR;
+});
+
+HTMLImports.addModule(function(scope) {
+  var flags = scope.flags;
+  var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;
+  var IMPORT_SELECTOR = scope.IMPORT_SELECTOR;
+  var rootDocument = scope.rootDocument;
+  var Loader = scope.Loader;
+  var Observer = scope.Observer;
+  var parser = scope.parser;
+  var importer = {
+    documents: {},
+    documentPreloadSelectors: IMPORT_SELECTOR,
+    importsPreloadSelectors: [ IMPORT_SELECTOR ].join(","),
+    loadNode: function(node) {
+      importLoader.addNode(node);
+    },
+    loadSubtree: function(parent) {
+      var nodes = this.marshalNodes(parent);
+      importLoader.addNodes(nodes);
+    },
+    marshalNodes: function(parent) {
+      return parent.querySelectorAll(this.loadSelectorsForNode(parent));
+    },
+    loadSelectorsForNode: function(node) {
+      var doc = node.ownerDocument || node;
+      return doc === rootDocument ? this.documentPreloadSelectors : this.importsPreloadSelectors;
+    },
+    loaded: function(url, elt, resource, err, redirectedUrl) {
+      flags.load && console.log("loaded", url, elt);
+      elt.__resource = resource;
+      elt.__error = err;
+      if (isImportLink(elt)) {
+        var doc = this.documents[url];
+        if (doc === undefined) {
+          doc = err ? null : makeDocument(resource, redirectedUrl || url);
+          if (doc) {
+            doc.__importLink = elt;
+            this.bootDocument(doc);
+          }
+          this.documents[url] = doc;
+        }
+        elt.import = doc;
+      }
+      parser.parseNext();
+    },
+    bootDocument: function(doc) {
+      this.loadSubtree(doc);
+      this.observer.observe(doc);
+      parser.parseNext();
+    },
+    loadedAll: function() {
+      parser.parseNext();
+    }
+  };
+  var importLoader = new Loader(importer.loaded.bind(importer), importer.loadedAll.bind(importer));
+  importer.observer = new Observer();
+  function isImportLink(elt) {
+    return isLinkRel(elt, IMPORT_LINK_TYPE);
+  }
+  function isLinkRel(elt, rel) {
+    return elt.localName === "link" && elt.getAttribute("rel") === rel;
+  }
+  function hasBaseURIAccessor(doc) {
+    return !!Object.getOwnPropertyDescriptor(doc, "baseURI");
+  }
+  function makeDocument(resource, url) {
+    var doc = document.implementation.createHTMLDocument(IMPORT_LINK_TYPE);
+    doc._URL = url;
+    var base = doc.createElement("base");
+    base.setAttribute("href", url);
+    if (!doc.baseURI && !hasBaseURIAccessor(doc)) {
+      Object.defineProperty(doc, "baseURI", {
+        value: url
+      });
+    }
+    var meta = doc.createElement("meta");
+    meta.setAttribute("charset", "utf-8");
+    doc.head.appendChild(meta);
+    doc.head.appendChild(base);
+    doc.body.innerHTML = resource;
+    if (window.HTMLTemplateElement && HTMLTemplateElement.bootstrap) {
+      HTMLTemplateElement.bootstrap(doc);
+    }
+    return doc;
+  }
+  if (!document.baseURI) {
+    var baseURIDescriptor = {
+      get: function() {
+        var base = document.querySelector("base");
+        return base ? base.href : window.location.href;
+      },
+      configurable: true
+    };
+    Object.defineProperty(document, "baseURI", baseURIDescriptor);
+    Object.defineProperty(rootDocument, "baseURI", baseURIDescriptor);
+  }
+  scope.importer = importer;
+  scope.importLoader = importLoader;
+});
+
+HTMLImports.addModule(function(scope) {
+  var parser = scope.parser;
+  var importer = scope.importer;
+  var dynamic = {
+    added: function(nodes) {
+      var owner, parsed, loading;
+      for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {
+        if (!owner) {
+          owner = n.ownerDocument;
+          parsed = parser.isParsed(owner);
+        }
+        loading = this.shouldLoadNode(n);
+        if (loading) {
+          importer.loadNode(n);
+        }
+        if (this.shouldParseNode(n) && parsed) {
+          parser.parseDynamic(n, loading);
+        }
+      }
+    },
+    shouldLoadNode: function(node) {
+      return node.nodeType === 1 && matches.call(node, importer.loadSelectorsForNode(node));
+    },
+    shouldParseNode: function(node) {
+      return node.nodeType === 1 && matches.call(node, parser.parseSelectorsForNode(node));
+    }
+  };
+  importer.observer.addCallback = dynamic.added.bind(dynamic);
+  var matches = HTMLElement.prototype.matches || HTMLElement.prototype.matchesSelector || HTMLElement.prototype.webkitMatchesSelector || HTMLElement.prototype.mozMatchesSelector || HTMLElement.prototype.msMatchesSelector;
+});
+
+(function(scope) {
+  var initializeModules = scope.initializeModules;
+  var isIE = scope.isIE;
+  if (scope.useNative) {
+    return;
+  }
+  if (isIE && typeof window.CustomEvent !== "function") {
+    window.CustomEvent = function(inType, params) {
+      params = params || {};
+      var e = document.createEvent("CustomEvent");
+      e.initCustomEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable), params.detail);
+      return e;
+    };
+    window.CustomEvent.prototype = window.Event.prototype;
+  }
+  initializeModules();
+  var rootDocument = scope.rootDocument;
+  function bootstrap() {
+    HTMLImports.importer.bootDocument(rootDocument);
+  }
+  if (document.readyState === "complete" || document.readyState === "interactive" && !window.attachEvent) {
+    bootstrap();
+  } else {
+    document.addEventListener("DOMContentLoaded", bootstrap);
+  }
+})(HTMLImports);
\ No newline at end of file
diff --git a/example/bower_components/webcomponentsjs/HTMLImports.min.js b/example/bower_components/webcomponentsjs/HTMLImports.min.js
new file mode 100644
index 000000000..a1a45ce17
--- /dev/null
+++ b/example/bower_components/webcomponentsjs/HTMLImports.min.js
@@ -0,0 +1,11 @@
+/**
+ * @license
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// @version 0.5.5
+"undefined"==typeof WeakMap&&!function(){var e=Object.defineProperty,t=Date.now()%1e9,n=function(){this.name="__st"+(1e9*Math.random()>>>0)+(t++ +"__")};n.prototype={set:function(t,n){var r=t[this.name];return r&&r[0]===t?r[1]=n:e(t,this.name,{value:[t,n],writable:!0}),this},get:function(e){var t;return(t=e[this.name])&&t[0]===e?t[1]:void 0},"delete":function(e){var t=e[this.name];return t&&t[0]===e?(t[0]=t[1]=void 0,!0):!1},has:function(e){var t=e[this.name];return t?t[0]===e:!1}},window.WeakMap=n}(),window.HTMLImports=window.HTMLImports||{flags:{}},function(e){function t(e,t){t=t||h,r(function(){i(e,t)},t)}function n(e){return"complete"===e.readyState||e.readyState===g}function r(e,t){if(n(t))e&&e();else{var o=function(){("complete"===t.readyState||t.readyState===g)&&(t.removeEventListener(_,o),r(e,t))};t.addEventListener(_,o)}}function o(e){e.target.__loaded=!0}function i(e,t){function n(){s==c&&e&&e()}function r(e){o(e),s++,n()}var i=t.querySelectorAll("link[rel=import]"),s=0,c=i.length;if(c)for(var d,l=0;c>l&&(d=i[l]);l++)a(d)?r.call(d,{target:d}):(d.addEventListener("load",r),d.addEventListener("error",r));else n()}function a(e){return u?e.__loaded||e["import"]&&"loading"!==e["import"].readyState:e.__importParsed}function s(e){for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)c(t)&&d(t)}function c(e){return"link"===e.localName&&"import"===e.rel}function d(e){var t=e["import"];t?o({target:e}):(e.addEventListener("load",o),e.addEventListener("error",o))}var l="import",u=Boolean(l in document.createElement("link")),m=Boolean(window.ShadowDOMPolyfill),p=function(e){return m?ShadowDOMPolyfill.wrapIfNeeded(e):e},h=p(document),f={get:function(){var e=HTMLImports.currentScript||document.currentScript||("complete"!==document.readyState?document.scripts[document.scripts.length-1]:null);return p(e)},configurable:!0};Object.defineProperty(document,"_currentScript",f),Object.defineProperty(h,"_currentScript",f);var v=/Trident|Edge/.test(navigator.userAgent),g=v?"complete":"interactive",_="readystatechange";u&&(new MutationObserver(function(e){for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)t.addedNodes&&s(t.addedNodes)}).observe(document.head,{childList:!0}),function(){if("loading"===document.readyState)for(var e,t=document.querySelectorAll("link[rel=import]"),n=0,r=t.length;r>n&&(e=t[n]);n++)d(e)}()),t(function(){HTMLImports.ready=!0,HTMLImports.readyTime=(new Date).getTime();var e=h.createEvent("CustomEvent");e.initCustomEvent("HTMLImportsLoaded",!0,!0,{}),h.dispatchEvent(e)}),e.IMPORT_LINK_TYPE=l,e.useNative=u,e.rootDocument=h,e.whenReady=t,e.isIE=v}(HTMLImports),function(e){var t=[],n=function(e){t.push(e)},r=function(){t.forEach(function(t){t(e)})};e.addModule=n,e.initializeModules=r}(HTMLImports),HTMLImports.addModule(function(e){var t=/(url\()([^)]*)(\))/g,n=/(@import[\s]+(?!url\())([^;]*)(;)/g,r={resolveUrlsInStyle:function(e){var t=e.ownerDocument,n=t.createElement("a");return e.textContent=this.resolveUrlsInCssText(e.textContent,n),e},resolveUrlsInCssText:function(e,r){var o=this.replaceUrls(e,r,t);return o=this.replaceUrls(o,r,n)},replaceUrls:function(e,t,n){return e.replace(n,function(e,n,r,o){var i=r.replace(/["']/g,"");return t.href=i,i=t.href,n+"'"+i+"'"+o})}};e.path=r}),HTMLImports.addModule(function(e){var t={async:!0,ok:function(e){return e.status>=200&&e.status<300||304===e.status||0===e.status},load:function(n,r,o){var i=new XMLHttpRequest;return(e.flags.debug||e.flags.bust)&&(n+="?"+Math.random()),i.open("GET",n,t.async),i.addEventListener("readystatechange",function(){if(4===i.readyState){var e=i.getResponseHeader("Location"),n=null;if(e)var n="/"===e.substr(0,1)?location.origin+e:e;r.call(o,!t.ok(i)&&i,i.response||i.responseText,n)}}),i.send(),i},loadDocument:function(e,t,n){this.load(e,t,n).responseType="document"}};e.xhr=t}),HTMLImports.addModule(function(e){var t=e.xhr,n=e.flags,r=function(e,t){this.cache={},this.onload=e,this.oncomplete=t,this.inflight=0,this.pending={}};r.prototype={addNodes:function(e){this.inflight+=e.length;for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)this.require(t);this.checkDone()},addNode:function(e){this.inflight++,this.require(e),this.checkDone()},require:function(e){var t=e.src||e.href;e.__nodeUrl=t,this.dedupe(t,e)||this.fetch(t,e)},dedupe:function(e,t){if(this.pending[e])return this.pending[e].push(t),!0;return this.cache[e]?(this.onload(e,t,this.cache[e]),this.tail(),!0):(this.pending[e]=[t],!1)},fetch:function(e,r){if(n.load&&console.log("fetch",e,r),e)if(e.match(/^data:/)){var o=e.split(","),i=o[0],a=o[1];a=i.indexOf(";base64")>-1?atob(a):decodeURIComponent(a),setTimeout(function(){this.receive(e,r,null,a)}.bind(this),0)}else{var s=function(t,n,o){this.receive(e,r,t,n,o)}.bind(this);t.load(e,s)}else setTimeout(function(){this.receive(e,r,{error:"href must be specified"},null)}.bind(this),0)},receive:function(e,t,n,r,o){this.cache[e]=r;for(var i,a=this.pending[e],s=0,c=a.length;c>s&&(i=a[s]);s++)this.onload(e,i,r,n,o),this.tail();this.pending[e]=null},tail:function(){--this.inflight,this.checkDone()},checkDone:function(){this.inflight||this.oncomplete()}},e.Loader=r}),HTMLImports.addModule(function(e){var t=function(e){this.addCallback=e,this.mo=new MutationObserver(this.handler.bind(this))};t.prototype={handler:function(e){for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)"childList"===t.type&&t.addedNodes.length&&this.addedNodes(t.addedNodes)},addedNodes:function(e){this.addCallback&&this.addCallback(e);for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)t.children&&t.children.length&&this.addedNodes(t.children)},observe:function(e){this.mo.observe(e,{childList:!0,subtree:!0})}},e.Observer=t}),HTMLImports.addModule(function(e){function t(e){return"link"===e.localName&&e.rel===l}function n(e){var t=r(e);return"data:text/javascript;charset=utf-8,"+encodeURIComponent(t)}function r(e){return e.textContent+o(e)}function o(e){var t=e.ownerDocument;t.__importedScripts=t.__importedScripts||0;var n=e.ownerDocument.baseURI,r=t.__importedScripts?"-"+t.__importedScripts:"";return t.__importedScripts++,"\n//# sourceURL="+n+r+".js\n"}function i(e){var t=e.ownerDocument.createElement("style");return t.textContent=e.textContent,a.resolveUrlsInStyle(t),t}var a=e.path,s=e.rootDocument,c=e.flags,d=e.isIE,l=e.IMPORT_LINK_TYPE,u="link[rel="+l+"]",m={documentSelectors:u,importsSelectors:[u,"link[rel=stylesheet]","style","script:not([type])",'script[type="text/javascript"]'].join(","),map:{link:"parseLink",script:"parseScript",style:"parseStyle"},dynamicElements:[],parseNext:function(){var e=this.nextToParse();e&&this.parse(e)},parse:function(e){if(this.isParsed(e))return void(c.parse&&console.log("[%s] is already parsed",e.localName));var t=this[this.map[e.localName]];t&&(this.markParsing(e),t.call(this,e))},parseDynamic:function(e,t){this.dynamicElements.push(e),t||this.parseNext()},markParsing:function(e){c.parse&&console.log("parsing",e),this.parsingElement=e},markParsingComplete:function(e){e.__importParsed=!0,this.markDynamicParsingComplete(e),e.__importElement&&(e.__importElement.__importParsed=!0,this.markDynamicParsingComplete(e.__importElement)),this.parsingElement=null,c.parse&&console.log("completed",e)},markDynamicParsingComplete:function(e){var t=this.dynamicElements.indexOf(e);t>=0&&this.dynamicElements.splice(t,1)},parseImport:function(e){if(HTMLImports.__importsParsingHook&&HTMLImports.__importsParsingHook(e),e["import"]&&(e["import"].__importParsed=!0),this.markParsingComplete(e),e.dispatchEvent(e.__resource&&!e.__error?new CustomEvent("load",{bubbles:!1}):new CustomEvent("error",{bubbles:!1})),e.__pending)for(var t;e.__pending.length;)t=e.__pending.shift(),t&&t({target:e});this.parseNext()},parseLink:function(e){t(e)?this.parseImport(e):(e.href=e.href,this.parseGeneric(e))},parseStyle:function(e){var t=e;e=i(e),e.__importElement=t,this.parseGeneric(e)},parseGeneric:function(e){this.trackElement(e),this.addElementToDocument(e)},rootImportForElement:function(e){for(var t=e;t.ownerDocument.__importLink;)t=t.ownerDocument.__importLink;return t},addElementToDocument:function(e){var t=this.rootImportForElement(e.__importElement||e);t.parentNode.insertBefore(e,t)},trackElement:function(e,t){var n=this,r=function(r){t&&t(r),n.markParsingComplete(e),n.parseNext()};if(e.addEventListener("load",r),e.addEventListener("error",r),d&&"style"===e.localName){var o=!1;if(-1==e.textContent.indexOf("@import"))o=!0;else if(e.sheet){o=!0;for(var i,a=e.sheet.cssRules,s=a?a.length:0,c=0;s>c&&(i=a[c]);c++)i.type===CSSRule.IMPORT_RULE&&(o=o&&Boolean(i.styleSheet))}o&&e.dispatchEvent(new CustomEvent("load",{bubbles:!1}))}},parseScript:function(t){var r=document.createElement("script");r.__importElement=t,r.src=t.src?t.src:n(t),e.currentScript=t,this.trackElement(r,function(){r.parentNode.removeChild(r),e.currentScript=null}),this.addElementToDocument(r)},nextToParse:function(){return this._mayParse=[],!this.parsingElement&&(this.nextToParseInDoc(s)||this.nextToParseDynamic())},nextToParseInDoc:function(e,n){if(e&&this._mayParse.indexOf(e)<0){this._mayParse.push(e);for(var r,o=e.querySelectorAll(this.parseSelectorsForNode(e)),i=0,a=o.length;a>i&&(r=o[i]);i++)if(!this.isParsed(r))return this.hasResource(r)?t(r)?this.nextToParseInDoc(r["import"],r):r:void 0}return n},nextToParseDynamic:function(){return this.dynamicElements[0]},parseSelectorsForNode:function(e){var t=e.ownerDocument||e;return t===s?this.documentSelectors:this.importsSelectors},isParsed:function(e){return e.__importParsed},needsDynamicParsing:function(e){return this.dynamicElements.indexOf(e)>=0},hasResource:function(e){return t(e)&&void 0===e["import"]?!1:!0}};e.parser=m,e.IMPORT_SELECTOR=u}),HTMLImports.addModule(function(e){function t(e){return n(e,a)}function n(e,t){return"link"===e.localName&&e.getAttribute("rel")===t}function r(e){return!!Object.getOwnPropertyDescriptor(e,"baseURI")}function o(e,t){var n=document.implementation.createHTMLDocument(a);n._URL=t;var o=n.createElement("base");o.setAttribute("href",t),n.baseURI||r(n)||Object.defineProperty(n,"baseURI",{value:t});var i=n.createElement("meta");return i.setAttribute("charset","utf-8"),n.head.appendChild(i),n.head.appendChild(o),n.body.innerHTML=e,window.HTMLTemplateElement&&HTMLTemplateElement.bootstrap&&HTMLTemplateElement.bootstrap(n),n}var i=e.flags,a=e.IMPORT_LINK_TYPE,s=e.IMPORT_SELECTOR,c=e.rootDocument,d=e.Loader,l=e.Observer,u=e.parser,m={documents:{},documentPreloadSelectors:s,importsPreloadSelectors:[s].join(","),loadNode:function(e){p.addNode(e)},loadSubtree:function(e){var t=this.marshalNodes(e);p.addNodes(t)},marshalNodes:function(e){return e.querySelectorAll(this.loadSelectorsForNode(e))},loadSelectorsForNode:function(e){var t=e.ownerDocument||e;return t===c?this.documentPreloadSelectors:this.importsPreloadSelectors},loaded:function(e,n,r,a,s){if(i.load&&console.log("loaded",e,n),n.__resource=r,n.__error=a,t(n)){var c=this.documents[e];void 0===c&&(c=a?null:o(r,s||e),c&&(c.__importLink=n,this.bootDocument(c)),this.documents[e]=c),n["import"]=c}u.parseNext()},bootDocument:function(e){this.loadSubtree(e),this.observer.observe(e),u.parseNext()},loadedAll:function(){u.parseNext()}},p=new d(m.loaded.bind(m),m.loadedAll.bind(m));if(m.observer=new l,!document.baseURI){var h={get:function(){var e=document.querySelector("base");return e?e.href:window.location.href},configurable:!0};Object.defineProperty(document,"baseURI",h),Object.defineProperty(c,"baseURI",h)}e.importer=m,e.importLoader=p}),HTMLImports.addModule(function(e){var t=e.parser,n=e.importer,r={added:function(e){for(var r,o,i,a,s=0,c=e.length;c>s&&(a=e[s]);s++)r||(r=a.ownerDocument,o=t.isParsed(r)),i=this.shouldLoadNode(a),i&&n.loadNode(a),this.shouldParseNode(a)&&o&&t.parseDynamic(a,i)},shouldLoadNode:function(e){return 1===e.nodeType&&o.call(e,n.loadSelectorsForNode(e))},shouldParseNode:function(e){return 1===e.nodeType&&o.call(e,t.parseSelectorsForNode(e))}};n.observer.addCallback=r.added.bind(r);var o=HTMLElement.prototype.matches||HTMLElement.prototype.matchesSelector||HTMLElement.prototype.webkitMatchesSelector||HTMLElement.prototype.mozMatchesSelector||HTMLElement.prototype.msMatchesSelector}),function(e){function t(){HTMLImports.importer.bootDocument(o)}var n=e.initializeModules,r=e.isIE;if(!e.useNative){r&&"function"!=typeof window.CustomEvent&&(window.CustomEvent=function(e,t){t=t||{};var n=document.createEvent("CustomEvent");return n.initCustomEvent(e,Boolean(t.bubbles),Boolean(t.cancelable),t.detail),n},window.CustomEvent.prototype=window.Event.prototype),n();var o=e.rootDocument;"complete"===document.readyState||"interactive"===document.readyState&&!window.attachEvent?t():document.addEventListener("DOMContentLoaded",t)}}(HTMLImports);
\ No newline at end of file
diff --git a/example/bower_components/webcomponentsjs/README.md b/example/bower_components/webcomponentsjs/README.md
new file mode 100644
index 000000000..49ed2b64f
--- /dev/null
+++ b/example/bower_components/webcomponentsjs/README.md
@@ -0,0 +1,73 @@
+webcomponents.js
+================
+
+[![Join the chat at https://gitter.im/webcomponents/webcomponentsjs](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/webcomponents/webcomponentsjs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+
+A suite of polyfills supporting the [Web Components](http://webcomponents.org) specs:
+
+**Custom Elements**: allows authors to define their own custom tags ([spec](https://w3c.github.io/webcomponents/spec/custom/)).
+
+**HTML Imports**: a way to include and reuse HTML documents via other HTML documents ([spec](https://w3c.github.io/webcomponents/spec/imports/)).
+
+**Shadow DOM**: provides encapsulation by hiding DOM subtrees under shadow roots ([spec](https://w3c.github.io/webcomponents/spec/shadow/)).
+
+This also folds in polyfills for `MutationObserver` and `WeakMap`.
+
+
+## Releases
+
+Pre-built (concatenated & minified) versions of the polyfills are maintained in the [tagged versions](https://github.com/webcomponents/webcomponentsjs/releases) of this repo. There are two variants:
+
+`webcomponents.js` includes all of the polyfills.
+
+`webcomponents-lite.js` includes all polyfills except for shadow DOM.
+
+
+## Browser Support
+
+Our polyfills are intended to work in the latest versions of evergreen browsers. See below
+for our complete browser support matrix:
+
+| Polyfill   | IE10 | IE11+ | Chrome* | Firefox* | Safari 7+* | Chrome Android* | Mobile Safari* |
+| ---------- |:----:|:-----:|:-------:|:--------:|:----------:|:---------------:|:--------------:|
+| Custom Elements | ~ | ✓ | ✓ | ✓ | ✓ | ✓| ✓ |
+| HTML Imports | ~ | ✓ | ✓ | ✓ | ✓| ✓| ✓ |
+| Shadow DOM | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+| Templates | ✓ | ✓ | ✓ | ✓| ✓ | ✓ | ✓ |
+
+
+*Indicates the current version of the browser
+
+~Indicates support may be flaky. If using Custom Elements or HTML Imports with Shadow DOM,
+you will get the non-flaky Mutation Observer polyfill that Shadow DOM includes.
+
+The polyfills may work in older browsers, however require additional polyfills (such as classList)
+to be used. We cannot guarantee support for browsers outside of our compatibility matrix.
+
+
+### Manually Building
+
+If you wish to build the polyfills yourself, you'll need `node` and `gulp` on your system:
+
+ * install [node.js](http://nodejs.org/) using the instructions on their website
+ * use `npm` to install [gulp.js](http://gulpjs.com/): `npm install -g gulp`
+
+Now you are ready to build the polyfills with:
+
+    # install dependencies
+    npm install
+    # build
+    gulp build
+
+The builds will be placed into the `dist/` directory.
+
+## Contribute
+
+See the [contributing guide](CONTRIBUTING.md)
+
+## License
+
+Everything in this repository is BSD style license unless otherwise specified.
+
+Copyright (c) 2015 The Polymer Authors. All rights reserved.
+
diff --git a/example/bower_components/webcomponentsjs/ShadowDOM.js b/example/bower_components/webcomponentsjs/ShadowDOM.js
new file mode 100644
index 000000000..fb5c08f34
--- /dev/null
+++ b/example/bower_components/webcomponentsjs/ShadowDOM.js
@@ -0,0 +1,4277 @@
+/**
+ * @license
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// @version 0.5.5
+if (typeof WeakMap === "undefined") {
+  (function() {
+    var defineProperty = Object.defineProperty;
+    var counter = Date.now() % 1e9;
+    var WeakMap = function() {
+      this.name = "__st" + (Math.random() * 1e9 >>> 0) + (counter++ + "__");
+    };
+    WeakMap.prototype = {
+      set: function(key, value) {
+        var entry = key[this.name];
+        if (entry && entry[0] === key) entry[1] = value; else defineProperty(key, this.name, {
+          value: [ key, value ],
+          writable: true
+        });
+        return this;
+      },
+      get: function(key) {
+        var entry;
+        return (entry = key[this.name]) && entry[0] === key ? entry[1] : undefined;
+      },
+      "delete": function(key) {
+        var entry = key[this.name];
+        if (!entry || entry[0] !== key) return false;
+        entry[0] = entry[1] = undefined;
+        return true;
+      },
+      has: function(key) {
+        var entry = key[this.name];
+        if (!entry) return false;
+        return entry[0] === key;
+      }
+    };
+    window.WeakMap = WeakMap;
+  })();
+}
+
+window.ShadowDOMPolyfill = {};
+
+(function(scope) {
+  "use strict";
+  var constructorTable = new WeakMap();
+  var nativePrototypeTable = new WeakMap();
+  var wrappers = Object.create(null);
+  function detectEval() {
+    if (typeof chrome !== "undefined" && chrome.app && chrome.app.runtime) {
+      return false;
+    }
+    if (navigator.getDeviceStorage) {
+      return false;
+    }
+    try {
+      var f = new Function("return true;");
+      return f();
+    } catch (ex) {
+      return false;
+    }
+  }
+  var hasEval = detectEval();
+  function assert(b) {
+    if (!b) throw new Error("Assertion failed");
+  }
+  var defineProperty = Object.defineProperty;
+  var getOwnPropertyNames = Object.getOwnPropertyNames;
+  var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
+  function mixin(to, from) {
+    var names = getOwnPropertyNames(from);
+    for (var i = 0; i < names.length; i++) {
+      var name = names[i];
+      defineProperty(to, name, getOwnPropertyDescriptor(from, name));
+    }
+    return to;
+  }
+  function mixinStatics(to, from) {
+    var names = getOwnPropertyNames(from);
+    for (var i = 0; i < names.length; i++) {
+      var name = names[i];
+      switch (name) {
+       case "arguments":
+       case "caller":
+       case "length":
+       case "name":
+       case "prototype":
+       case "toString":
+        continue;
+      }
+      defineProperty(to, name, getOwnPropertyDescriptor(from, name));
+    }
+    return to;
+  }
+  function oneOf(object, propertyNames) {
+    for (var i = 0; i < propertyNames.length; i++) {
+      if (propertyNames[i] in object) return propertyNames[i];
+    }
+  }
+  var nonEnumerableDataDescriptor = {
+    value: undefined,
+    configurable: true,
+    enumerable: false,
+    writable: true
+  };
+  function defineNonEnumerableDataProperty(object, name, value) {
+    nonEnumerableDataDescriptor.value = value;
+    defineProperty(object, name, nonEnumerableDataDescriptor);
+  }
+  getOwnPropertyNames(window);
+  function getWrapperConstructor(node) {
+    var nativePrototype = node.__proto__ || Object.getPrototypeOf(node);
+    if (isFirefox) {
+      try {
+        getOwnPropertyNames(nativePrototype);
+      } catch (error) {
+        nativePrototype = nativePrototype.__proto__;
+      }
+    }
+    var wrapperConstructor = constructorTable.get(nativePrototype);
+    if (wrapperConstructor) return wrapperConstructor;
+    var parentWrapperConstructor = getWrapperConstructor(nativePrototype);
+    var GeneratedWrapper = createWrapperConstructor(parentWrapperConstructor);
+    registerInternal(nativePrototype, GeneratedWrapper, node);
+    return GeneratedWrapper;
+  }
+  function addForwardingProperties(nativePrototype, wrapperPrototype) {
+    installProperty(nativePrototype, wrapperPrototype, true);
+  }
+  function registerInstanceProperties(wrapperPrototype, instanceObject) {
+    installProperty(instanceObject, wrapperPrototype, false);
+  }
+  var isFirefox = /Firefox/.test(navigator.userAgent);
+  var dummyDescriptor = {
+    get: function() {},
+    set: function(v) {},
+    configurable: true,
+    enumerable: true
+  };
+  function isEventHandlerName(name) {
+    return /^on[a-z]+$/.test(name);
+  }
+  function isIdentifierName(name) {
+    return /^\w[a-zA-Z_0-9]*$/.test(name);
+  }
+  function getGetter(name) {
+    return hasEval && isIdentifierName(name) ? new Function("return this.__impl4cf1e782hg__." + name) : function() {
+      return this.__impl4cf1e782hg__[name];
+    };
+  }
+  function getSetter(name) {
+    return hasEval && isIdentifierName(name) ? new Function("v", "this.__impl4cf1e782hg__." + name + " = v") : function(v) {
+      this.__impl4cf1e782hg__[name] = v;
+    };
+  }
+  function getMethod(name) {
+    return hasEval && isIdentifierName(name) ? new Function("return this.__impl4cf1e782hg__." + name + ".apply(this.__impl4cf1e782hg__, arguments)") : function() {
+      return this.__impl4cf1e782hg__[name].apply(this.__impl4cf1e782hg__, arguments);
+    };
+  }
+  function getDescriptor(source, name) {
+    try {
+      return Object.getOwnPropertyDescriptor(source, name);
+    } catch (ex) {
+      return dummyDescriptor;
+    }
+  }
+  var isBrokenSafari = function() {
+    var descr = Object.getOwnPropertyDescriptor(Node.prototype, "nodeType");
+    return descr && !descr.get && !descr.set;
+  }();
+  function installProperty(source, target, allowMethod, opt_blacklist) {
+    var names = getOwnPropertyNames(source);
+    for (var i = 0; i < names.length; i++) {
+      var name = names[i];
+      if (name === "polymerBlackList_") continue;
+      if (name in target) continue;
+      if (source.polymerBlackList_ && source.polymerBlackList_[name]) continue;
+      if (isFirefox) {
+        source.__lookupGetter__(name);
+      }
+      var descriptor = getDescriptor(source, name);
+      var getter, setter;
+      if (allowMethod && typeof descriptor.value === "function") {
+        target[name] = getMethod(name);
+        continue;
+      }
+      var isEvent = isEventHandlerName(name);
+      if (isEvent) getter = scope.getEventHandlerGetter(name); else getter = getGetter(name);
+      if (descriptor.writable || descriptor.set || isBrokenSafari) {
+        if (isEvent) setter = scope.getEventHandlerSetter(name); else setter = getSetter(name);
+      }
+      var configurable = isBrokenSafari || descriptor.configurable;
+      defineProperty(target, name, {
+        get: getter,
+        set: setter,
+        configurable: configurable,
+        enumerable: descriptor.enumerable
+      });
+    }
+  }
+  function register(nativeConstructor, wrapperConstructor, opt_instance) {
+    var nativePrototype = nativeConstructor.prototype;
+    registerInternal(nativePrototype, wrapperConstructor, opt_instance);
+    mixinStatics(wrapperConstructor, nativeConstructor);
+  }
+  function registerInternal(nativePrototype, wrapperConstructor, opt_instance) {
+    var wrapperPrototype = wrapperConstructor.prototype;
+    assert(constructorTable.get(nativePrototype) === undefined);
+    constructorTable.set(nativePrototype, wrapperConstructor);
+    nativePrototypeTable.set(wrapperPrototype, nativePrototype);
+    addForwardingProperties(nativePrototype, wrapperPrototype);
+    if (opt_instance) registerInstanceProperties(wrapperPrototype, opt_instance);
+    defineNonEnumerableDataProperty(wrapperPrototype, "constructor", wrapperConstructor);
+    wrapperConstructor.prototype = wrapperPrototype;
+  }
+  function isWrapperFor(wrapperConstructor, nativeConstructor) {
+    return constructorTable.get(nativeConstructor.prototype) === wrapperConstructor;
+  }
+  function registerObject(object) {
+    var nativePrototype = Object.getPrototypeOf(object);
+    var superWrapperConstructor = getWrapperConstructor(nativePrototype);
+    var GeneratedWrapper = createWrapperConstructor(superWrapperConstructor);
+    registerInternal(nativePrototype, GeneratedWrapper, object);
+    return GeneratedWrapper;
+  }
+  function createWrapperConstructor(superWrapperConstructor) {
+    function GeneratedWrapper(node) {
+      superWrapperConstructor.call(this, node);
+    }
+    var p = Object.create(superWrapperConstructor.prototype);
+    p.constructor = GeneratedWrapper;
+    GeneratedWrapper.prototype = p;
+    return GeneratedWrapper;
+  }
+  function isWrapper(object) {
+    return object && object.__impl4cf1e782hg__;
+  }
+  function isNative(object) {
+    return !isWrapper(object);
+  }
+  function wrap(impl) {
+    if (impl === null) return null;
+    assert(isNative(impl));
+    return impl.__wrapper8e3dd93a60__ || (impl.__wrapper8e3dd93a60__ = new (getWrapperConstructor(impl))(impl));
+  }
+  function unwrap(wrapper) {
+    if (wrapper === null) return null;
+    assert(isWrapper(wrapper));
+    return wrapper.__impl4cf1e782hg__;
+  }
+  function unsafeUnwrap(wrapper) {
+    return wrapper.__impl4cf1e782hg__;
+  }
+  function setWrapper(impl, wrapper) {
+    wrapper.__impl4cf1e782hg__ = impl;
+    impl.__wrapper8e3dd93a60__ = wrapper;
+  }
+  function unwrapIfNeeded(object) {
+    return object && isWrapper(object) ? unwrap(object) : object;
+  }
+  function wrapIfNeeded(object) {
+    return object && !isWrapper(object) ? wrap(object) : object;
+  }
+  function rewrap(node, wrapper) {
+    if (wrapper === null) return;
+    assert(isNative(node));
+    assert(wrapper === undefined || isWrapper(wrapper));
+    node.__wrapper8e3dd93a60__ = wrapper;
+  }
+  var getterDescriptor = {
+    get: undefined,
+    configurable: true,
+    enumerable: true
+  };
+  function defineGetter(constructor, name, getter) {
+    getterDescriptor.get = getter;
+    defineProperty(constructor.prototype, name, getterDescriptor);
+  }
+  function defineWrapGetter(constructor, name) {
+    defineGetter(constructor, name, function() {
+      return wrap(this.__impl4cf1e782hg__[name]);
+    });
+  }
+  function forwardMethodsToWrapper(constructors, names) {
+    constructors.forEach(function(constructor) {
+      names.forEach(function(name) {
+        constructor.prototype[name] = function() {
+          var w = wrapIfNeeded(this);
+          return w[name].apply(w, arguments);
+        };
+      });
+    });
+  }
+  scope.assert = assert;
+  scope.constructorTable = constructorTable;
+  scope.defineGetter = defineGetter;
+  scope.defineWrapGetter = defineWrapGetter;
+  scope.forwardMethodsToWrapper = forwardMethodsToWrapper;
+  scope.isWrapper = isWrapper;
+  scope.isWrapperFor = isWrapperFor;
+  scope.mixin = mixin;
+  scope.nativePrototypeTable = nativePrototypeTable;
+  scope.oneOf = oneOf;
+  scope.registerObject = registerObject;
+  scope.registerWrapper = register;
+  scope.rewrap = rewrap;
+  scope.setWrapper = setWrapper;
+  scope.unsafeUnwrap = unsafeUnwrap;
+  scope.unwrap = unwrap;
+  scope.unwrapIfNeeded = unwrapIfNeeded;
+  scope.wrap = wrap;
+  scope.wrapIfNeeded = wrapIfNeeded;
+  scope.wrappers = wrappers;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  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;
+    }
+  };
+  scope.ArraySplice = ArraySplice;
+})(window.ShadowDOMPolyfill);
+
+(function(context) {
+  "use strict";
+  var OriginalMutationObserver = window.MutationObserver;
+  var callbacks = [];
+  var pending = false;
+  var timerFunc;
+  function handle() {
+    pending = false;
+    var copies = callbacks.slice(0);
+    callbacks = [];
+    for (var i = 0; i < copies.length; i++) {
+      (0, copies[i])();
+    }
+  }
+  if (OriginalMutationObserver) {
+    var counter = 1;
+    var observer = new OriginalMutationObserver(handle);
+    var textNode = document.createTextNode(counter);
+    observer.observe(textNode, {
+      characterData: true
+    });
+    timerFunc = function() {
+      counter = (counter + 1) % 2;
+      textNode.data = counter;
+    };
+  } else {
+    timerFunc = window.setTimeout;
+  }
+  function setEndOfMicrotask(func) {
+    callbacks.push(func);
+    if (pending) return;
+    pending = true;
+    timerFunc(handle, 0);
+  }
+  context.setEndOfMicrotask = setEndOfMicrotask;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var setEndOfMicrotask = scope.setEndOfMicrotask;
+  var wrapIfNeeded = scope.wrapIfNeeded;
+  var wrappers = scope.wrappers;
+  var registrationsTable = new WeakMap();
+  var globalMutationObservers = [];
+  var isScheduled = false;
+  function scheduleCallback(observer) {
+    if (observer.scheduled_) return;
+    observer.scheduled_ = true;
+    globalMutationObservers.push(observer);
+    if (isScheduled) return;
+    setEndOfMicrotask(notifyObservers);
+    isScheduled = true;
+  }
+  function notifyObservers() {
+    isScheduled = false;
+    while (globalMutationObservers.length) {
+      var notifyList = globalMutationObservers;
+      globalMutationObservers = [];
+      notifyList.sort(function(x, y) {
+        return x.uid_ - y.uid_;
+      });
+      for (var i = 0; i < notifyList.length; i++) {
+        var mo = notifyList[i];
+        mo.scheduled_ = false;
+        var queue = mo.takeRecords();
+        removeTransientObserversFor(mo);
+        if (queue.length) {
+          mo.callback_(queue, mo);
+        }
+      }
+    }
+  }
+  function MutationRecord(type, target) {
+    this.type = type;
+    this.target = target;
+    this.addedNodes = new wrappers.NodeList();
+    this.removedNodes = new wrappers.NodeList();
+    this.previousSibling = null;
+    this.nextSibling = null;
+    this.attributeName = null;
+    this.attributeNamespace = null;
+    this.oldValue = null;
+  }
+  function registerTransientObservers(ancestor, node) {
+    for (;ancestor; ancestor = ancestor.parentNode) {
+      var registrations = registrationsTable.get(ancestor);
+      if (!registrations) continue;
+      for (var i = 0; i < registrations.length; i++) {
+        var registration = registrations[i];
+        if (registration.options.subtree) registration.addTransientObserver(node);
+      }
+    }
+  }
+  function removeTransientObserversFor(observer) {
+    for (var i = 0; i < observer.nodes_.length; i++) {
+      var node = observer.nodes_[i];
+      var registrations = registrationsTable.get(node);
+      if (!registrations) return;
+      for (var j = 0; j < registrations.length; j++) {
+        var registration = registrations[j];
+        if (registration.observer === observer) registration.removeTransientObservers();
+      }
+    }
+  }
+  function enqueueMutation(target, type, data) {
+    var interestedObservers = Object.create(null);
+    var associatedStrings = Object.create(null);
+    for (var node = target; node; node = node.parentNode) {
+      var registrations = registrationsTable.get(node);
+      if (!registrations) continue;
+      for (var j = 0; j < registrations.length; j++) {
+        var registration = registrations[j];
+        var options = registration.options;
+        if (node !== target && !options.subtree) continue;
+        if (type === "attributes" && !options.attributes) continue;
+        if (type === "attributes" && options.attributeFilter && (data.namespace !== null || options.attributeFilter.indexOf(data.name) === -1)) {
+          continue;
+        }
+        if (type === "characterData" && !options.characterData) continue;
+        if (type === "childList" && !options.childList) continue;
+        var observer = registration.observer;
+        interestedObservers[observer.uid_] = observer;
+        if (type === "attributes" && options.attributeOldValue || type === "characterData" && options.characterDataOldValue) {
+          associatedStrings[observer.uid_] = data.oldValue;
+        }
+      }
+    }
+    for (var uid in interestedObservers) {
+      var observer = interestedObservers[uid];
+      var record = new MutationRecord(type, target);
+      if ("name" in data && "namespace" in data) {
+        record.attributeName = data.name;
+        record.attributeNamespace = data.namespace;
+      }
+      if (data.addedNodes) record.addedNodes = data.addedNodes;
+      if (data.removedNodes) record.removedNodes = data.removedNodes;
+      if (data.previousSibling) record.previousSibling = data.previousSibling;
+      if (data.nextSibling) record.nextSibling = data.nextSibling;
+      if (associatedStrings[uid] !== undefined) record.oldValue = associatedStrings[uid];
+      scheduleCallback(observer);
+      observer.records_.push(record);
+    }
+  }
+  var slice = Array.prototype.slice;
+  function MutationObserverOptions(options) {
+    this.childList = !!options.childList;
+    this.subtree = !!options.subtree;
+    if (!("attributes" in options) && ("attributeOldValue" in options || "attributeFilter" in options)) {
+      this.attributes = true;
+    } else {
+      this.attributes = !!options.attributes;
+    }
+    if ("characterDataOldValue" in options && !("characterData" in options)) this.characterData = true; else this.characterData = !!options.characterData;
+    if (!this.attributes && (options.attributeOldValue || "attributeFilter" in options) || !this.characterData && options.characterDataOldValue) {
+      throw new TypeError();
+    }
+    this.characterData = !!options.characterData;
+    this.attributeOldValue = !!options.attributeOldValue;
+    this.characterDataOldValue = !!options.characterDataOldValue;
+    if ("attributeFilter" in options) {
+      if (options.attributeFilter == null || typeof options.attributeFilter !== "object") {
+        throw new TypeError();
+      }
+      this.attributeFilter = slice.call(options.attributeFilter);
+    } else {
+      this.attributeFilter = null;
+    }
+  }
+  var uidCounter = 0;
+  function MutationObserver(callback) {
+    this.callback_ = callback;
+    this.nodes_ = [];
+    this.records_ = [];
+    this.uid_ = ++uidCounter;
+    this.scheduled_ = false;
+  }
+  MutationObserver.prototype = {
+    constructor: MutationObserver,
+    observe: function(target, options) {
+      target = wrapIfNeeded(target);
+      var newOptions = new MutationObserverOptions(options);
+      var registration;
+      var registrations = registrationsTable.get(target);
+      if (!registrations) registrationsTable.set(target, registrations = []);
+      for (var i = 0; i < registrations.length; i++) {
+        if (registrations[i].observer === this) {
+          registration = registrations[i];
+          registration.removeTransientObservers();
+          registration.options = newOptions;
+        }
+      }
+      if (!registration) {
+        registration = new Registration(this, target, newOptions);
+        registrations.push(registration);
+        this.nodes_.push(target);
+      }
+    },
+    disconnect: function() {
+      this.nodes_.forEach(function(node) {
+        var registrations = registrationsTable.get(node);
+        for (var i = 0; i < registrations.length; i++) {
+          var registration = registrations[i];
+          if (registration.observer === this) {
+            registrations.splice(i, 1);
+            break;
+          }
+        }
+      }, this);
+      this.records_ = [];
+    },
+    takeRecords: function() {
+      var copyOfRecords = this.records_;
+      this.records_ = [];
+      return copyOfRecords;
+    }
+  };
+  function Registration(observer, target, options) {
+    this.observer = observer;
+    this.target = target;
+    this.options = options;
+    this.transientObservedNodes = [];
+  }
+  Registration.prototype = {
+    addTransientObserver: function(node) {
+      if (node === this.target) return;
+      scheduleCallback(this.observer);
+      this.transientObservedNodes.push(node);
+      var registrations = registrationsTable.get(node);
+      if (!registrations) registrationsTable.set(node, registrations = []);
+      registrations.push(this);
+    },
+    removeTransientObservers: function() {
+      var transientObservedNodes = this.transientObservedNodes;
+      this.transientObservedNodes = [];
+      for (var i = 0; i < transientObservedNodes.length; i++) {
+        var node = transientObservedNodes[i];
+        var registrations = registrationsTable.get(node);
+        for (var j = 0; j < registrations.length; j++) {
+          if (registrations[j] === this) {
+            registrations.splice(j, 1);
+            break;
+          }
+        }
+      }
+    }
+  };
+  scope.enqueueMutation = enqueueMutation;
+  scope.registerTransientObservers = registerTransientObservers;
+  scope.wrappers.MutationObserver = MutationObserver;
+  scope.wrappers.MutationRecord = MutationRecord;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  function TreeScope(root, parent) {
+    this.root = root;
+    this.parent = parent;
+  }
+  TreeScope.prototype = {
+    get renderer() {
+      if (this.root instanceof scope.wrappers.ShadowRoot) {
+        return scope.getRendererForHost(this.root.host);
+      }
+      return null;
+    },
+    contains: function(treeScope) {
+      for (;treeScope; treeScope = treeScope.parent) {
+        if (treeScope === this) return true;
+      }
+      return false;
+    }
+  };
+  function setTreeScope(node, treeScope) {
+    if (node.treeScope_ !== treeScope) {
+      node.treeScope_ = treeScope;
+      for (var sr = node.shadowRoot; sr; sr = sr.olderShadowRoot) {
+        sr.treeScope_.parent = treeScope;
+      }
+      for (var child = node.firstChild; child; child = child.nextSibling) {
+        setTreeScope(child, treeScope);
+      }
+    }
+  }
+  function getTreeScope(node) {
+    if (node instanceof scope.wrappers.Window) {
+      debugger;
+    }
+    if (node.treeScope_) return node.treeScope_;
+    var parent = node.parentNode;
+    var treeScope;
+    if (parent) treeScope = getTreeScope(parent); else treeScope = new TreeScope(node, null);
+    return node.treeScope_ = treeScope;
+  }
+  scope.TreeScope = TreeScope;
+  scope.getTreeScope = getTreeScope;
+  scope.setTreeScope = setTreeScope;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
+  var getTreeScope = scope.getTreeScope;
+  var mixin = scope.mixin;
+  var registerWrapper = scope.registerWrapper;
+  var setWrapper = scope.setWrapper;
+  var unsafeUnwrap = scope.unsafeUnwrap;
+  var unwrap = scope.unwrap;
+  var wrap = scope.wrap;
+  var wrappers = scope.wrappers;
+  var wrappedFuns = new WeakMap();
+  var listenersTable = new WeakMap();
+  var handledEventsTable = new WeakMap();
+  var currentlyDispatchingEvents = new WeakMap();
+  var targetTable = new WeakMap();
+  var currentTargetTable = new WeakMap();
+  var relatedTargetTable = new WeakMap();
+  var eventPhaseTable = new WeakMap();
+  var stopPropagationTable = new WeakMap();
+  var stopImmediatePropagationTable = new WeakMap();
+  var eventHandlersTable = new WeakMap();
+  var eventPathTable = new WeakMap();
+  function isShadowRoot(node) {
+    return node instanceof wrappers.ShadowRoot;
+  }
+  function rootOfNode(node) {
+    return getTreeScope(node).root;
+  }
+  function getEventPath(node, event) {
+    var path = [];
+    var current = node;
+    path.push(current);
+    while (current) {
+      var destinationInsertionPoints = getDestinationInsertionPoints(current);
+      if (destinationInsertionPoints && destinationInsertionPoints.length > 0) {
+        for (var i = 0; i < destinationInsertionPoints.length; i++) {
+          var insertionPoint = destinationInsertionPoints[i];
+          if (isShadowInsertionPoint(insertionPoint)) {
+            var shadowRoot = rootOfNode(insertionPoint);
+            var olderShadowRoot = shadowRoot.olderShadowRoot;
+            if (olderShadowRoot) path.push(olderShadowRoot);
+          }
+          path.push(insertionPoint);
+        }
+        current = destinationInsertionPoints[destinationInsertionPoints.length - 1];
+      } else {
+        if (isShadowRoot(current)) {
+          if (inSameTree(node, current) && eventMustBeStopped(event)) {
+            break;
+          }
+          current = current.host;
+          path.push(current);
+        } else {
+          current = current.parentNode;
+          if (current) path.push(current);
+        }
+      }
+    }
+    return path;
+  }
+  function eventMustBeStopped(event) {
+    if (!event) return false;
+    switch (event.type) {
+     case "abort":
+     case "error":
+     case "select":
+     case "change":
+     case "load":
+     case "reset":
+     case "resize":
+     case "scroll":
+     case "selectstart":
+      return true;
+    }
+    return false;
+  }
+  function isShadowInsertionPoint(node) {
+    return node instanceof HTMLShadowElement;
+  }
+  function getDestinationInsertionPoints(node) {
+    return scope.getDestinationInsertionPoints(node);
+  }
+  function eventRetargetting(path, currentTarget) {
+    if (path.length === 0) return currentTarget;
+    if (currentTarget instanceof wrappers.Window) currentTarget = currentTarget.document;
+    var currentTargetTree = getTreeScope(currentTarget);
+    var originalTarget = path[0];
+    var originalTargetTree = getTreeScope(originalTarget);
+    var relativeTargetTree = lowestCommonInclusiveAncestor(currentTargetTree, originalTargetTree);
+    for (var i = 0; i < path.length; i++) {
+      var node = path[i];
+      if (getTreeScope(node) === relativeTargetTree) return node;
+    }
+    return path[path.length - 1];
+  }
+  function getTreeScopeAncestors(treeScope) {
+    var ancestors = [];
+    for (;treeScope; treeScope = treeScope.parent) {
+      ancestors.push(treeScope);
+    }
+    return ancestors;
+  }
+  function lowestCommonInclusiveAncestor(tsA, tsB) {
+    var ancestorsA = getTreeScopeAncestors(tsA);
+    var ancestorsB = getTreeScopeAncestors(tsB);
+    var result = null;
+    while (ancestorsA.length > 0 && ancestorsB.length > 0) {
+      var a = ancestorsA.pop();
+      var b = ancestorsB.pop();
+      if (a === b) result = a; else break;
+    }
+    return result;
+  }
+  function getTreeScopeRoot(ts) {
+    if (!ts.parent) return ts;
+    return getTreeScopeRoot(ts.parent);
+  }
+  function relatedTargetResolution(event, currentTarget, relatedTarget) {
+    if (currentTarget instanceof wrappers.Window) currentTarget = currentTarget.document;
+    var currentTargetTree = getTreeScope(currentTarget);
+    var relatedTargetTree = getTreeScope(relatedTarget);
+    var relatedTargetEventPath = getEventPath(relatedTarget, event);
+    var lowestCommonAncestorTree;
+    var lowestCommonAncestorTree = lowestCommonInclusiveAncestor(currentTargetTree, relatedTargetTree);
+    if (!lowestCommonAncestorTree) lowestCommonAncestorTree = relatedTargetTree.root;
+    for (var commonAncestorTree = lowestCommonAncestorTree; commonAncestorTree; commonAncestorTree = commonAncestorTree.parent) {
+      var adjustedRelatedTarget;
+      for (var i = 0; i < relatedTargetEventPath.length; i++) {
+        var node = relatedTargetEventPath[i];
+        if (getTreeScope(node) === commonAncestorTree) return node;
+      }
+    }
+    return null;
+  }
+  function inSameTree(a, b) {
+    return getTreeScope(a) === getTreeScope(b);
+  }
+  var NONE = 0;
+  var CAPTURING_PHASE = 1;
+  var AT_TARGET = 2;
+  var BUBBLING_PHASE = 3;
+  var pendingError;
+  function dispatchOriginalEvent(originalEvent) {
+    if (handledEventsTable.get(originalEvent)) return;
+    handledEventsTable.set(originalEvent, true);
+    dispatchEvent(wrap(originalEvent), wrap(originalEvent.target));
+    if (pendingError) {
+      var err = pendingError;
+      pendingError = null;
+      throw err;
+    }
+  }
+  function isLoadLikeEvent(event) {
+    switch (event.type) {
+     case "load":
+     case "beforeunload":
+     case "unload":
+      return true;
+    }
+    return false;
+  }
+  function dispatchEvent(event, originalWrapperTarget) {
+    if (currentlyDispatchingEvents.get(event)) throw new Error("InvalidStateError");
+    currentlyDispatchingEvents.set(event, true);
+    scope.renderAllPending();
+    var eventPath;
+    var overrideTarget;
+    var win;
+    if (isLoadLikeEvent(event) && !event.bubbles) {
+      var doc = originalWrapperTarget;
+      if (doc instanceof wrappers.Document && (win = doc.defaultView)) {
+        overrideTarget = doc;
+        eventPath = [];
+      }
+    }
+    if (!eventPath) {
+      if (originalWrapperTarget instanceof wrappers.Window) {
+        win = originalWrapperTarget;
+        eventPath = [];
+      } else {
+        eventPath = getEventPath(originalWrapperTarget, event);
+        if (!isLoadLikeEvent(event)) {
+          var doc = eventPath[eventPath.length - 1];
+          if (doc instanceof wrappers.Document) win = doc.defaultView;
+        }
+      }
+    }
+    eventPathTable.set(event, eventPath);
+    if (dispatchCapturing(event, eventPath, win, overrideTarget)) {
+      if (dispatchAtTarget(event, eventPath, win, overrideTarget)) {
+        dispatchBubbling(event, eventPath, win, overrideTarget);
+      }
+    }
+    eventPhaseTable.set(event, NONE);
+    currentTargetTable.delete(event, null);
+    currentlyDispatchingEvents.delete(event);
+    return event.defaultPrevented;
+  }
+  function dispatchCapturing(event, eventPath, win, overrideTarget) {
+    var phase = CAPTURING_PHASE;
+    if (win) {
+      if (!invoke(win, event, phase, eventPath, overrideTarget)) return false;
+    }
+    for (var i = eventPath.length - 1; i > 0; i--) {
+      if (!invoke(eventPath[i], event, phase, eventPath, overrideTarget)) return false;
+    }
+    return true;
+  }
+  function dispatchAtTarget(event, eventPath, win, overrideTarget) {
+    var phase = AT_TARGET;
+    var currentTarget = eventPath[0] || win;
+    return invoke(currentTarget, event, phase, eventPath, overrideTarget);
+  }
+  function dispatchBubbling(event, eventPath, win, overrideTarget) {
+    var phase = BUBBLING_PHASE;
+    for (var i = 1; i < eventPath.length; i++) {
+      if (!invoke(eventPath[i], event, phase, eventPath, overrideTarget)) return;
+    }
+    if (win && eventPath.length > 0) {
+      invoke(win, event, phase, eventPath, overrideTarget);
+    }
+  }
+  function invoke(currentTarget, event, phase, eventPath, overrideTarget) {
+    var listeners = listenersTable.get(currentTarget);
+    if (!listeners) return true;
+    var target = overrideTarget || eventRetargetting(eventPath, currentTarget);
+    if (target === currentTarget) {
+      if (phase === CAPTURING_PHASE) return true;
+      if (phase === BUBBLING_PHASE) phase = AT_TARGET;
+    } else if (phase === BUBBLING_PHASE && !event.bubbles) {
+      return true;
+    }
+    if ("relatedTarget" in event) {
+      var originalEvent = unwrap(event);
+      var unwrappedRelatedTarget = originalEvent.relatedTarget;
+      if (unwrappedRelatedTarget) {
+        if (unwrappedRelatedTarget instanceof Object && unwrappedRelatedTarget.addEventListener) {
+          var relatedTarget = wrap(unwrappedRelatedTarget);
+          var adjusted = relatedTargetResolution(event, currentTarget, relatedTarget);
+          if (adjusted === target) return true;
+        } else {
+          adjusted = null;
+        }
+        relatedTargetTable.set(event, adjusted);
+      }
+    }
+    eventPhaseTable.set(event, phase);
+    var type = event.type;
+    var anyRemoved = false;
+    targetTable.set(event, target);
+    currentTargetTable.set(event, currentTarget);
+    listeners.depth++;
+    for (var i = 0, len = listeners.length; i < len; i++) {
+      var listener = listeners[i];
+      if (listener.removed) {
+        anyRemoved = true;
+        continue;
+      }
+      if (listener.type !== type || !listener.capture && phase === CAPTURING_PHASE || listener.capture && phase === BUBBLING_PHASE) {
+        continue;
+      }
+      try {
+        if (typeof listener.handler === "function") listener.handler.call(currentTarget, event); else listener.handler.handleEvent(event);
+        if (stopImmediatePropagationTable.get(event)) return false;
+      } catch (ex) {
+        if (!pendingError) pendingError = ex;
+      }
+    }
+    listeners.depth--;
+    if (anyRemoved && listeners.depth === 0) {
+      var copy = listeners.slice();
+      listeners.length = 0;
+      for (var i = 0; i < copy.length; i++) {
+        if (!copy[i].removed) listeners.push(copy[i]);
+      }
+    }
+    return !stopPropagationTable.get(event);
+  }
+  function Listener(type, handler, capture) {
+    this.type = type;
+    this.handler = handler;
+    this.capture = Boolean(capture);
+  }
+  Listener.prototype = {
+    equals: function(that) {
+      return this.handler === that.handler && this.type === that.type && this.capture === that.capture;
+    },
+    get removed() {
+      return this.handler === null;
+    },
+    remove: function() {
+      this.handler = null;
+    }
+  };
+  var OriginalEvent = window.Event;
+  OriginalEvent.prototype.polymerBlackList_ = {
+    returnValue: true,
+    keyLocation: true
+  };
+  function Event(type, options) {
+    if (type instanceof OriginalEvent) {
+      var impl = type;
+      if (!OriginalBeforeUnloadEvent && impl.type === "beforeunload" && !(this instanceof BeforeUnloadEvent)) {
+        return new BeforeUnloadEvent(impl);
+      }
+      setWrapper(impl, this);
+    } else {
+      return wrap(constructEvent(OriginalEvent, "Event", type, options));
+    }
+  }
+  Event.prototype = {
+    get target() {
+      return targetTable.get(this);
+    },
+    get currentTarget() {
+      return currentTargetTable.get(this);
+    },
+    get eventPhase() {
+      return eventPhaseTable.get(this);
+    },
+    get path() {
+      var eventPath = eventPathTable.get(this);
+      if (!eventPath) return [];
+      return eventPath.slice();
+    },
+    stopPropagation: function() {
+      stopPropagationTable.set(this, true);
+    },
+    stopImmediatePropagation: function() {
+      stopPropagationTable.set(this, true);
+      stopImmediatePropagationTable.set(this, true);
+    }
+  };
+  registerWrapper(OriginalEvent, Event, document.createEvent("Event"));
+  function unwrapOptions(options) {
+    if (!options || !options.relatedTarget) return options;
+    return Object.create(options, {
+      relatedTarget: {
+        value: unwrap(options.relatedTarget)
+      }
+    });
+  }
+  function registerGenericEvent(name, SuperEvent, prototype) {
+    var OriginalEvent = window[name];
+    var GenericEvent = function(type, options) {
+      if (type instanceof OriginalEvent) setWrapper(type, this); else return wrap(constructEvent(OriginalEvent, name, type, options));
+    };
+    GenericEvent.prototype = Object.create(SuperEvent.prototype);
+    if (prototype) mixin(GenericEvent.prototype, prototype);
+    if (OriginalEvent) {
+      try {
+        registerWrapper(OriginalEvent, GenericEvent, new OriginalEvent("temp"));
+      } catch (ex) {
+        registerWrapper(OriginalEvent, GenericEvent, document.createEvent(name));
+      }
+    }
+    return GenericEvent;
+  }
+  var UIEvent = registerGenericEvent("UIEvent", Event);
+  var CustomEvent = registerGenericEvent("CustomEvent", Event);
+  var relatedTargetProto = {
+    get relatedTarget() {
+      var relatedTarget = relatedTargetTable.get(this);
+      if (relatedTarget !== undefined) return relatedTarget;
+      return wrap(unwrap(this).relatedTarget);
+    }
+  };
+  function getInitFunction(name, relatedTargetIndex) {
+    return function() {
+      arguments[relatedTargetIndex] = unwrap(arguments[relatedTargetIndex]);
+      var impl = unwrap(this);
+      impl[name].apply(impl, arguments);
+    };
+  }
+  var mouseEventProto = mixin({
+    initMouseEvent: getInitFunction("initMouseEvent", 14)
+  }, relatedTargetProto);
+  var focusEventProto = mixin({
+    initFocusEvent: getInitFunction("initFocusEvent", 5)
+  }, relatedTargetProto);
+  var MouseEvent = registerGenericEvent("MouseEvent", UIEvent, mouseEventProto);
+  var FocusEvent = registerGenericEvent("FocusEvent", UIEvent, focusEventProto);
+  var defaultInitDicts = Object.create(null);
+  var supportsEventConstructors = function() {
+    try {
+      new window.FocusEvent("focus");
+    } catch (ex) {
+      return false;
+    }
+    return true;
+  }();
+  function constructEvent(OriginalEvent, name, type, options) {
+    if (supportsEventConstructors) return new OriginalEvent(type, unwrapOptions(options));
+    var event = unwrap(document.createEvent(name));
+    var defaultDict = defaultInitDicts[name];
+    var args = [ type ];
+    Object.keys(defaultDict).forEach(function(key) {
+      var v = options != null && key in options ? options[key] : defaultDict[key];
+      if (key === "relatedTarget") v = unwrap(v);
+      args.push(v);
+    });
+    event["init" + name].apply(event, args);
+    return event;
+  }
+  if (!supportsEventConstructors) {
+    var configureEventConstructor = function(name, initDict, superName) {
+      if (superName) {
+        var superDict = defaultInitDicts[superName];
+        initDict = mixin(mixin({}, superDict), initDict);
+      }
+      defaultInitDicts[name] = initDict;
+    };
+    configureEventConstructor("Event", {
+      bubbles: false,
+      cancelable: false
+    });
+    configureEventConstructor("CustomEvent", {
+      detail: null
+    }, "Event");
+    configureEventConstructor("UIEvent", {
+      view: null,
+      detail: 0
+    }, "Event");
+    configureEventConstructor("MouseEvent", {
+      screenX: 0,
+      screenY: 0,
+      clientX: 0,
+      clientY: 0,
+      ctrlKey: false,
+      altKey: false,
+      shiftKey: false,
+      metaKey: false,
+      button: 0,
+      relatedTarget: null
+    }, "UIEvent");
+    configureEventConstructor("FocusEvent", {
+      relatedTarget: null
+    }, "UIEvent");
+  }
+  var OriginalBeforeUnloadEvent = window.BeforeUnloadEvent;
+  function BeforeUnloadEvent(impl) {
+    Event.call(this, impl);
+  }
+  BeforeUnloadEvent.prototype = Object.create(Event.prototype);
+  mixin(BeforeUnloadEvent.prototype, {
+    get returnValue() {
+      return unsafeUnwrap(this).returnValue;
+    },
+    set returnValue(v) {
+      unsafeUnwrap(this).returnValue = v;
+    }
+  });
+  if (OriginalBeforeUnloadEvent) registerWrapper(OriginalBeforeUnloadEvent, BeforeUnloadEvent);
+  function isValidListener(fun) {
+    if (typeof fun === "function") return true;
+    return fun && fun.handleEvent;
+  }
+  function isMutationEvent(type) {
+    switch (type) {
+     case "DOMAttrModified":
+     case "DOMAttributeNameChanged":
+     case "DOMCharacterDataModified":
+     case "DOMElementNameChanged":
+     case "DOMNodeInserted":
+     case "DOMNodeInsertedIntoDocument":
+     case "DOMNodeRemoved":
+     case "DOMNodeRemovedFromDocument":
+     case "DOMSubtreeModified":
+      return true;
+    }
+    return false;
+  }
+  var OriginalEventTarget = window.EventTarget;
+  function EventTarget(impl) {
+    setWrapper(impl, this);
+  }
+  var methodNames = [ "addEventListener", "removeEventListener", "dispatchEvent" ];
+  [ Node, Window ].forEach(function(constructor) {
+    var p = constructor.prototype;
+    methodNames.forEach(function(name) {
+      Object.defineProperty(p, name + "_", {
+        value: p[name]
+      });
+    });
+  });
+  function getTargetToListenAt(wrapper) {
+    if (wrapper instanceof wrappers.ShadowRoot) wrapper = wrapper.host;
+    return unwrap(wrapper);
+  }
+  EventTarget.prototype = {
+    addEventListener: function(type, fun, capture) {
+      if (!isValidListener(fun) || isMutationEvent(type)) return;
+      var listener = new Listener(type, fun, capture);
+      var listeners = listenersTable.get(this);
+      if (!listeners) {
+        listeners = [];
+        listeners.depth = 0;
+        listenersTable.set(this, listeners);
+      } else {
+        for (var i = 0; i < listeners.length; i++) {
+          if (listener.equals(listeners[i])) return;
+        }
+      }
+      listeners.push(listener);
+      var target = getTargetToListenAt(this);
+      target.addEventListener_(type, dispatchOriginalEvent, true);
+    },
+    removeEventListener: function(type, fun, capture) {
+      capture = Boolean(capture);
+      var listeners = listenersTable.get(this);
+      if (!listeners) return;
+      var count = 0, found = false;
+      for (var i = 0; i < listeners.length; i++) {
+        if (listeners[i].type === type && listeners[i].capture === capture) {
+          count++;
+          if (listeners[i].handler === fun) {
+            found = true;
+            listeners[i].remove();
+          }
+        }
+      }
+      if (found && count === 1) {
+        var target = getTargetToListenAt(this);
+        target.removeEventListener_(type, dispatchOriginalEvent, true);
+      }
+    },
+    dispatchEvent: function(event) {
+      var nativeEvent = unwrap(event);
+      var eventType = nativeEvent.type;
+      handledEventsTable.set(nativeEvent, false);
+      scope.renderAllPending();
+      var tempListener;
+      if (!hasListenerInAncestors(this, eventType)) {
+        tempListener = function() {};
+        this.addEventListener(eventType, tempListener, true);
+      }
+      try {
+        return unwrap(this).dispatchEvent_(nativeEvent);
+      } finally {
+        if (tempListener) this.removeEventListener(eventType, tempListener, true);
+      }
+    }
+  };
+  function hasListener(node, type) {
+    var listeners = listenersTable.get(node);
+    if (listeners) {
+      for (var i = 0; i < listeners.length; i++) {
+        if (!listeners[i].removed && listeners[i].type === type) return true;
+      }
+    }
+    return false;
+  }
+  function hasListenerInAncestors(target, type) {
+    for (var node = unwrap(target); node; node = node.parentNode) {
+      if (hasListener(wrap(node), type)) return true;
+    }
+    return false;
+  }
+  if (OriginalEventTarget) registerWrapper(OriginalEventTarget, EventTarget);
+  function wrapEventTargetMethods(constructors) {
+    forwardMethodsToWrapper(constructors, methodNames);
+  }
+  var originalElementFromPoint = document.elementFromPoint;
+  function elementFromPoint(self, document, x, y) {
+    scope.renderAllPending();
+    var element = wrap(originalElementFromPoint.call(unsafeUnwrap(document), x, y));
+    if (!element) return null;
+    var path = getEventPath(element, null);
+    var idx = path.lastIndexOf(self);
+    if (idx == -1) return null; else path = path.slice(0, idx);
+    return eventRetargetting(path, self);
+  }
+  function getEventHandlerGetter(name) {
+    return function() {
+      var inlineEventHandlers = eventHandlersTable.get(this);
+      return inlineEventHandlers && inlineEventHandlers[name] && inlineEventHandlers[name].value || null;
+    };
+  }
+  function getEventHandlerSetter(name) {
+    var eventType = name.slice(2);
+    return function(value) {
+      var inlineEventHandlers = eventHandlersTable.get(this);
+      if (!inlineEventHandlers) {
+        inlineEventHandlers = Object.create(null);
+        eventHandlersTable.set(this, inlineEventHandlers);
+      }
+      var old = inlineEventHandlers[name];
+      if (old) this.removeEventListener(eventType, old.wrapped, false);
+      if (typeof value === "function") {
+        var wrapped = function(e) {
+          var rv = value.call(this, e);
+          if (rv === false) e.preventDefault(); else if (name === "onbeforeunload" && typeof rv === "string") e.returnValue = rv;
+        };
+        this.addEventListener(eventType, wrapped, false);
+        inlineEventHandlers[name] = {
+          value: value,
+          wrapped: wrapped
+        };
+      }
+    };
+  }
+  scope.elementFromPoint = elementFromPoint;
+  scope.getEventHandlerGetter = getEventHandlerGetter;
+  scope.getEventHandlerSetter = getEventHandlerSetter;
+  scope.wrapEventTargetMethods = wrapEventTargetMethods;
+  scope.wrappers.BeforeUnloadEvent = BeforeUnloadEvent;
+  scope.wrappers.CustomEvent = CustomEvent;
+  scope.wrappers.Event = Event;
+  scope.wrappers.EventTarget = EventTarget;
+  scope.wrappers.FocusEvent = FocusEvent;
+  scope.wrappers.MouseEvent = MouseEvent;
+  scope.wrappers.UIEvent = UIEvent;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var UIEvent = scope.wrappers.UIEvent;
+  var mixin = scope.mixin;
+  var registerWrapper = scope.registerWrapper;
+  var setWrapper = scope.setWrapper;
+  var unsafeUnwrap = scope.unsafeUnwrap;
+  var wrap = scope.wrap;
+  var OriginalTouchEvent = window.TouchEvent;
+  if (!OriginalTouchEvent) return;
+  var nativeEvent;
+  try {
+    nativeEvent = document.createEvent("TouchEvent");
+  } catch (ex) {
+    return;
+  }
+  var nonEnumDescriptor = {
+    enumerable: false
+  };
+  function nonEnum(obj, prop) {
+    Object.defineProperty(obj, prop, nonEnumDescriptor);
+  }
+  function Touch(impl) {
+    setWrapper(impl, this);
+  }
+  Touch.prototype = {
+    get target() {
+      return wrap(unsafeUnwrap(this).target);
+    }
+  };
+  var descr = {
+    configurable: true,
+    enumerable: true,
+    get: null
+  };
+  [ "clientX", "clientY", "screenX", "screenY", "pageX", "pageY", "identifier", "webkitRadiusX", "webkitRadiusY", "webkitRotationAngle", "webkitForce" ].forEach(function(name) {
+    descr.get = function() {
+      return unsafeUnwrap(this)[name];
+    };
+    Object.defineProperty(Touch.prototype, name, descr);
+  });
+  function TouchList() {
+    this.length = 0;
+    nonEnum(this, "length");
+  }
+  TouchList.prototype = {
+    item: function(index) {
+      return this[index];
+    }
+  };
+  function wrapTouchList(nativeTouchList) {
+    var list = new TouchList();
+    for (var i = 0; i < nativeTouchList.length; i++) {
+      list[i] = new Touch(nativeTouchList[i]);
+    }
+    list.length = i;
+    return list;
+  }
+  function TouchEvent(impl) {
+    UIEvent.call(this, impl);
+  }
+  TouchEvent.prototype = Object.create(UIEvent.prototype);
+  mixin(TouchEvent.prototype, {
+    get touches() {
+      return wrapTouchList(unsafeUnwrap(this).touches);
+    },
+    get targetTouches() {
+      return wrapTouchList(unsafeUnwrap(this).targetTouches);
+    },
+    get changedTouches() {
+      return wrapTouchList(unsafeUnwrap(this).changedTouches);
+    },
+    initTouchEvent: function() {
+      throw new Error("Not implemented");
+    }
+  });
+  registerWrapper(OriginalTouchEvent, TouchEvent, nativeEvent);
+  scope.wrappers.Touch = Touch;
+  scope.wrappers.TouchEvent = TouchEvent;
+  scope.wrappers.TouchList = TouchList;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var unsafeUnwrap = scope.unsafeUnwrap;
+  var wrap = scope.wrap;
+  var nonEnumDescriptor = {
+    enumerable: false
+  };
+  function nonEnum(obj, prop) {
+    Object.defineProperty(obj, prop, nonEnumDescriptor);
+  }
+  function NodeList() {
+    this.length = 0;
+    nonEnum(this, "length");
+  }
+  NodeList.prototype = {
+    item: function(index) {
+      return this[index];
+    }
+  };
+  nonEnum(NodeList.prototype, "item");
+  function wrapNodeList(list) {
+    if (list == null) return list;
+    var wrapperList = new NodeList();
+    for (var i = 0, length = list.length; i < length; i++) {
+      wrapperList[i] = wrap(list[i]);
+    }
+    wrapperList.length = length;
+    return wrapperList;
+  }
+  function addWrapNodeListMethod(wrapperConstructor, name) {
+    wrapperConstructor.prototype[name] = function() {
+      return wrapNodeList(unsafeUnwrap(this)[name].apply(unsafeUnwrap(this), arguments));
+    };
+  }
+  scope.wrappers.NodeList = NodeList;
+  scope.addWrapNodeListMethod = addWrapNodeListMethod;
+  scope.wrapNodeList = wrapNodeList;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  scope.wrapHTMLCollection = scope.wrapNodeList;
+  scope.wrappers.HTMLCollection = scope.wrappers.NodeList;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var EventTarget = scope.wrappers.EventTarget;
+  var NodeList = scope.wrappers.NodeList;
+  var TreeScope = scope.TreeScope;
+  var assert = scope.assert;
+  var defineWrapGetter = scope.defineWrapGetter;
+  var enqueueMutation = scope.enqueueMutation;
+  var getTreeScope = scope.getTreeScope;
+  var isWrapper = scope.isWrapper;
+  var mixin = scope.mixin;
+  var registerTransientObservers = scope.registerTransientObservers;
+  var registerWrapper = scope.registerWrapper;
+  var setTreeScope = scope.setTreeScope;
+  var unsafeUnwrap = scope.unsafeUnwrap;
+  var unwrap = scope.unwrap;
+  var unwrapIfNeeded = scope.unwrapIfNeeded;
+  var wrap = scope.wrap;
+  var wrapIfNeeded = scope.wrapIfNeeded;
+  var wrappers = scope.wrappers;
+  function assertIsNodeWrapper(node) {
+    assert(node instanceof Node);
+  }
+  function createOneElementNodeList(node) {
+    var nodes = new NodeList();
+    nodes[0] = node;
+    nodes.length = 1;
+    return nodes;
+  }
+  var surpressMutations = false;
+  function enqueueRemovalForInsertedNodes(node, parent, nodes) {
+    enqueueMutation(parent, "childList", {
+      removedNodes: nodes,
+      previousSibling: node.previousSibling,
+      nextSibling: node.nextSibling
+    });
+  }
+  function enqueueRemovalForInsertedDocumentFragment(df, nodes) {
+    enqueueMutation(df, "childList", {
+      removedNodes: nodes
+    });
+  }
+  function collectNodes(node, parentNode, previousNode, nextNode) {
+    if (node instanceof DocumentFragment) {
+      var nodes = collectNodesForDocumentFragment(node);
+      surpressMutations = true;
+      for (var i = nodes.length - 1; i >= 0; i--) {
+        node.removeChild(nodes[i]);
+        nodes[i].parentNode_ = parentNode;
+      }
+      surpressMutations = false;
+      for (var i = 0; i < nodes.length; i++) {
+        nodes[i].previousSibling_ = nodes[i - 1] || previousNode;
+        nodes[i].nextSibling_ = nodes[i + 1] || nextNode;
+      }
+      if (previousNode) previousNode.nextSibling_ = nodes[0];
+      if (nextNode) nextNode.previousSibling_ = nodes[nodes.length - 1];
+      return nodes;
+    }
+    var nodes = createOneElementNodeList(node);
+    var oldParent = node.parentNode;
+    if (oldParent) {
+      oldParent.removeChild(node);
+    }
+    node.parentNode_ = parentNode;
+    node.previousSibling_ = previousNode;
+    node.nextSibling_ = nextNode;
+    if (previousNode) previousNode.nextSibling_ = node;
+    if (nextNode) nextNode.previousSibling_ = node;
+    return nodes;
+  }
+  function collectNodesNative(node) {
+    if (node instanceof DocumentFragment) return collectNodesForDocumentFragment(node);
+    var nodes = createOneElementNodeList(node);
+    var oldParent = node.parentNode;
+    if (oldParent) enqueueRemovalForInsertedNodes(node, oldParent, nodes);
+    return nodes;
+  }
+  function collectNodesForDocumentFragment(node) {
+    var nodes = new NodeList();
+    var i = 0;
+    for (var child = node.firstChild; child; child = child.nextSibling) {
+      nodes[i++] = child;
+    }
+    nodes.length = i;
+    enqueueRemovalForInsertedDocumentFragment(node, nodes);
+    return nodes;
+  }
+  function snapshotNodeList(nodeList) {
+    return nodeList;
+  }
+  function nodeWasAdded(node, treeScope) {
+    setTreeScope(node, treeScope);
+    node.nodeIsInserted_();
+  }
+  function nodesWereAdded(nodes, parent) {
+    var treeScope = getTreeScope(parent);
+    for (var i = 0; i < nodes.length; i++) {
+      nodeWasAdded(nodes[i], treeScope);
+    }
+  }
+  function nodeWasRemoved(node) {
+    setTreeScope(node, new TreeScope(node, null));
+  }
+  function nodesWereRemoved(nodes) {
+    for (var i = 0; i < nodes.length; i++) {
+      nodeWasRemoved(nodes[i]);
+    }
+  }
+  function ensureSameOwnerDocument(parent, child) {
+    var ownerDoc = parent.nodeType === Node.DOCUMENT_NODE ? parent : parent.ownerDocument;
+    if (ownerDoc !== child.ownerDocument) ownerDoc.adoptNode(child);
+  }
+  function adoptNodesIfNeeded(owner, nodes) {
+    if (!nodes.length) return;
+    var ownerDoc = owner.ownerDocument;
+    if (ownerDoc === nodes[0].ownerDocument) return;
+    for (var i = 0; i < nodes.length; i++) {
+      scope.adoptNodeNoRemove(nodes[i], ownerDoc);
+    }
+  }
+  function unwrapNodesForInsertion(owner, nodes) {
+    adoptNodesIfNeeded(owner, nodes);
+    var length = nodes.length;
+    if (length === 1) return unwrap(nodes[0]);
+    var df = unwrap(owner.ownerDocument.createDocumentFragment());
+    for (var i = 0; i < length; i++) {
+      df.appendChild(unwrap(nodes[i]));
+    }
+    return df;
+  }
+  function clearChildNodes(wrapper) {
+    if (wrapper.firstChild_ !== undefined) {
+      var child = wrapper.firstChild_;
+      while (child) {
+        var tmp = child;
+        child = child.nextSibling_;
+        tmp.parentNode_ = tmp.previousSibling_ = tmp.nextSibling_ = undefined;
+      }
+    }
+    wrapper.firstChild_ = wrapper.lastChild_ = undefined;
+  }
+  function removeAllChildNodes(wrapper) {
+    if (wrapper.invalidateShadowRenderer()) {
+      var childWrapper = wrapper.firstChild;
+      while (childWrapper) {
+        assert(childWrapper.parentNode === wrapper);
+        var nextSibling = childWrapper.nextSibling;
+        var childNode = unwrap(childWrapper);
+        var parentNode = childNode.parentNode;
+        if (parentNode) originalRemoveChild.call(parentNode, childNode);
+        childWrapper.previousSibling_ = childWrapper.nextSibling_ = childWrapper.parentNode_ = null;
+        childWrapper = nextSibling;
+      }
+      wrapper.firstChild_ = wrapper.lastChild_ = null;
+    } else {
+      var node = unwrap(wrapper);
+      var child = node.firstChild;
+      var nextSibling;
+      while (child) {
+        nextSibling = child.nextSibling;
+        originalRemoveChild.call(node, child);
+        child = nextSibling;
+      }
+    }
+  }
+  function invalidateParent(node) {
+    var p = node.parentNode;
+    return p && p.invalidateShadowRenderer();
+  }
+  function cleanupNodes(nodes) {
+    for (var i = 0, n; i < nodes.length; i++) {
+      n = nodes[i];
+      n.parentNode.removeChild(n);
+    }
+  }
+  var originalImportNode = document.importNode;
+  var originalCloneNode = window.Node.prototype.cloneNode;
+  function cloneNode(node, deep, opt_doc) {
+    var clone;
+    if (opt_doc) clone = wrap(originalImportNode.call(opt_doc, unsafeUnwrap(node), false)); else clone = wrap(originalCloneNode.call(unsafeUnwrap(node), false));
+    if (deep) {
+      for (var child = node.firstChild; child; child = child.nextSibling) {
+        clone.appendChild(cloneNode(child, true, opt_doc));
+      }
+      if (node instanceof wrappers.HTMLTemplateElement) {
+        var cloneContent = clone.content;
+        for (var child = node.content.firstChild; child; child = child.nextSibling) {
+          cloneContent.appendChild(cloneNode(child, true, opt_doc));
+        }
+      }
+    }
+    return clone;
+  }
+  function contains(self, child) {
+    if (!child || getTreeScope(self) !== getTreeScope(child)) return false;
+    for (var node = child; node; node = node.parentNode) {
+      if (node === self) return true;
+    }
+    return false;
+  }
+  var OriginalNode = window.Node;
+  function Node(original) {
+    assert(original instanceof OriginalNode);
+    EventTarget.call(this, original);
+    this.parentNode_ = undefined;
+    this.firstChild_ = undefined;
+    this.lastChild_ = undefined;
+    this.nextSibling_ = undefined;
+    this.previousSibling_ = undefined;
+    this.treeScope_ = undefined;
+  }
+  var OriginalDocumentFragment = window.DocumentFragment;
+  var originalAppendChild = OriginalNode.prototype.appendChild;
+  var originalCompareDocumentPosition = OriginalNode.prototype.compareDocumentPosition;
+  var originalInsertBefore = OriginalNode.prototype.insertBefore;
+  var originalRemoveChild = OriginalNode.prototype.removeChild;
+  var originalReplaceChild = OriginalNode.prototype.replaceChild;
+  var isIe = /Trident|Edge/.test(navigator.userAgent);
+  var removeChildOriginalHelper = isIe ? function(parent, child) {
+    try {
+      originalRemoveChild.call(parent, child);
+    } catch (ex) {
+      if (!(parent instanceof OriginalDocumentFragment)) throw ex;
+    }
+  } : function(parent, child) {
+    originalRemoveChild.call(parent, child);
+  };
+  Node.prototype = Object.create(EventTarget.prototype);
+  mixin(Node.prototype, {
+    appendChild: function(childWrapper) {
+      return this.insertBefore(childWrapper, null);
+    },
+    insertBefore: function(childWrapper, refWrapper) {
+      assertIsNodeWrapper(childWrapper);
+      var refNode;
+      if (refWrapper) {
+        if (isWrapper(refWrapper)) {
+          refNode = unwrap(refWrapper);
+        } else {
+          refNode = refWrapper;
+          refWrapper = wrap(refNode);
+        }
+      } else {
+        refWrapper = null;
+        refNode = null;
+      }
+      refWrapper && assert(refWrapper.parentNode === this);
+      var nodes;
+      var previousNode = refWrapper ? refWrapper.previousSibling : this.lastChild;
+      var useNative = !this.invalidateShadowRenderer() && !invalidateParent(childWrapper);
+      if (useNative) nodes = collectNodesNative(childWrapper); else nodes = collectNodes(childWrapper, this, previousNode, refWrapper);
+      if (useNative) {
+        ensureSameOwnerDocument(this, childWrapper);
+        clearChildNodes(this);
+        originalInsertBefore.call(unsafeUnwrap(this), unwrap(childWrapper), refNode);
+      } else {
+        if (!previousNode) this.firstChild_ = nodes[0];
+        if (!refWrapper) {
+          this.lastChild_ = nodes[nodes.length - 1];
+          if (this.firstChild_ === undefined) this.firstChild_ = this.firstChild;
+        }
+        var parentNode = refNode ? refNode.parentNode : unsafeUnwrap(this);
+        if (parentNode) {
+          originalInsertBefore.call(parentNode, unwrapNodesForInsertion(this, nodes), refNode);
+        } else {
+          adoptNodesIfNeeded(this, nodes);
+        }
+      }
+      enqueueMutation(this, "childList", {
+        addedNodes: nodes,
+        nextSibling: refWrapper,
+        previousSibling: previousNode
+      });
+      nodesWereAdded(nodes, this);
+      return childWrapper;
+    },
+    removeChild: function(childWrapper) {
+      assertIsNodeWrapper(childWrapper);
+      if (childWrapper.parentNode !== this) {
+        var found = false;
+        var childNodes = this.childNodes;
+        for (var ieChild = this.firstChild; ieChild; ieChild = ieChild.nextSibling) {
+          if (ieChild === childWrapper) {
+            found = true;
+            break;
+          }
+        }
+        if (!found) {
+          throw new Error("NotFoundError");
+        }
+      }
+      var childNode = unwrap(childWrapper);
+      var childWrapperNextSibling = childWrapper.nextSibling;
+      var childWrapperPreviousSibling = childWrapper.previousSibling;
+      if (this.invalidateShadowRenderer()) {
+        var thisFirstChild = this.firstChild;
+        var thisLastChild = this.lastChild;
+        var parentNode = childNode.parentNode;
+        if (parentNode) removeChildOriginalHelper(parentNode, childNode);
+        if (thisFirstChild === childWrapper) this.firstChild_ = childWrapperNextSibling;
+        if (thisLastChild === childWrapper) this.lastChild_ = childWrapperPreviousSibling;
+        if (childWrapperPreviousSibling) childWrapperPreviousSibling.nextSibling_ = childWrapperNextSibling;
+        if (childWrapperNextSibling) {
+          childWrapperNextSibling.previousSibling_ = childWrapperPreviousSibling;
+        }
+        childWrapper.previousSibling_ = childWrapper.nextSibling_ = childWrapper.parentNode_ = undefined;
+      } else {
+        clearChildNodes(this);
+        removeChildOriginalHelper(unsafeUnwrap(this), childNode);
+      }
+      if (!surpressMutations) {
+        enqueueMutation(this, "childList", {
+          removedNodes: createOneElementNodeList(childWrapper),
+          nextSibling: childWrapperNextSibling,
+          previousSibling: childWrapperPreviousSibling
+        });
+      }
+      registerTransientObservers(this, childWrapper);
+      return childWrapper;
+    },
+    replaceChild: function(newChildWrapper, oldChildWrapper) {
+      assertIsNodeWrapper(newChildWrapper);
+      var oldChildNode;
+      if (isWrapper(oldChildWrapper)) {
+        oldChildNode = unwrap(oldChildWrapper);
+      } else {
+        oldChildNode = oldChildWrapper;
+        oldChildWrapper = wrap(oldChildNode);
+      }
+      if (oldChildWrapper.parentNode !== this) {
+        throw new Error("NotFoundError");
+      }
+      var nextNode = oldChildWrapper.nextSibling;
+      var previousNode = oldChildWrapper.previousSibling;
+      var nodes;
+      var useNative = !this.invalidateShadowRenderer() && !invalidateParent(newChildWrapper);
+      if (useNative) {
+        nodes = collectNodesNative(newChildWrapper);
+      } else {
+        if (nextNode === newChildWrapper) nextNode = newChildWrapper.nextSibling;
+        nodes = collectNodes(newChildWrapper, this, previousNode, nextNode);
+      }
+      if (!useNative) {
+        if (this.firstChild === oldChildWrapper) this.firstChild_ = nodes[0];
+        if (this.lastChild === oldChildWrapper) this.lastChild_ = nodes[nodes.length - 1];
+        oldChildWrapper.previousSibling_ = oldChildWrapper.nextSibling_ = oldChildWrapper.parentNode_ = undefined;
+        if (oldChildNode.parentNode) {
+          originalReplaceChild.call(oldChildNode.parentNode, unwrapNodesForInsertion(this, nodes), oldChildNode);
+        }
+      } else {
+        ensureSameOwnerDocument(this, newChildWrapper);
+        clearChildNodes(this);
+        originalReplaceChild.call(unsafeUnwrap(this), unwrap(newChildWrapper), oldChildNode);
+      }
+      enqueueMutation(this, "childList", {
+        addedNodes: nodes,
+        removedNodes: createOneElementNodeList(oldChildWrapper),
+        nextSibling: nextNode,
+        previousSibling: previousNode
+      });
+      nodeWasRemoved(oldChildWrapper);
+      nodesWereAdded(nodes, this);
+      return oldChildWrapper;
+    },
+    nodeIsInserted_: function() {
+      for (var child = this.firstChild; child; child = child.nextSibling) {
+        child.nodeIsInserted_();
+      }
+    },
+    hasChildNodes: function() {
+      return this.firstChild !== null;
+    },
+    get parentNode() {
+      return this.parentNode_ !== undefined ? this.parentNode_ : wrap(unsafeUnwrap(this).parentNode);
+    },
+    get firstChild() {
+      return this.firstChild_ !== undefined ? this.firstChild_ : wrap(unsafeUnwrap(this).firstChild);
+    },
+    get lastChild() {
+      return this.lastChild_ !== undefined ? this.lastChild_ : wrap(unsafeUnwrap(this).lastChild);
+    },
+    get nextSibling() {
+      return this.nextSibling_ !== undefined ? this.nextSibling_ : wrap(unsafeUnwrap(this).nextSibling);
+    },
+    get previousSibling() {
+      return this.previousSibling_ !== undefined ? this.previousSibling_ : wrap(unsafeUnwrap(this).previousSibling);
+    },
+    get parentElement() {
+      var p = this.parentNode;
+      while (p && p.nodeType !== Node.ELEMENT_NODE) {
+        p = p.parentNode;
+      }
+      return p;
+    },
+    get textContent() {
+      var s = "";
+      for (var child = this.firstChild; child; child = child.nextSibling) {
+        if (child.nodeType != Node.COMMENT_NODE) {
+          s += child.textContent;
+        }
+      }
+      return s;
+    },
+    set textContent(textContent) {
+      if (textContent == null) textContent = "";
+      var removedNodes = snapshotNodeList(this.childNodes);
+      if (this.invalidateShadowRenderer()) {
+        removeAllChildNodes(this);
+        if (textContent !== "") {
+          var textNode = unsafeUnwrap(this).ownerDocument.createTextNode(textContent);
+          this.appendChild(textNode);
+        }
+      } else {
+        clearChildNodes(this);
+        unsafeUnwrap(this).textContent = textContent;
+      }
+      var addedNodes = snapshotNodeList(this.childNodes);
+      enqueueMutation(this, "childList", {
+        addedNodes: addedNodes,
+        removedNodes: removedNodes
+      });
+      nodesWereRemoved(removedNodes);
+      nodesWereAdded(addedNodes, this);
+    },
+    get childNodes() {
+      var wrapperList = new NodeList();
+      var i = 0;
+      for (var child = this.firstChild; child; child = child.nextSibling) {
+        wrapperList[i++] = child;
+      }
+      wrapperList.length = i;
+      return wrapperList;
+    },
+    cloneNode: function(deep) {
+      return cloneNode(this, deep);
+    },
+    contains: function(child) {
+      return contains(this, wrapIfNeeded(child));
+    },
+    compareDocumentPosition: function(otherNode) {
+      return originalCompareDocumentPosition.call(unsafeUnwrap(this), unwrapIfNeeded(otherNode));
+    },
+    normalize: function() {
+      var nodes = snapshotNodeList(this.childNodes);
+      var remNodes = [];
+      var s = "";
+      var modNode;
+      for (var i = 0, n; i < nodes.length; i++) {
+        n = nodes[i];
+        if (n.nodeType === Node.TEXT_NODE) {
+          if (!modNode && !n.data.length) this.removeChild(n); else if (!modNode) modNode = n; else {
+            s += n.data;
+            remNodes.push(n);
+          }
+        } else {
+          if (modNode && remNodes.length) {
+            modNode.data += s;
+            cleanupNodes(remNodes);
+          }
+          remNodes = [];
+          s = "";
+          modNode = null;
+          if (n.childNodes.length) n.normalize();
+        }
+      }
+      if (modNode && remNodes.length) {
+        modNode.data += s;
+        cleanupNodes(remNodes);
+      }
+    }
+  });
+  defineWrapGetter(Node, "ownerDocument");
+  registerWrapper(OriginalNode, Node, document.createDocumentFragment());
+  delete Node.prototype.querySelector;
+  delete Node.prototype.querySelectorAll;
+  Node.prototype = mixin(Object.create(EventTarget.prototype), Node.prototype);
+  scope.cloneNode = cloneNode;
+  scope.nodeWasAdded = nodeWasAdded;
+  scope.nodeWasRemoved = nodeWasRemoved;
+  scope.nodesWereAdded = nodesWereAdded;
+  scope.nodesWereRemoved = nodesWereRemoved;
+  scope.originalInsertBefore = originalInsertBefore;
+  scope.originalRemoveChild = originalRemoveChild;
+  scope.snapshotNodeList = snapshotNodeList;
+  scope.wrappers.Node = Node;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var HTMLCollection = scope.wrappers.HTMLCollection;
+  var NodeList = scope.wrappers.NodeList;
+  var getTreeScope = scope.getTreeScope;
+  var unsafeUnwrap = scope.unsafeUnwrap;
+  var wrap = scope.wrap;
+  var originalDocumentQuerySelector = document.querySelector;
+  var originalElementQuerySelector = document.documentElement.querySelector;
+  var originalDocumentQuerySelectorAll = document.querySelectorAll;
+  var originalElementQuerySelectorAll = document.documentElement.querySelectorAll;
+  var originalDocumentGetElementsByTagName = document.getElementsByTagName;
+  var originalElementGetElementsByTagName = document.documentElement.getElementsByTagName;
+  var originalDocumentGetElementsByTagNameNS = document.getElementsByTagNameNS;
+  var originalElementGetElementsByTagNameNS = document.documentElement.getElementsByTagNameNS;
+  var OriginalElement = window.Element;
+  var OriginalDocument = window.HTMLDocument || window.Document;
+  function filterNodeList(list, index, result, deep) {
+    var wrappedItem = null;
+    var root = null;
+    for (var i = 0, length = list.length; i < length; i++) {
+      wrappedItem = wrap(list[i]);
+      if (!deep && (root = getTreeScope(wrappedItem).root)) {
+        if (root instanceof scope.wrappers.ShadowRoot) {
+          continue;
+        }
+      }
+      result[index++] = wrappedItem;
+    }
+    return index;
+  }
+  function shimSelector(selector) {
+    return String(selector).replace(/\/deep\/|::shadow/g, " ");
+  }
+  function shimMatchesSelector(selector) {
+    return String(selector).replace(/:host\(([^\s]+)\)/g, "$1").replace(/([^\s]):host/g, "$1").replace(":host", "*").replace(/\^|\/shadow\/|\/shadow-deep\/|::shadow|\/deep\/|::content/g, " ");
+  }
+  function findOne(node, selector) {
+    var m, el = node.firstElementChild;
+    while (el) {
+      if (el.matches(selector)) return el;
+      m = findOne(el, selector);
+      if (m) return m;
+      el = el.nextElementSibling;
+    }
+    return null;
+  }
+  function matchesSelector(el, selector) {
+    return el.matches(selector);
+  }
+  var XHTML_NS = "http://www.w3.org/1999/xhtml";
+  function matchesTagName(el, localName, localNameLowerCase) {
+    var ln = el.localName;
+    return ln === localName || ln === localNameLowerCase && el.namespaceURI === XHTML_NS;
+  }
+  function matchesEveryThing() {
+    return true;
+  }
+  function matchesLocalNameOnly(el, ns, localName) {
+    return el.localName === localName;
+  }
+  function matchesNameSpace(el, ns) {
+    return el.namespaceURI === ns;
+  }
+  function matchesLocalNameNS(el, ns, localName) {
+    return el.namespaceURI === ns && el.localName === localName;
+  }
+  function findElements(node, index, result, p, arg0, arg1) {
+    var el = node.firstElementChild;
+    while (el) {
+      if (p(el, arg0, arg1)) result[index++] = el;
+      index = findElements(el, index, result, p, arg0, arg1);
+      el = el.nextElementSibling;
+    }
+    return index;
+  }
+  function querySelectorAllFiltered(p, index, result, selector, deep) {
+    var target = unsafeUnwrap(this);
+    var list;
+    var root = getTreeScope(this).root;
+    if (root instanceof scope.wrappers.ShadowRoot) {
+      return findElements(this, index, result, p, selector, null);
+    } else if (target instanceof OriginalElement) {
+      list = originalElementQuerySelectorAll.call(target, selector);
+    } else if (target instanceof OriginalDocument) {
+      list = originalDocumentQuerySelectorAll.call(target, selector);
+    } else {
+      return findElements(this, index, result, p, selector, null);
+    }
+    return filterNodeList(list, index, result, deep);
+  }
+  var SelectorsInterface = {
+    querySelector: function(selector) {
+      var shimmed = shimSelector(selector);
+      var deep = shimmed !== selector;
+      selector = shimmed;
+      var target = unsafeUnwrap(this);
+      var wrappedItem;
+      var root = getTreeScope(this).root;
+      if (root instanceof scope.wrappers.ShadowRoot) {
+        return findOne(this, selector);
+      } else if (target instanceof OriginalElement) {
+        wrappedItem = wrap(originalElementQuerySelector.call(target, selector));
+      } else if (target instanceof OriginalDocument) {
+        wrappedItem = wrap(originalDocumentQuerySelector.call(target, selector));
+      } else {
+        return findOne(this, selector);
+      }
+      if (!wrappedItem) {
+        return wrappedItem;
+      } else if (!deep && (root = getTreeScope(wrappedItem).root)) {
+        if (root instanceof scope.wrappers.ShadowRoot) {
+          return findOne(this, selector);
+        }
+      }
+      return wrappedItem;
+    },
+    querySelectorAll: function(selector) {
+      var shimmed = shimSelector(selector);
+      var deep = shimmed !== selector;
+      selector = shimmed;
+      var result = new NodeList();
+      result.length = querySelectorAllFiltered.call(this, matchesSelector, 0, result, selector, deep);
+      return result;
+    }
+  };
+  var MatchesInterface = {
+    matches: function(selector) {
+      selector = shimMatchesSelector(selector);
+      return scope.originalMatches.call(unsafeUnwrap(this), selector);
+    }
+  };
+  function getElementsByTagNameFiltered(p, index, result, localName, lowercase) {
+    var target = unsafeUnwrap(this);
+    var list;
+    var root = getTreeScope(this).root;
+    if (root instanceof scope.wrappers.ShadowRoot) {
+      return findElements(this, index, result, p, localName, lowercase);
+    } else if (target instanceof OriginalElement) {
+      list = originalElementGetElementsByTagName.call(target, localName, lowercase);
+    } else if (target instanceof OriginalDocument) {
+      list = originalDocumentGetElementsByTagName.call(target, localName, lowercase);
+    } else {
+      return findElements(this, index, result, p, localName, lowercase);
+    }
+    return filterNodeList(list, index, result, false);
+  }
+  function getElementsByTagNameNSFiltered(p, index, result, ns, localName) {
+    var target = unsafeUnwrap(this);
+    var list;
+    var root = getTreeScope(this).root;
+    if (root instanceof scope.wrappers.ShadowRoot) {
+      return findElements(this, index, result, p, ns, localName);
+    } else if (target instanceof OriginalElement) {
+      list = originalElementGetElementsByTagNameNS.call(target, ns, localName);
+    } else if (target instanceof OriginalDocument) {
+      list = originalDocumentGetElementsByTagNameNS.call(target, ns, localName);
+    } else {
+      return findElements(this, index, result, p, ns, localName);
+    }
+    return filterNodeList(list, index, result, false);
+  }
+  var GetElementsByInterface = {
+    getElementsByTagName: function(localName) {
+      var result = new HTMLCollection();
+      var match = localName === "*" ? matchesEveryThing : matchesTagName;
+      result.length = getElementsByTagNameFiltered.call(this, match, 0, result, localName, localName.toLowerCase());
+      return result;
+    },
+    getElementsByClassName: function(className) {
+      return this.querySelectorAll("." + className);
+    },
+    getElementsByTagNameNS: function(ns, localName) {
+      var result = new HTMLCollection();
+      var match = null;
+      if (ns === "*") {
+        match = localName === "*" ? matchesEveryThing : matchesLocalNameOnly;
+      } else {
+        match = localName === "*" ? matchesNameSpace : matchesLocalNameNS;
+      }
+      result.length = getElementsByTagNameNSFiltered.call(this, match, 0, result, ns || null, localName);
+      return result;
+    }
+  };
+  scope.GetElementsByInterface = GetElementsByInterface;
+  scope.SelectorsInterface = SelectorsInterface;
+  scope.MatchesInterface = MatchesInterface;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var NodeList = scope.wrappers.NodeList;
+  function forwardElement(node) {
+    while (node && node.nodeType !== Node.ELEMENT_NODE) {
+      node = node.nextSibling;
+    }
+    return node;
+  }
+  function backwardsElement(node) {
+    while (node && node.nodeType !== Node.ELEMENT_NODE) {
+      node = node.previousSibling;
+    }
+    return node;
+  }
+  var ParentNodeInterface = {
+    get firstElementChild() {
+      return forwardElement(this.firstChild);
+    },
+    get lastElementChild() {
+      return backwardsElement(this.lastChild);
+    },
+    get childElementCount() {
+      var count = 0;
+      for (var child = this.firstElementChild; child; child = child.nextElementSibling) {
+        count++;
+      }
+      return count;
+    },
+    get children() {
+      var wrapperList = new NodeList();
+      var i = 0;
+      for (var child = this.firstElementChild; child; child = child.nextElementSibling) {
+        wrapperList[i++] = child;
+      }
+      wrapperList.length = i;
+      return wrapperList;
+    },
+    remove: function() {
+      var p = this.parentNode;
+      if (p) p.removeChild(this);
+    }
+  };
+  var ChildNodeInterface = {
+    get nextElementSibling() {
+      return forwardElement(this.nextSibling);
+    },
+    get previousElementSibling() {
+      return backwardsElement(this.previousSibling);
+    }
+  };
+  scope.ChildNodeInterface = ChildNodeInterface;
+  scope.ParentNodeInterface = ParentNodeInterface;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var ChildNodeInterface = scope.ChildNodeInterface;
+  var Node = scope.wrappers.Node;
+  var enqueueMutation = scope.enqueueMutation;
+  var mixin = scope.mixin;
+  var registerWrapper = scope.registerWrapper;
+  var unsafeUnwrap = scope.unsafeUnwrap;
+  var OriginalCharacterData = window.CharacterData;
+  function CharacterData(node) {
+    Node.call(this, node);
+  }
+  CharacterData.prototype = Object.create(Node.prototype);
+  mixin(CharacterData.prototype, {
+    get textContent() {
+      return this.data;
+    },
+    set textContent(value) {
+      this.data = value;
+    },
+    get data() {
+      return unsafeUnwrap(this).data;
+    },
+    set data(value) {
+      var oldValue = unsafeUnwrap(this).data;
+      enqueueMutation(this, "characterData", {
+        oldValue: oldValue
+      });
+      unsafeUnwrap(this).data = value;
+    }
+  });
+  mixin(CharacterData.prototype, ChildNodeInterface);
+  registerWrapper(OriginalCharacterData, CharacterData, document.createTextNode(""));
+  scope.wrappers.CharacterData = CharacterData;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var CharacterData = scope.wrappers.CharacterData;
+  var enqueueMutation = scope.enqueueMutation;
+  var mixin = scope.mixin;
+  var registerWrapper = scope.registerWrapper;
+  function toUInt32(x) {
+    return x >>> 0;
+  }
+  var OriginalText = window.Text;
+  function Text(node) {
+    CharacterData.call(this, node);
+  }
+  Text.prototype = Object.create(CharacterData.prototype);
+  mixin(Text.prototype, {
+    splitText: function(offset) {
+      offset = toUInt32(offset);
+      var s = this.data;
+      if (offset > s.length) throw new Error("IndexSizeError");
+      var head = s.slice(0, offset);
+      var tail = s.slice(offset);
+      this.data = head;
+      var newTextNode = this.ownerDocument.createTextNode(tail);
+      if (this.parentNode) this.parentNode.insertBefore(newTextNode, this.nextSibling);
+      return newTextNode;
+    }
+  });
+  registerWrapper(OriginalText, Text, document.createTextNode(""));
+  scope.wrappers.Text = Text;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  if (!window.DOMTokenList) {
+    console.warn("Missing DOMTokenList prototype, please include a " + "compatible classList polyfill such as http://goo.gl/uTcepH.");
+    return;
+  }
+  var unsafeUnwrap = scope.unsafeUnwrap;
+  var enqueueMutation = scope.enqueueMutation;
+  function getClass(el) {
+    return unsafeUnwrap(el).getAttribute("class");
+  }
+  function enqueueClassAttributeChange(el, oldValue) {
+    enqueueMutation(el, "attributes", {
+      name: "class",
+      namespace: null,
+      oldValue: oldValue
+    });
+  }
+  function invalidateClass(el) {
+    scope.invalidateRendererBasedOnAttribute(el, "class");
+  }
+  function changeClass(tokenList, method, args) {
+    var ownerElement = tokenList.ownerElement_;
+    if (ownerElement == null) {
+      return method.apply(tokenList, args);
+    }
+    var oldValue = getClass(ownerElement);
+    var retv = method.apply(tokenList, args);
+    if (getClass(ownerElement) !== oldValue) {
+      enqueueClassAttributeChange(ownerElement, oldValue);
+      invalidateClass(ownerElement);
+    }
+    return retv;
+  }
+  var oldAdd = DOMTokenList.prototype.add;
+  DOMTokenList.prototype.add = function() {
+    changeClass(this, oldAdd, arguments);
+  };
+  var oldRemove = DOMTokenList.prototype.remove;
+  DOMTokenList.prototype.remove = function() {
+    changeClass(this, oldRemove, arguments);
+  };
+  var oldToggle = DOMTokenList.prototype.toggle;
+  DOMTokenList.prototype.toggle = function() {
+    return changeClass(this, oldToggle, arguments);
+  };
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var ChildNodeInterface = scope.ChildNodeInterface;
+  var GetElementsByInterface = scope.GetElementsByInterface;
+  var Node = scope.wrappers.Node;
+  var ParentNodeInterface = scope.ParentNodeInterface;
+  var SelectorsInterface = scope.SelectorsInterface;
+  var MatchesInterface = scope.MatchesInterface;
+  var addWrapNodeListMethod = scope.addWrapNodeListMethod;
+  var enqueueMutation = scope.enqueueMutation;
+  var mixin = scope.mixin;
+  var oneOf = scope.oneOf;
+  var registerWrapper = scope.registerWrapper;
+  var unsafeUnwrap = scope.unsafeUnwrap;
+  var wrappers = scope.wrappers;
+  var OriginalElement = window.Element;
+  var matchesNames = [ "matches", "mozMatchesSelector", "msMatchesSelector", "webkitMatchesSelector" ].filter(function(name) {
+    return OriginalElement.prototype[name];
+  });
+  var matchesName = matchesNames[0];
+  var originalMatches = OriginalElement.prototype[matchesName];
+  function invalidateRendererBasedOnAttribute(element, name) {
+    var p = element.parentNode;
+    if (!p || !p.shadowRoot) return;
+    var renderer = scope.getRendererForHost(p);
+    if (renderer.dependsOnAttribute(name)) renderer.invalidate();
+  }
+  function enqueAttributeChange(element, name, oldValue) {
+    enqueueMutation(element, "attributes", {
+      name: name,
+      namespace: null,
+      oldValue: oldValue
+    });
+  }
+  var classListTable = new WeakMap();
+  function Element(node) {
+    Node.call(this, node);
+  }
+  Element.prototype = Object.create(Node.prototype);
+  mixin(Element.prototype, {
+    createShadowRoot: function() {
+      var newShadowRoot = new wrappers.ShadowRoot(this);
+      unsafeUnwrap(this).polymerShadowRoot_ = newShadowRoot;
+      var renderer = scope.getRendererForHost(this);
+      renderer.invalidate();
+      return newShadowRoot;
+    },
+    get shadowRoot() {
+      return unsafeUnwrap(this).polymerShadowRoot_ || null;
+    },
+    setAttribute: function(name, value) {
+      var oldValue = unsafeUnwrap(this).getAttribute(name);
+      unsafeUnwrap(this).setAttribute(name, value);
+      enqueAttributeChange(this, name, oldValue);
+      invalidateRendererBasedOnAttribute(this, name);
+    },
+    removeAttribute: function(name) {
+      var oldValue = unsafeUnwrap(this).getAttribute(name);
+      unsafeUnwrap(this).removeAttribute(name);
+      enqueAttributeChange(this, name, oldValue);
+      invalidateRendererBasedOnAttribute(this, name);
+    },
+    get classList() {
+      var list = classListTable.get(this);
+      if (!list) {
+        list = unsafeUnwrap(this).classList;
+        if (!list) return;
+        list.ownerElement_ = this;
+        classListTable.set(this, list);
+      }
+      return list;
+    },
+    get className() {
+      return unsafeUnwrap(this).className;
+    },
+    set className(v) {
+      this.setAttribute("class", v);
+    },
+    get id() {
+      return unsafeUnwrap(this).id;
+    },
+    set id(v) {
+      this.setAttribute("id", v);
+    }
+  });
+  matchesNames.forEach(function(name) {
+    if (name !== "matches") {
+      Element.prototype[name] = function(selector) {
+        return this.matches(selector);
+      };
+    }
+  });
+  if (OriginalElement.prototype.webkitCreateShadowRoot) {
+    Element.prototype.webkitCreateShadowRoot = Element.prototype.createShadowRoot;
+  }
+  mixin(Element.prototype, ChildNodeInterface);
+  mixin(Element.prototype, GetElementsByInterface);
+  mixin(Element.prototype, ParentNodeInterface);
+  mixin(Element.prototype, SelectorsInterface);
+  mixin(Element.prototype, MatchesInterface);
+  registerWrapper(OriginalElement, Element, document.createElementNS(null, "x"));
+  scope.invalidateRendererBasedOnAttribute = invalidateRendererBasedOnAttribute;
+  scope.matchesNames = matchesNames;
+  scope.originalMatches = originalMatches;
+  scope.wrappers.Element = Element;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var Element = scope.wrappers.Element;
+  var defineGetter = scope.defineGetter;
+  var enqueueMutation = scope.enqueueMutation;
+  var mixin = scope.mixin;
+  var nodesWereAdded = scope.nodesWereAdded;
+  var nodesWereRemoved = scope.nodesWereRemoved;
+  var registerWrapper = scope.registerWrapper;
+  var snapshotNodeList = scope.snapshotNodeList;
+  var unsafeUnwrap = scope.unsafeUnwrap;
+  var unwrap = scope.unwrap;
+  var wrap = scope.wrap;
+  var wrappers = scope.wrappers;
+  var escapeAttrRegExp = /[&\u00A0"]/g;
+  var escapeDataRegExp = /[&\u00A0<>]/g;
+  function escapeReplace(c) {
+    switch (c) {
+     case "&":
+      return "&";
+
+     case "<":
+      return "<";
+
+     case ">":
+      return ">";
+
+     case '"':
+      return """;
+
+     case " ":
+      return " ";
+    }
+  }
+  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) {
+    switch (node.nodeType) {
+     case Node.ELEMENT_NODE:
+      var tagName = node.tagName.toLowerCase();
+      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) + "";
+
+     case Node.TEXT_NODE:
+      var data = node.data;
+      if (parentNode && plaintextParents[parentNode.localName]) return data;
+      return escapeData(data);
+
+     case Node.COMMENT_NODE:
+      return "";
+
+     default:
+      console.error(node);
+      throw new Error("not implemented");
+    }
+  }
+  function getInnerHTML(node) {
+    if (node instanceof wrappers.HTMLTemplateElement) node = node.content;
+    var s = "";
+    for (var child = node.firstChild; child; child = child.nextSibling) {
+      s += getOuterHTML(child, node);
+    }
+    return s;
+  }
+  function setInnerHTML(node, value, opt_tagName) {
+    var tagName = opt_tagName || "div";
+    node.textContent = "";
+    var tempElement = unwrap(node.ownerDocument.createElement(tagName));
+    tempElement.innerHTML = value;
+    var firstChild;
+    while (firstChild = tempElement.firstChild) {
+      node.appendChild(wrap(firstChild));
+    }
+  }
+  var oldIe = /MSIE/.test(navigator.userAgent);
+  var OriginalHTMLElement = window.HTMLElement;
+  var OriginalHTMLTemplateElement = window.HTMLTemplateElement;
+  function HTMLElement(node) {
+    Element.call(this, node);
+  }
+  HTMLElement.prototype = Object.create(Element.prototype);
+  mixin(HTMLElement.prototype, {
+    get innerHTML() {
+      return getInnerHTML(this);
+    },
+    set innerHTML(value) {
+      if (oldIe && plaintextParents[this.localName]) {
+        this.textContent = value;
+        return;
+      }
+      var removedNodes = snapshotNodeList(this.childNodes);
+      if (this.invalidateShadowRenderer()) {
+        if (this instanceof wrappers.HTMLTemplateElement) setInnerHTML(this.content, value); else setInnerHTML(this, value, this.tagName);
+      } else if (!OriginalHTMLTemplateElement && this instanceof wrappers.HTMLTemplateElement) {
+        setInnerHTML(this.content, value);
+      } else {
+        unsafeUnwrap(this).innerHTML = value;
+      }
+      var addedNodes = snapshotNodeList(this.childNodes);
+      enqueueMutation(this, "childList", {
+        addedNodes: addedNodes,
+        removedNodes: removedNodes
+      });
+      nodesWereRemoved(removedNodes);
+      nodesWereAdded(addedNodes, this);
+    },
+    get outerHTML() {
+      return getOuterHTML(this, this.parentNode);
+    },
+    set outerHTML(value) {
+      var p = this.parentNode;
+      if (p) {
+        p.invalidateShadowRenderer();
+        var df = frag(p, value);
+        p.replaceChild(df, this);
+      }
+    },
+    insertAdjacentHTML: function(position, text) {
+      var contextElement, refNode;
+      switch (String(position).toLowerCase()) {
+       case "beforebegin":
+        contextElement = this.parentNode;
+        refNode = this;
+        break;
+
+       case "afterend":
+        contextElement = this.parentNode;
+        refNode = this.nextSibling;
+        break;
+
+       case "afterbegin":
+        contextElement = this;
+        refNode = this.firstChild;
+        break;
+
+       case "beforeend":
+        contextElement = this;
+        refNode = null;
+        break;
+
+       default:
+        return;
+      }
+      var df = frag(contextElement, text);
+      contextElement.insertBefore(df, refNode);
+    },
+    get hidden() {
+      return this.hasAttribute("hidden");
+    },
+    set hidden(v) {
+      if (v) {
+        this.setAttribute("hidden", "");
+      } else {
+        this.removeAttribute("hidden");
+      }
+    }
+  });
+  function frag(contextElement, html) {
+    var p = unwrap(contextElement.cloneNode(false));
+    p.innerHTML = html;
+    var df = unwrap(document.createDocumentFragment());
+    var c;
+    while (c = p.firstChild) {
+      df.appendChild(c);
+    }
+    return wrap(df);
+  }
+  function getter(name) {
+    return function() {
+      scope.renderAllPending();
+      return unsafeUnwrap(this)[name];
+    };
+  }
+  function getterRequiresRendering(name) {
+    defineGetter(HTMLElement, name, getter(name));
+  }
+  [ "clientHeight", "clientLeft", "clientTop", "clientWidth", "offsetHeight", "offsetLeft", "offsetTop", "offsetWidth", "scrollHeight", "scrollWidth" ].forEach(getterRequiresRendering);
+  function getterAndSetterRequiresRendering(name) {
+    Object.defineProperty(HTMLElement.prototype, name, {
+      get: getter(name),
+      set: function(v) {
+        scope.renderAllPending();
+        unsafeUnwrap(this)[name] = v;
+      },
+      configurable: true,
+      enumerable: true
+    });
+  }
+  [ "scrollLeft", "scrollTop" ].forEach(getterAndSetterRequiresRendering);
+  function methodRequiresRendering(name) {
+    Object.defineProperty(HTMLElement.prototype, name, {
+      value: function() {
+        scope.renderAllPending();
+        return unsafeUnwrap(this)[name].apply(unsafeUnwrap(this), arguments);
+      },
+      configurable: true,
+      enumerable: true
+    });
+  }
+  [ "getBoundingClientRect", "getClientRects", "scrollIntoView" ].forEach(methodRequiresRendering);
+  registerWrapper(OriginalHTMLElement, HTMLElement, document.createElement("b"));
+  scope.wrappers.HTMLElement = HTMLElement;
+  scope.getInnerHTML = getInnerHTML;
+  scope.setInnerHTML = setInnerHTML;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var HTMLElement = scope.wrappers.HTMLElement;
+  var mixin = scope.mixin;
+  var registerWrapper = scope.registerWrapper;
+  var unsafeUnwrap = scope.unsafeUnwrap;
+  var wrap = scope.wrap;
+  var OriginalHTMLCanvasElement = window.HTMLCanvasElement;
+  function HTMLCanvasElement(node) {
+    HTMLElement.call(this, node);
+  }
+  HTMLCanvasElement.prototype = Object.create(HTMLElement.prototype);
+  mixin(HTMLCanvasElement.prototype, {
+    getContext: function() {
+      var context = unsafeUnwrap(this).getContext.apply(unsafeUnwrap(this), arguments);
+      return context && wrap(context);
+    }
+  });
+  registerWrapper(OriginalHTMLCanvasElement, HTMLCanvasElement, document.createElement("canvas"));
+  scope.wrappers.HTMLCanvasElement = HTMLCanvasElement;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var HTMLElement = scope.wrappers.HTMLElement;
+  var mixin = scope.mixin;
+  var registerWrapper = scope.registerWrapper;
+  var OriginalHTMLContentElement = window.HTMLContentElement;
+  function HTMLContentElement(node) {
+    HTMLElement.call(this, node);
+  }
+  HTMLContentElement.prototype = Object.create(HTMLElement.prototype);
+  mixin(HTMLContentElement.prototype, {
+    constructor: HTMLContentElement,
+    get select() {
+      return this.getAttribute("select");
+    },
+    set select(value) {
+      this.setAttribute("select", value);
+    },
+    setAttribute: function(n, v) {
+      HTMLElement.prototype.setAttribute.call(this, n, v);
+      if (String(n).toLowerCase() === "select") this.invalidateShadowRenderer(true);
+    }
+  });
+  if (OriginalHTMLContentElement) registerWrapper(OriginalHTMLContentElement, HTMLContentElement);
+  scope.wrappers.HTMLContentElement = HTMLContentElement;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var HTMLElement = scope.wrappers.HTMLElement;
+  var mixin = scope.mixin;
+  var registerWrapper = scope.registerWrapper;
+  var wrapHTMLCollection = scope.wrapHTMLCollection;
+  var unwrap = scope.unwrap;
+  var OriginalHTMLFormElement = window.HTMLFormElement;
+  function HTMLFormElement(node) {
+    HTMLElement.call(this, node);
+  }
+  HTMLFormElement.prototype = Object.create(HTMLElement.prototype);
+  mixin(HTMLFormElement.prototype, {
+    get elements() {
+      return wrapHTMLCollection(unwrap(this).elements);
+    }
+  });
+  registerWrapper(OriginalHTMLFormElement, HTMLFormElement, document.createElement("form"));
+  scope.wrappers.HTMLFormElement = HTMLFormElement;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var HTMLElement = scope.wrappers.HTMLElement;
+  var registerWrapper = scope.registerWrapper;
+  var unwrap = scope.unwrap;
+  var rewrap = scope.rewrap;
+  var OriginalHTMLImageElement = window.HTMLImageElement;
+  function HTMLImageElement(node) {
+    HTMLElement.call(this, node);
+  }
+  HTMLImageElement.prototype = Object.create(HTMLElement.prototype);
+  registerWrapper(OriginalHTMLImageElement, HTMLImageElement, document.createElement("img"));
+  function Image(width, height) {
+    if (!(this instanceof Image)) {
+      throw new TypeError("DOM object constructor cannot be called as a function.");
+    }
+    var node = unwrap(document.createElement("img"));
+    HTMLElement.call(this, node);
+    rewrap(node, this);
+    if (width !== undefined) node.width = width;
+    if (height !== undefined) node.height = height;
+  }
+  Image.prototype = HTMLImageElement.prototype;
+  scope.wrappers.HTMLImageElement = HTMLImageElement;
+  scope.wrappers.Image = Image;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var HTMLElement = scope.wrappers.HTMLElement;
+  var mixin = scope.mixin;
+  var NodeList = scope.wrappers.NodeList;
+  var registerWrapper = scope.registerWrapper;
+  var OriginalHTMLShadowElement = window.HTMLShadowElement;
+  function HTMLShadowElement(node) {
+    HTMLElement.call(this, node);
+  }
+  HTMLShadowElement.prototype = Object.create(HTMLElement.prototype);
+  HTMLShadowElement.prototype.constructor = HTMLShadowElement;
+  if (OriginalHTMLShadowElement) registerWrapper(OriginalHTMLShadowElement, HTMLShadowElement);
+  scope.wrappers.HTMLShadowElement = HTMLShadowElement;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var HTMLElement = scope.wrappers.HTMLElement;
+  var mixin = scope.mixin;
+  var registerWrapper = scope.registerWrapper;
+  var unsafeUnwrap = scope.unsafeUnwrap;
+  var unwrap = scope.unwrap;
+  var wrap = scope.wrap;
+  var contentTable = new WeakMap();
+  var templateContentsOwnerTable = new WeakMap();
+  function getTemplateContentsOwner(doc) {
+    if (!doc.defaultView) return doc;
+    var d = templateContentsOwnerTable.get(doc);
+    if (!d) {
+      d = doc.implementation.createHTMLDocument("");
+      while (d.lastChild) {
+        d.removeChild(d.lastChild);
+      }
+      templateContentsOwnerTable.set(doc, d);
+    }
+    return d;
+  }
+  function extractContent(templateElement) {
+    var doc = getTemplateContentsOwner(templateElement.ownerDocument);
+    var df = unwrap(doc.createDocumentFragment());
+    var child;
+    while (child = templateElement.firstChild) {
+      df.appendChild(child);
+    }
+    return df;
+  }
+  var OriginalHTMLTemplateElement = window.HTMLTemplateElement;
+  function HTMLTemplateElement(node) {
+    HTMLElement.call(this, node);
+    if (!OriginalHTMLTemplateElement) {
+      var content = extractContent(node);
+      contentTable.set(this, wrap(content));
+    }
+  }
+  HTMLTemplateElement.prototype = Object.create(HTMLElement.prototype);
+  mixin(HTMLTemplateElement.prototype, {
+    constructor: HTMLTemplateElement,
+    get content() {
+      if (OriginalHTMLTemplateElement) return wrap(unsafeUnwrap(this).content);
+      return contentTable.get(this);
+    }
+  });
+  if (OriginalHTMLTemplateElement) registerWrapper(OriginalHTMLTemplateElement, HTMLTemplateElement);
+  scope.wrappers.HTMLTemplateElement = HTMLTemplateElement;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var HTMLElement = scope.wrappers.HTMLElement;
+  var registerWrapper = scope.registerWrapper;
+  var OriginalHTMLMediaElement = window.HTMLMediaElement;
+  if (!OriginalHTMLMediaElement) return;
+  function HTMLMediaElement(node) {
+    HTMLElement.call(this, node);
+  }
+  HTMLMediaElement.prototype = Object.create(HTMLElement.prototype);
+  registerWrapper(OriginalHTMLMediaElement, HTMLMediaElement, document.createElement("audio"));
+  scope.wrappers.HTMLMediaElement = HTMLMediaElement;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var HTMLMediaElement = scope.wrappers.HTMLMediaElement;
+  var registerWrapper = scope.registerWrapper;
+  var unwrap = scope.unwrap;
+  var rewrap = scope.rewrap;
+  var OriginalHTMLAudioElement = window.HTMLAudioElement;
+  if (!OriginalHTMLAudioElement) return;
+  function HTMLAudioElement(node) {
+    HTMLMediaElement.call(this, node);
+  }
+  HTMLAudioElement.prototype = Object.create(HTMLMediaElement.prototype);
+  registerWrapper(OriginalHTMLAudioElement, HTMLAudioElement, document.createElement("audio"));
+  function Audio(src) {
+    if (!(this instanceof Audio)) {
+      throw new TypeError("DOM object constructor cannot be called as a function.");
+    }
+    var node = unwrap(document.createElement("audio"));
+    HTMLMediaElement.call(this, node);
+    rewrap(node, this);
+    node.setAttribute("preload", "auto");
+    if (src !== undefined) node.setAttribute("src", src);
+  }
+  Audio.prototype = HTMLAudioElement.prototype;
+  scope.wrappers.HTMLAudioElement = HTMLAudioElement;
+  scope.wrappers.Audio = Audio;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var HTMLElement = scope.wrappers.HTMLElement;
+  var mixin = scope.mixin;
+  var registerWrapper = scope.registerWrapper;
+  var rewrap = scope.rewrap;
+  var unwrap = scope.unwrap;
+  var wrap = scope.wrap;
+  var OriginalHTMLOptionElement = window.HTMLOptionElement;
+  function trimText(s) {
+    return s.replace(/\s+/g, " ").trim();
+  }
+  function HTMLOptionElement(node) {
+    HTMLElement.call(this, node);
+  }
+  HTMLOptionElement.prototype = Object.create(HTMLElement.prototype);
+  mixin(HTMLOptionElement.prototype, {
+    get text() {
+      return trimText(this.textContent);
+    },
+    set text(value) {
+      this.textContent = trimText(String(value));
+    },
+    get form() {
+      return wrap(unwrap(this).form);
+    }
+  });
+  registerWrapper(OriginalHTMLOptionElement, HTMLOptionElement, document.createElement("option"));
+  function Option(text, value, defaultSelected, selected) {
+    if (!(this instanceof Option)) {
+      throw new TypeError("DOM object constructor cannot be called as a function.");
+    }
+    var node = unwrap(document.createElement("option"));
+    HTMLElement.call(this, node);
+    rewrap(node, this);
+    if (text !== undefined) node.text = text;
+    if (value !== undefined) node.setAttribute("value", value);
+    if (defaultSelected === true) node.setAttribute("selected", "");
+    node.selected = selected === true;
+  }
+  Option.prototype = HTMLOptionElement.prototype;
+  scope.wrappers.HTMLOptionElement = HTMLOptionElement;
+  scope.wrappers.Option = Option;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var HTMLElement = scope.wrappers.HTMLElement;
+  var mixin = scope.mixin;
+  var registerWrapper = scope.registerWrapper;
+  var unwrap = scope.unwrap;
+  var wrap = scope.wrap;
+  var OriginalHTMLSelectElement = window.HTMLSelectElement;
+  function HTMLSelectElement(node) {
+    HTMLElement.call(this, node);
+  }
+  HTMLSelectElement.prototype = Object.create(HTMLElement.prototype);
+  mixin(HTMLSelectElement.prototype, {
+    add: function(element, before) {
+      if (typeof before === "object") before = unwrap(before);
+      unwrap(this).add(unwrap(element), before);
+    },
+    remove: function(indexOrNode) {
+      if (indexOrNode === undefined) {
+        HTMLElement.prototype.remove.call(this);
+        return;
+      }
+      if (typeof indexOrNode === "object") indexOrNode = unwrap(indexOrNode);
+      unwrap(this).remove(indexOrNode);
+    },
+    get form() {
+      return wrap(unwrap(this).form);
+    }
+  });
+  registerWrapper(OriginalHTMLSelectElement, HTMLSelectElement, document.createElement("select"));
+  scope.wrappers.HTMLSelectElement = HTMLSelectElement;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var HTMLElement = scope.wrappers.HTMLElement;
+  var mixin = scope.mixin;
+  var registerWrapper = scope.registerWrapper;
+  var unwrap = scope.unwrap;
+  var wrap = scope.wrap;
+  var wrapHTMLCollection = scope.wrapHTMLCollection;
+  var OriginalHTMLTableElement = window.HTMLTableElement;
+  function HTMLTableElement(node) {
+    HTMLElement.call(this, node);
+  }
+  HTMLTableElement.prototype = Object.create(HTMLElement.prototype);
+  mixin(HTMLTableElement.prototype, {
+    get caption() {
+      return wrap(unwrap(this).caption);
+    },
+    createCaption: function() {
+      return wrap(unwrap(this).createCaption());
+    },
+    get tHead() {
+      return wrap(unwrap(this).tHead);
+    },
+    createTHead: function() {
+      return wrap(unwrap(this).createTHead());
+    },
+    createTFoot: function() {
+      return wrap(unwrap(this).createTFoot());
+    },
+    get tFoot() {
+      return wrap(unwrap(this).tFoot);
+    },
+    get tBodies() {
+      return wrapHTMLCollection(unwrap(this).tBodies);
+    },
+    createTBody: function() {
+      return wrap(unwrap(this).createTBody());
+    },
+    get rows() {
+      return wrapHTMLCollection(unwrap(this).rows);
+    },
+    insertRow: function(index) {
+      return wrap(unwrap(this).insertRow(index));
+    }
+  });
+  registerWrapper(OriginalHTMLTableElement, HTMLTableElement, document.createElement("table"));
+  scope.wrappers.HTMLTableElement = HTMLTableElement;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var HTMLElement = scope.wrappers.HTMLElement;
+  var mixin = scope.mixin;
+  var registerWrapper = scope.registerWrapper;
+  var wrapHTMLCollection = scope.wrapHTMLCollection;
+  var unwrap = scope.unwrap;
+  var wrap = scope.wrap;
+  var OriginalHTMLTableSectionElement = window.HTMLTableSectionElement;
+  function HTMLTableSectionElement(node) {
+    HTMLElement.call(this, node);
+  }
+  HTMLTableSectionElement.prototype = Object.create(HTMLElement.prototype);
+  mixin(HTMLTableSectionElement.prototype, {
+    constructor: HTMLTableSectionElement,
+    get rows() {
+      return wrapHTMLCollection(unwrap(this).rows);
+    },
+    insertRow: function(index) {
+      return wrap(unwrap(this).insertRow(index));
+    }
+  });
+  registerWrapper(OriginalHTMLTableSectionElement, HTMLTableSectionElement, document.createElement("thead"));
+  scope.wrappers.HTMLTableSectionElement = HTMLTableSectionElement;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var HTMLElement = scope.wrappers.HTMLElement;
+  var mixin = scope.mixin;
+  var registerWrapper = scope.registerWrapper;
+  var wrapHTMLCollection = scope.wrapHTMLCollection;
+  var unwrap = scope.unwrap;
+  var wrap = scope.wrap;
+  var OriginalHTMLTableRowElement = window.HTMLTableRowElement;
+  function HTMLTableRowElement(node) {
+    HTMLElement.call(this, node);
+  }
+  HTMLTableRowElement.prototype = Object.create(HTMLElement.prototype);
+  mixin(HTMLTableRowElement.prototype, {
+    get cells() {
+      return wrapHTMLCollection(unwrap(this).cells);
+    },
+    insertCell: function(index) {
+      return wrap(unwrap(this).insertCell(index));
+    }
+  });
+  registerWrapper(OriginalHTMLTableRowElement, HTMLTableRowElement, document.createElement("tr"));
+  scope.wrappers.HTMLTableRowElement = HTMLTableRowElement;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var HTMLContentElement = scope.wrappers.HTMLContentElement;
+  var HTMLElement = scope.wrappers.HTMLElement;
+  var HTMLShadowElement = scope.wrappers.HTMLShadowElement;
+  var HTMLTemplateElement = scope.wrappers.HTMLTemplateElement;
+  var mixin = scope.mixin;
+  var registerWrapper = scope.registerWrapper;
+  var OriginalHTMLUnknownElement = window.HTMLUnknownElement;
+  function HTMLUnknownElement(node) {
+    switch (node.localName) {
+     case "content":
+      return new HTMLContentElement(node);
+
+     case "shadow":
+      return new HTMLShadowElement(node);
+
+     case "template":
+      return new HTMLTemplateElement(node);
+    }
+    HTMLElement.call(this, node);
+  }
+  HTMLUnknownElement.prototype = Object.create(HTMLElement.prototype);
+  registerWrapper(OriginalHTMLUnknownElement, HTMLUnknownElement);
+  scope.wrappers.HTMLUnknownElement = HTMLUnknownElement;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var Element = scope.wrappers.Element;
+  var HTMLElement = scope.wrappers.HTMLElement;
+  var registerObject = scope.registerObject;
+  var defineWrapGetter = scope.defineWrapGetter;
+  var SVG_NS = "http://www.w3.org/2000/svg";
+  var svgTitleElement = document.createElementNS(SVG_NS, "title");
+  var SVGTitleElement = registerObject(svgTitleElement);
+  var SVGElement = Object.getPrototypeOf(SVGTitleElement.prototype).constructor;
+  if (!("classList" in svgTitleElement)) {
+    var descr = Object.getOwnPropertyDescriptor(Element.prototype, "classList");
+    Object.defineProperty(HTMLElement.prototype, "classList", descr);
+    delete Element.prototype.classList;
+  }
+  defineWrapGetter(SVGElement, "ownerSVGElement");
+  scope.wrappers.SVGElement = SVGElement;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var mixin = scope.mixin;
+  var registerWrapper = scope.registerWrapper;
+  var unwrap = scope.unwrap;
+  var wrap = scope.wrap;
+  var OriginalSVGUseElement = window.SVGUseElement;
+  var SVG_NS = "http://www.w3.org/2000/svg";
+  var gWrapper = wrap(document.createElementNS(SVG_NS, "g"));
+  var useElement = document.createElementNS(SVG_NS, "use");
+  var SVGGElement = gWrapper.constructor;
+  var parentInterfacePrototype = Object.getPrototypeOf(SVGGElement.prototype);
+  var parentInterface = parentInterfacePrototype.constructor;
+  function SVGUseElement(impl) {
+    parentInterface.call(this, impl);
+  }
+  SVGUseElement.prototype = Object.create(parentInterfacePrototype);
+  if ("instanceRoot" in useElement) {
+    mixin(SVGUseElement.prototype, {
+      get instanceRoot() {
+        return wrap(unwrap(this).instanceRoot);
+      },
+      get animatedInstanceRoot() {
+        return wrap(unwrap(this).animatedInstanceRoot);
+      }
+    });
+  }
+  registerWrapper(OriginalSVGUseElement, SVGUseElement, useElement);
+  scope.wrappers.SVGUseElement = SVGUseElement;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var EventTarget = scope.wrappers.EventTarget;
+  var mixin = scope.mixin;
+  var registerWrapper = scope.registerWrapper;
+  var unsafeUnwrap = scope.unsafeUnwrap;
+  var wrap = scope.wrap;
+  var OriginalSVGElementInstance = window.SVGElementInstance;
+  if (!OriginalSVGElementInstance) return;
+  function SVGElementInstance(impl) {
+    EventTarget.call(this, impl);
+  }
+  SVGElementInstance.prototype = Object.create(EventTarget.prototype);
+  mixin(SVGElementInstance.prototype, {
+    get correspondingElement() {
+      return wrap(unsafeUnwrap(this).correspondingElement);
+    },
+    get correspondingUseElement() {
+      return wrap(unsafeUnwrap(this).correspondingUseElement);
+    },
+    get parentNode() {
+      return wrap(unsafeUnwrap(this).parentNode);
+    },
+    get childNodes() {
+      throw new Error("Not implemented");
+    },
+    get firstChild() {
+      return wrap(unsafeUnwrap(this).firstChild);
+    },
+    get lastChild() {
+      return wrap(unsafeUnwrap(this).lastChild);
+    },
+    get previousSibling() {
+      return wrap(unsafeUnwrap(this).previousSibling);
+    },
+    get nextSibling() {
+      return wrap(unsafeUnwrap(this).nextSibling);
+    }
+  });
+  registerWrapper(OriginalSVGElementInstance, SVGElementInstance);
+  scope.wrappers.SVGElementInstance = SVGElementInstance;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var mixin = scope.mixin;
+  var registerWrapper = scope.registerWrapper;
+  var setWrapper = scope.setWrapper;
+  var unsafeUnwrap = scope.unsafeUnwrap;
+  var unwrap = scope.unwrap;
+  var unwrapIfNeeded = scope.unwrapIfNeeded;
+  var wrap = scope.wrap;
+  var OriginalCanvasRenderingContext2D = window.CanvasRenderingContext2D;
+  function CanvasRenderingContext2D(impl) {
+    setWrapper(impl, this);
+  }
+  mixin(CanvasRenderingContext2D.prototype, {
+    get canvas() {
+      return wrap(unsafeUnwrap(this).canvas);
+    },
+    drawImage: function() {
+      arguments[0] = unwrapIfNeeded(arguments[0]);
+      unsafeUnwrap(this).drawImage.apply(unsafeUnwrap(this), arguments);
+    },
+    createPattern: function() {
+      arguments[0] = unwrap(arguments[0]);
+      return unsafeUnwrap(this).createPattern.apply(unsafeUnwrap(this), arguments);
+    }
+  });
+  registerWrapper(OriginalCanvasRenderingContext2D, CanvasRenderingContext2D, document.createElement("canvas").getContext("2d"));
+  scope.wrappers.CanvasRenderingContext2D = CanvasRenderingContext2D;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var mixin = scope.mixin;
+  var registerWrapper = scope.registerWrapper;
+  var setWrapper = scope.setWrapper;
+  var unsafeUnwrap = scope.unsafeUnwrap;
+  var unwrapIfNeeded = scope.unwrapIfNeeded;
+  var wrap = scope.wrap;
+  var OriginalWebGLRenderingContext = window.WebGLRenderingContext;
+  if (!OriginalWebGLRenderingContext) return;
+  function WebGLRenderingContext(impl) {
+    setWrapper(impl, this);
+  }
+  mixin(WebGLRenderingContext.prototype, {
+    get canvas() {
+      return wrap(unsafeUnwrap(this).canvas);
+    },
+    texImage2D: function() {
+      arguments[5] = unwrapIfNeeded(arguments[5]);
+      unsafeUnwrap(this).texImage2D.apply(unsafeUnwrap(this), arguments);
+    },
+    texSubImage2D: function() {
+      arguments[6] = unwrapIfNeeded(arguments[6]);
+      unsafeUnwrap(this).texSubImage2D.apply(unsafeUnwrap(this), arguments);
+    }
+  });
+  var instanceProperties = /WebKit/.test(navigator.userAgent) ? {
+    drawingBufferHeight: null,
+    drawingBufferWidth: null
+  } : {};
+  registerWrapper(OriginalWebGLRenderingContext, WebGLRenderingContext, instanceProperties);
+  scope.wrappers.WebGLRenderingContext = WebGLRenderingContext;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var registerWrapper = scope.registerWrapper;
+  var setWrapper = scope.setWrapper;
+  var unsafeUnwrap = scope.unsafeUnwrap;
+  var unwrap = scope.unwrap;
+  var unwrapIfNeeded = scope.unwrapIfNeeded;
+  var wrap = scope.wrap;
+  var OriginalRange = window.Range;
+  function Range(impl) {
+    setWrapper(impl, this);
+  }
+  Range.prototype = {
+    get startContainer() {
+      return wrap(unsafeUnwrap(this).startContainer);
+    },
+    get endContainer() {
+      return wrap(unsafeUnwrap(this).endContainer);
+    },
+    get commonAncestorContainer() {
+      return wrap(unsafeUnwrap(this).commonAncestorContainer);
+    },
+    setStart: function(refNode, offset) {
+      unsafeUnwrap(this).setStart(unwrapIfNeeded(refNode), offset);
+    },
+    setEnd: function(refNode, offset) {
+      unsafeUnwrap(this).setEnd(unwrapIfNeeded(refNode), offset);
+    },
+    setStartBefore: function(refNode) {
+      unsafeUnwrap(this).setStartBefore(unwrapIfNeeded(refNode));
+    },
+    setStartAfter: function(refNode) {
+      unsafeUnwrap(this).setStartAfter(unwrapIfNeeded(refNode));
+    },
+    setEndBefore: function(refNode) {
+      unsafeUnwrap(this).setEndBefore(unwrapIfNeeded(refNode));
+    },
+    setEndAfter: function(refNode) {
+      unsafeUnwrap(this).setEndAfter(unwrapIfNeeded(refNode));
+    },
+    selectNode: function(refNode) {
+      unsafeUnwrap(this).selectNode(unwrapIfNeeded(refNode));
+    },
+    selectNodeContents: function(refNode) {
+      unsafeUnwrap(this).selectNodeContents(unwrapIfNeeded(refNode));
+    },
+    compareBoundaryPoints: function(how, sourceRange) {
+      return unsafeUnwrap(this).compareBoundaryPoints(how, unwrap(sourceRange));
+    },
+    extractContents: function() {
+      return wrap(unsafeUnwrap(this).extractContents());
+    },
+    cloneContents: function() {
+      return wrap(unsafeUnwrap(this).cloneContents());
+    },
+    insertNode: function(node) {
+      unsafeUnwrap(this).insertNode(unwrapIfNeeded(node));
+    },
+    surroundContents: function(newParent) {
+      unsafeUnwrap(this).surroundContents(unwrapIfNeeded(newParent));
+    },
+    cloneRange: function() {
+      return wrap(unsafeUnwrap(this).cloneRange());
+    },
+    isPointInRange: function(node, offset) {
+      return unsafeUnwrap(this).isPointInRange(unwrapIfNeeded(node), offset);
+    },
+    comparePoint: function(node, offset) {
+      return unsafeUnwrap(this).comparePoint(unwrapIfNeeded(node), offset);
+    },
+    intersectsNode: function(node) {
+      return unsafeUnwrap(this).intersectsNode(unwrapIfNeeded(node));
+    },
+    toString: function() {
+      return unsafeUnwrap(this).toString();
+    }
+  };
+  if (OriginalRange.prototype.createContextualFragment) {
+    Range.prototype.createContextualFragment = function(html) {
+      return wrap(unsafeUnwrap(this).createContextualFragment(html));
+    };
+  }
+  registerWrapper(window.Range, Range, document.createRange());
+  scope.wrappers.Range = Range;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var GetElementsByInterface = scope.GetElementsByInterface;
+  var ParentNodeInterface = scope.ParentNodeInterface;
+  var SelectorsInterface = scope.SelectorsInterface;
+  var mixin = scope.mixin;
+  var registerObject = scope.registerObject;
+  var DocumentFragment = registerObject(document.createDocumentFragment());
+  mixin(DocumentFragment.prototype, ParentNodeInterface);
+  mixin(DocumentFragment.prototype, SelectorsInterface);
+  mixin(DocumentFragment.prototype, GetElementsByInterface);
+  var Comment = registerObject(document.createComment(""));
+  scope.wrappers.Comment = Comment;
+  scope.wrappers.DocumentFragment = DocumentFragment;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var DocumentFragment = scope.wrappers.DocumentFragment;
+  var TreeScope = scope.TreeScope;
+  var elementFromPoint = scope.elementFromPoint;
+  var getInnerHTML = scope.getInnerHTML;
+  var getTreeScope = scope.getTreeScope;
+  var mixin = scope.mixin;
+  var rewrap = scope.rewrap;
+  var setInnerHTML = scope.setInnerHTML;
+  var unsafeUnwrap = scope.unsafeUnwrap;
+  var unwrap = scope.unwrap;
+  var shadowHostTable = new WeakMap();
+  var nextOlderShadowTreeTable = new WeakMap();
+  var spaceCharRe = /[ \t\n\r\f]/;
+  function ShadowRoot(hostWrapper) {
+    var node = unwrap(unsafeUnwrap(hostWrapper).ownerDocument.createDocumentFragment());
+    DocumentFragment.call(this, node);
+    rewrap(node, this);
+    var oldShadowRoot = hostWrapper.shadowRoot;
+    nextOlderShadowTreeTable.set(this, oldShadowRoot);
+    this.treeScope_ = new TreeScope(this, getTreeScope(oldShadowRoot || hostWrapper));
+    shadowHostTable.set(this, hostWrapper);
+  }
+  ShadowRoot.prototype = Object.create(DocumentFragment.prototype);
+  mixin(ShadowRoot.prototype, {
+    constructor: ShadowRoot,
+    get innerHTML() {
+      return getInnerHTML(this);
+    },
+    set innerHTML(value) {
+      setInnerHTML(this, value);
+      this.invalidateShadowRenderer();
+    },
+    get olderShadowRoot() {
+      return nextOlderShadowTreeTable.get(this) || null;
+    },
+    get host() {
+      return shadowHostTable.get(this) || null;
+    },
+    invalidateShadowRenderer: function() {
+      return shadowHostTable.get(this).invalidateShadowRenderer();
+    },
+    elementFromPoint: function(x, y) {
+      return elementFromPoint(this, this.ownerDocument, x, y);
+    },
+    getElementById: function(id) {
+      if (spaceCharRe.test(id)) return null;
+      return this.querySelector('[id="' + id + '"]');
+    }
+  });
+  scope.wrappers.ShadowRoot = ShadowRoot;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var Element = scope.wrappers.Element;
+  var HTMLContentElement = scope.wrappers.HTMLContentElement;
+  var HTMLShadowElement = scope.wrappers.HTMLShadowElement;
+  var Node = scope.wrappers.Node;
+  var ShadowRoot = scope.wrappers.ShadowRoot;
+  var assert = scope.assert;
+  var getTreeScope = scope.getTreeScope;
+  var mixin = scope.mixin;
+  var oneOf = scope.oneOf;
+  var unsafeUnwrap = scope.unsafeUnwrap;
+  var unwrap = scope.unwrap;
+  var wrap = scope.wrap;
+  var ArraySplice = scope.ArraySplice;
+  function updateWrapperUpAndSideways(wrapper) {
+    wrapper.previousSibling_ = wrapper.previousSibling;
+    wrapper.nextSibling_ = wrapper.nextSibling;
+    wrapper.parentNode_ = wrapper.parentNode;
+  }
+  function updateWrapperDown(wrapper) {
+    wrapper.firstChild_ = wrapper.firstChild;
+    wrapper.lastChild_ = wrapper.lastChild;
+  }
+  function updateAllChildNodes(parentNodeWrapper) {
+    assert(parentNodeWrapper instanceof Node);
+    for (var childWrapper = parentNodeWrapper.firstChild; childWrapper; childWrapper = childWrapper.nextSibling) {
+      updateWrapperUpAndSideways(childWrapper);
+    }
+    updateWrapperDown(parentNodeWrapper);
+  }
+  function insertBefore(parentNodeWrapper, newChildWrapper, refChildWrapper) {
+    var parentNode = unwrap(parentNodeWrapper);
+    var newChild = unwrap(newChildWrapper);
+    var refChild = refChildWrapper ? unwrap(refChildWrapper) : null;
+    remove(newChildWrapper);
+    updateWrapperUpAndSideways(newChildWrapper);
+    if (!refChildWrapper) {
+      parentNodeWrapper.lastChild_ = parentNodeWrapper.lastChild;
+      if (parentNodeWrapper.lastChild === parentNodeWrapper.firstChild) parentNodeWrapper.firstChild_ = parentNodeWrapper.firstChild;
+      var lastChildWrapper = wrap(parentNode.lastChild);
+      if (lastChildWrapper) lastChildWrapper.nextSibling_ = lastChildWrapper.nextSibling;
+    } else {
+      if (parentNodeWrapper.firstChild === refChildWrapper) parentNodeWrapper.firstChild_ = refChildWrapper;
+      refChildWrapper.previousSibling_ = refChildWrapper.previousSibling;
+    }
+    scope.originalInsertBefore.call(parentNode, newChild, refChild);
+  }
+  function remove(nodeWrapper) {
+    var node = unwrap(nodeWrapper);
+    var parentNode = node.parentNode;
+    if (!parentNode) return;
+    var parentNodeWrapper = wrap(parentNode);
+    updateWrapperUpAndSideways(nodeWrapper);
+    if (nodeWrapper.previousSibling) nodeWrapper.previousSibling.nextSibling_ = nodeWrapper;
+    if (nodeWrapper.nextSibling) nodeWrapper.nextSibling.previousSibling_ = nodeWrapper;
+    if (parentNodeWrapper.lastChild === nodeWrapper) parentNodeWrapper.lastChild_ = nodeWrapper;
+    if (parentNodeWrapper.firstChild === nodeWrapper) parentNodeWrapper.firstChild_ = nodeWrapper;
+    scope.originalRemoveChild.call(parentNode, node);
+  }
+  var distributedNodesTable = new WeakMap();
+  var destinationInsertionPointsTable = new WeakMap();
+  var rendererForHostTable = new WeakMap();
+  function resetDistributedNodes(insertionPoint) {
+    distributedNodesTable.set(insertionPoint, []);
+  }
+  function getDistributedNodes(insertionPoint) {
+    var rv = distributedNodesTable.get(insertionPoint);
+    if (!rv) distributedNodesTable.set(insertionPoint, rv = []);
+    return rv;
+  }
+  function getChildNodesSnapshot(node) {
+    var result = [], i = 0;
+    for (var child = node.firstChild; child; child = child.nextSibling) {
+      result[i++] = child;
+    }
+    return result;
+  }
+  var request = oneOf(window, [ "requestAnimationFrame", "mozRequestAnimationFrame", "webkitRequestAnimationFrame", "setTimeout" ]);
+  var pendingDirtyRenderers = [];
+  var renderTimer;
+  function renderAllPending() {
+    for (var i = 0; i < pendingDirtyRenderers.length; i++) {
+      var renderer = pendingDirtyRenderers[i];
+      var parentRenderer = renderer.parentRenderer;
+      if (parentRenderer && parentRenderer.dirty) continue;
+      renderer.render();
+    }
+    pendingDirtyRenderers = [];
+  }
+  function handleRequestAnimationFrame() {
+    renderTimer = null;
+    renderAllPending();
+  }
+  function getRendererForHost(host) {
+    var renderer = rendererForHostTable.get(host);
+    if (!renderer) {
+      renderer = new ShadowRenderer(host);
+      rendererForHostTable.set(host, renderer);
+    }
+    return renderer;
+  }
+  function getShadowRootAncestor(node) {
+    var root = getTreeScope(node).root;
+    if (root instanceof ShadowRoot) return root;
+    return null;
+  }
+  function getRendererForShadowRoot(shadowRoot) {
+    return getRendererForHost(shadowRoot.host);
+  }
+  var spliceDiff = new ArraySplice();
+  spliceDiff.equals = function(renderNode, rawNode) {
+    return unwrap(renderNode.node) === rawNode;
+  };
+  function RenderNode(node) {
+    this.skip = false;
+    this.node = node;
+    this.childNodes = [];
+  }
+  RenderNode.prototype = {
+    append: function(node) {
+      var rv = new RenderNode(node);
+      this.childNodes.push(rv);
+      return rv;
+    },
+    sync: function(opt_added) {
+      if (this.skip) return;
+      var nodeWrapper = this.node;
+      var newChildren = this.childNodes;
+      var oldChildren = getChildNodesSnapshot(unwrap(nodeWrapper));
+      var added = opt_added || new WeakMap();
+      var splices = spliceDiff.calculateSplices(newChildren, oldChildren);
+      var newIndex = 0, oldIndex = 0;
+      var lastIndex = 0;
+      for (var i = 0; i < splices.length; i++) {
+        var splice = splices[i];
+        for (;lastIndex < splice.index; lastIndex++) {
+          oldIndex++;
+          newChildren[newIndex++].sync(added);
+        }
+        var removedCount = splice.removed.length;
+        for (var j = 0; j < removedCount; j++) {
+          var wrapper = wrap(oldChildren[oldIndex++]);
+          if (!added.get(wrapper)) remove(wrapper);
+        }
+        var addedCount = splice.addedCount;
+        var refNode = oldChildren[oldIndex] && wrap(oldChildren[oldIndex]);
+        for (var j = 0; j < addedCount; j++) {
+          var newChildRenderNode = newChildren[newIndex++];
+          var newChildWrapper = newChildRenderNode.node;
+          insertBefore(nodeWrapper, newChildWrapper, refNode);
+          added.set(newChildWrapper, true);
+          newChildRenderNode.sync(added);
+        }
+        lastIndex += addedCount;
+      }
+      for (var i = lastIndex; i < newChildren.length; i++) {
+        newChildren[i].sync(added);
+      }
+    }
+  };
+  function ShadowRenderer(host) {
+    this.host = host;
+    this.dirty = false;
+    this.invalidateAttributes();
+    this.associateNode(host);
+  }
+  ShadowRenderer.prototype = {
+    render: function(opt_renderNode) {
+      if (!this.dirty) return;
+      this.invalidateAttributes();
+      var host = this.host;
+      this.distribution(host);
+      var renderNode = opt_renderNode || new RenderNode(host);
+      this.buildRenderTree(renderNode, host);
+      var topMostRenderer = !opt_renderNode;
+      if (topMostRenderer) renderNode.sync();
+      this.dirty = false;
+    },
+    get parentRenderer() {
+      return getTreeScope(this.host).renderer;
+    },
+    invalidate: function() {
+      if (!this.dirty) {
+        this.dirty = true;
+        var parentRenderer = this.parentRenderer;
+        if (parentRenderer) parentRenderer.invalidate();
+        pendingDirtyRenderers.push(this);
+        if (renderTimer) return;
+        renderTimer = window[request](handleRequestAnimationFrame, 0);
+      }
+    },
+    distribution: function(root) {
+      this.resetAllSubtrees(root);
+      this.distributionResolution(root);
+    },
+    resetAll: function(node) {
+      if (isInsertionPoint(node)) resetDistributedNodes(node); else resetDestinationInsertionPoints(node);
+      this.resetAllSubtrees(node);
+    },
+    resetAllSubtrees: function(node) {
+      for (var child = node.firstChild; child; child = child.nextSibling) {
+        this.resetAll(child);
+      }
+      if (node.shadowRoot) this.resetAll(node.shadowRoot);
+      if (node.olderShadowRoot) this.resetAll(node.olderShadowRoot);
+    },
+    distributionResolution: function(node) {
+      if (isShadowHost(node)) {
+        var shadowHost = node;
+        var pool = poolPopulation(shadowHost);
+        var shadowTrees = getShadowTrees(shadowHost);
+        for (var i = 0; i < shadowTrees.length; i++) {
+          this.poolDistribution(shadowTrees[i], pool);
+        }
+        for (var i = shadowTrees.length - 1; i >= 0; i--) {
+          var shadowTree = shadowTrees[i];
+          var shadow = getShadowInsertionPoint(shadowTree);
+          if (shadow) {
+            var olderShadowRoot = shadowTree.olderShadowRoot;
+            if (olderShadowRoot) {
+              pool = poolPopulation(olderShadowRoot);
+            }
+            for (var j = 0; j < pool.length; j++) {
+              destributeNodeInto(pool[j], shadow);
+            }
+          }
+          this.distributionResolution(shadowTree);
+        }
+      }
+      for (var child = node.firstChild; child; child = child.nextSibling) {
+        this.distributionResolution(child);
+      }
+    },
+    poolDistribution: function(node, pool) {
+      if (node instanceof HTMLShadowElement) return;
+      if (node instanceof HTMLContentElement) {
+        var content = node;
+        this.updateDependentAttributes(content.getAttribute("select"));
+        var anyDistributed = false;
+        for (var i = 0; i < pool.length; i++) {
+          var node = pool[i];
+          if (!node) continue;
+          if (matches(node, content)) {
+            destributeNodeInto(node, content);
+            pool[i] = undefined;
+            anyDistributed = true;
+          }
+        }
+        if (!anyDistributed) {
+          for (var child = content.firstChild; child; child = child.nextSibling) {
+            destributeNodeInto(child, content);
+          }
+        }
+        return;
+      }
+      for (var child = node.firstChild; child; child = child.nextSibling) {
+        this.poolDistribution(child, pool);
+      }
+    },
+    buildRenderTree: function(renderNode, node) {
+      var children = this.compose(node);
+      for (var i = 0; i < children.length; i++) {
+        var child = children[i];
+        var childRenderNode = renderNode.append(child);
+        this.buildRenderTree(childRenderNode, child);
+      }
+      if (isShadowHost(node)) {
+        var renderer = getRendererForHost(node);
+        renderer.dirty = false;
+      }
+    },
+    compose: function(node) {
+      var children = [];
+      var p = node.shadowRoot || node;
+      for (var child = p.firstChild; child; child = child.nextSibling) {
+        if (isInsertionPoint(child)) {
+          this.associateNode(p);
+          var distributedNodes = getDistributedNodes(child);
+          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;
+    },
+    invalidateAttributes: function() {
+      this.attributes = Object.create(null);
+    },
+    updateDependentAttributes: function(selector) {
+      if (!selector) return;
+      var attributes = this.attributes;
+      if (/\.\w+/.test(selector)) attributes["class"] = true;
+      if (/#\w+/.test(selector)) attributes["id"] = true;
+      selector.replace(/\[\s*([^\s=\|~\]]+)/g, function(_, name) {
+        attributes[name] = true;
+      });
+    },
+    dependsOnAttribute: function(name) {
+      return this.attributes[name];
+    },
+    associateNode: function(node) {
+      unsafeUnwrap(node).polymerShadowRenderer_ = this;
+    }
+  };
+  function poolPopulation(node) {
+    var pool = [];
+    for (var child = node.firstChild; child; child = child.nextSibling) {
+      if (isInsertionPoint(child)) {
+        pool.push.apply(pool, getDistributedNodes(child));
+      } else {
+        pool.push(child);
+      }
+    }
+    return pool;
+  }
+  function getShadowInsertionPoint(node) {
+    if (node instanceof HTMLShadowElement) return node;
+    if (node instanceof HTMLContentElement) return null;
+    for (var child = node.firstChild; child; child = child.nextSibling) {
+      var res = getShadowInsertionPoint(child);
+      if (res) return res;
+    }
+    return null;
+  }
+  function destributeNodeInto(child, insertionPoint) {
+    getDistributedNodes(insertionPoint).push(child);
+    var points = destinationInsertionPointsTable.get(child);
+    if (!points) destinationInsertionPointsTable.set(child, [ insertionPoint ]); else points.push(insertionPoint);
+  }
+  function getDestinationInsertionPoints(node) {
+    return destinationInsertionPointsTable.get(node);
+  }
+  function resetDestinationInsertionPoints(node) {
+    destinationInsertionPointsTable.set(node, undefined);
+  }
+  var selectorStartCharRe = /^(:not\()?[*.#[a-zA-Z_|]/;
+  function matches(node, contentElement) {
+    var select = contentElement.getAttribute("select");
+    if (!select) return true;
+    select = select.trim();
+    if (!select) return true;
+    if (!(node instanceof Element)) return false;
+    if (!selectorStartCharRe.test(select)) return false;
+    try {
+      return node.matches(select);
+    } catch (ex) {
+      return false;
+    }
+  }
+  function isFinalDestination(insertionPoint, node) {
+    var points = getDestinationInsertionPoints(node);
+    return points && points[points.length - 1] === insertionPoint;
+  }
+  function isInsertionPoint(node) {
+    return node instanceof HTMLContentElement || node instanceof HTMLShadowElement;
+  }
+  function isShadowHost(shadowHost) {
+    return shadowHost.shadowRoot;
+  }
+  function getShadowTrees(host) {
+    var trees = [];
+    for (var tree = host.shadowRoot; tree; tree = tree.olderShadowRoot) {
+      trees.push(tree);
+    }
+    return trees;
+  }
+  function render(host) {
+    new ShadowRenderer(host).render();
+  }
+  Node.prototype.invalidateShadowRenderer = function(force) {
+    var renderer = unsafeUnwrap(this).polymerShadowRenderer_;
+    if (renderer) {
+      renderer.invalidate();
+      return true;
+    }
+    return false;
+  };
+  HTMLContentElement.prototype.getDistributedNodes = HTMLShadowElement.prototype.getDistributedNodes = function() {
+    renderAllPending();
+    return getDistributedNodes(this);
+  };
+  Element.prototype.getDestinationInsertionPoints = function() {
+    renderAllPending();
+    return getDestinationInsertionPoints(this) || [];
+  };
+  HTMLContentElement.prototype.nodeIsInserted_ = HTMLShadowElement.prototype.nodeIsInserted_ = function() {
+    this.invalidateShadowRenderer();
+    var shadowRoot = getShadowRootAncestor(this);
+    var renderer;
+    if (shadowRoot) renderer = getRendererForShadowRoot(shadowRoot);
+    unsafeUnwrap(this).polymerShadowRenderer_ = renderer;
+    if (renderer) renderer.invalidate();
+  };
+  scope.getRendererForHost = getRendererForHost;
+  scope.getShadowTrees = getShadowTrees;
+  scope.renderAllPending = renderAllPending;
+  scope.getDestinationInsertionPoints = getDestinationInsertionPoints;
+  scope.visual = {
+    insertBefore: insertBefore,
+    remove: remove
+  };
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var HTMLElement = scope.wrappers.HTMLElement;
+  var assert = scope.assert;
+  var mixin = scope.mixin;
+  var registerWrapper = scope.registerWrapper;
+  var unwrap = scope.unwrap;
+  var wrap = scope.wrap;
+  var elementsWithFormProperty = [ "HTMLButtonElement", "HTMLFieldSetElement", "HTMLInputElement", "HTMLKeygenElement", "HTMLLabelElement", "HTMLLegendElement", "HTMLObjectElement", "HTMLOutputElement", "HTMLTextAreaElement" ];
+  function createWrapperConstructor(name) {
+    if (!window[name]) return;
+    assert(!scope.wrappers[name]);
+    var GeneratedWrapper = function(node) {
+      HTMLElement.call(this, node);
+    };
+    GeneratedWrapper.prototype = Object.create(HTMLElement.prototype);
+    mixin(GeneratedWrapper.prototype, {
+      get form() {
+        return wrap(unwrap(this).form);
+      }
+    });
+    registerWrapper(window[name], GeneratedWrapper, document.createElement(name.slice(4, -7)));
+    scope.wrappers[name] = GeneratedWrapper;
+  }
+  elementsWithFormProperty.forEach(createWrapperConstructor);
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var registerWrapper = scope.registerWrapper;
+  var setWrapper = scope.setWrapper;
+  var unsafeUnwrap = scope.unsafeUnwrap;
+  var unwrap = scope.unwrap;
+  var unwrapIfNeeded = scope.unwrapIfNeeded;
+  var wrap = scope.wrap;
+  var OriginalSelection = window.Selection;
+  function Selection(impl) {
+    setWrapper(impl, this);
+  }
+  Selection.prototype = {
+    get anchorNode() {
+      return wrap(unsafeUnwrap(this).anchorNode);
+    },
+    get focusNode() {
+      return wrap(unsafeUnwrap(this).focusNode);
+    },
+    addRange: function(range) {
+      unsafeUnwrap(this).addRange(unwrap(range));
+    },
+    collapse: function(node, index) {
+      unsafeUnwrap(this).collapse(unwrapIfNeeded(node), index);
+    },
+    containsNode: function(node, allowPartial) {
+      return unsafeUnwrap(this).containsNode(unwrapIfNeeded(node), allowPartial);
+    },
+    extend: function(node, offset) {
+      unsafeUnwrap(this).extend(unwrapIfNeeded(node), offset);
+    },
+    getRangeAt: function(index) {
+      return wrap(unsafeUnwrap(this).getRangeAt(index));
+    },
+    removeRange: function(range) {
+      unsafeUnwrap(this).removeRange(unwrap(range));
+    },
+    selectAllChildren: function(node) {
+      unsafeUnwrap(this).selectAllChildren(unwrapIfNeeded(node));
+    },
+    toString: function() {
+      return unsafeUnwrap(this).toString();
+    }
+  };
+  registerWrapper(window.Selection, Selection, window.getSelection());
+  scope.wrappers.Selection = Selection;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var GetElementsByInterface = scope.GetElementsByInterface;
+  var Node = scope.wrappers.Node;
+  var ParentNodeInterface = scope.ParentNodeInterface;
+  var Selection = scope.wrappers.Selection;
+  var SelectorsInterface = scope.SelectorsInterface;
+  var ShadowRoot = scope.wrappers.ShadowRoot;
+  var TreeScope = scope.TreeScope;
+  var cloneNode = scope.cloneNode;
+  var defineWrapGetter = scope.defineWrapGetter;
+  var elementFromPoint = scope.elementFromPoint;
+  var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
+  var matchesNames = scope.matchesNames;
+  var mixin = scope.mixin;
+  var registerWrapper = scope.registerWrapper;
+  var renderAllPending = scope.renderAllPending;
+  var rewrap = scope.rewrap;
+  var setWrapper = scope.setWrapper;
+  var unsafeUnwrap = scope.unsafeUnwrap;
+  var unwrap = scope.unwrap;
+  var wrap = scope.wrap;
+  var wrapEventTargetMethods = scope.wrapEventTargetMethods;
+  var wrapNodeList = scope.wrapNodeList;
+  var implementationTable = new WeakMap();
+  function Document(node) {
+    Node.call(this, node);
+    this.treeScope_ = new TreeScope(this, null);
+  }
+  Document.prototype = Object.create(Node.prototype);
+  defineWrapGetter(Document, "documentElement");
+  defineWrapGetter(Document, "body");
+  defineWrapGetter(Document, "head");
+  function wrapMethod(name) {
+    var original = document[name];
+    Document.prototype[name] = function() {
+      return wrap(original.apply(unsafeUnwrap(this), arguments));
+    };
+  }
+  [ "createComment", "createDocumentFragment", "createElement", "createElementNS", "createEvent", "createEventNS", "createRange", "createTextNode", "getElementById" ].forEach(wrapMethod);
+  var originalAdoptNode = document.adoptNode;
+  function adoptNodeNoRemove(node, doc) {
+    originalAdoptNode.call(unsafeUnwrap(doc), unwrap(node));
+    adoptSubtree(node, doc);
+  }
+  function adoptSubtree(node, doc) {
+    if (node.shadowRoot) doc.adoptNode(node.shadowRoot);
+    if (node instanceof ShadowRoot) adoptOlderShadowRoots(node, doc);
+    for (var child = node.firstChild; child; child = child.nextSibling) {
+      adoptSubtree(child, doc);
+    }
+  }
+  function adoptOlderShadowRoots(shadowRoot, doc) {
+    var oldShadowRoot = shadowRoot.olderShadowRoot;
+    if (oldShadowRoot) doc.adoptNode(oldShadowRoot);
+  }
+  var originalGetSelection = document.getSelection;
+  mixin(Document.prototype, {
+    adoptNode: function(node) {
+      if (node.parentNode) node.parentNode.removeChild(node);
+      adoptNodeNoRemove(node, this);
+      return node;
+    },
+    elementFromPoint: function(x, y) {
+      return elementFromPoint(this, this, x, y);
+    },
+    importNode: function(node, deep) {
+      return cloneNode(node, deep, unsafeUnwrap(this));
+    },
+    getSelection: function() {
+      renderAllPending();
+      return new Selection(originalGetSelection.call(unwrap(this)));
+    },
+    getElementsByName: function(name) {
+      return SelectorsInterface.querySelectorAll.call(this, "[name=" + JSON.stringify(String(name)) + "]");
+    }
+  });
+  if (document.registerElement) {
+    var originalRegisterElement = document.registerElement;
+    Document.prototype.registerElement = function(tagName, object) {
+      var prototype, extendsOption;
+      if (object !== undefined) {
+        prototype = object.prototype;
+        extendsOption = object.extends;
+      }
+      if (!prototype) prototype = Object.create(HTMLElement.prototype);
+      if (scope.nativePrototypeTable.get(prototype)) {
+        throw new Error("NotSupportedError");
+      }
+      var proto = Object.getPrototypeOf(prototype);
+      var nativePrototype;
+      var prototypes = [];
+      while (proto) {
+        nativePrototype = scope.nativePrototypeTable.get(proto);
+        if (nativePrototype) break;
+        prototypes.push(proto);
+        proto = Object.getPrototypeOf(proto);
+      }
+      if (!nativePrototype) {
+        throw new Error("NotSupportedError");
+      }
+      var newPrototype = Object.create(nativePrototype);
+      for (var i = prototypes.length - 1; i >= 0; i--) {
+        newPrototype = Object.create(newPrototype);
+      }
+      [ "createdCallback", "attachedCallback", "detachedCallback", "attributeChangedCallback" ].forEach(function(name) {
+        var f = prototype[name];
+        if (!f) return;
+        newPrototype[name] = function() {
+          if (!(wrap(this) instanceof CustomElementConstructor)) {
+            rewrap(this);
+          }
+          f.apply(wrap(this), arguments);
+        };
+      });
+      var p = {
+        prototype: newPrototype
+      };
+      if (extendsOption) p.extends = extendsOption;
+      function CustomElementConstructor(node) {
+        if (!node) {
+          if (extendsOption) {
+            return document.createElement(extendsOption, tagName);
+          } else {
+            return document.createElement(tagName);
+          }
+        }
+        setWrapper(node, this);
+      }
+      CustomElementConstructor.prototype = prototype;
+      CustomElementConstructor.prototype.constructor = CustomElementConstructor;
+      scope.constructorTable.set(newPrototype, CustomElementConstructor);
+      scope.nativePrototypeTable.set(prototype, newPrototype);
+      var nativeConstructor = originalRegisterElement.call(unwrap(this), tagName, p);
+      return CustomElementConstructor;
+    };
+    forwardMethodsToWrapper([ window.HTMLDocument || window.Document ], [ "registerElement" ]);
+  }
+  forwardMethodsToWrapper([ window.HTMLBodyElement, window.HTMLDocument || window.Document, window.HTMLHeadElement, window.HTMLHtmlElement ], [ "appendChild", "compareDocumentPosition", "contains", "getElementsByClassName", "getElementsByTagName", "getElementsByTagNameNS", "insertBefore", "querySelector", "querySelectorAll", "removeChild", "replaceChild" ]);
+  forwardMethodsToWrapper([ window.HTMLBodyElement, window.HTMLHeadElement, window.HTMLHtmlElement ], matchesNames);
+  forwardMethodsToWrapper([ window.HTMLDocument || window.Document ], [ "adoptNode", "importNode", "contains", "createComment", "createDocumentFragment", "createElement", "createElementNS", "createEvent", "createEventNS", "createRange", "createTextNode", "elementFromPoint", "getElementById", "getElementsByName", "getSelection" ]);
+  mixin(Document.prototype, GetElementsByInterface);
+  mixin(Document.prototype, ParentNodeInterface);
+  mixin(Document.prototype, SelectorsInterface);
+  mixin(Document.prototype, {
+    get implementation() {
+      var implementation = implementationTable.get(this);
+      if (implementation) return implementation;
+      implementation = new DOMImplementation(unwrap(this).implementation);
+      implementationTable.set(this, implementation);
+      return implementation;
+    },
+    get defaultView() {
+      return wrap(unwrap(this).defaultView);
+    }
+  });
+  registerWrapper(window.Document, Document, document.implementation.createHTMLDocument(""));
+  if (window.HTMLDocument) registerWrapper(window.HTMLDocument, Document);
+  wrapEventTargetMethods([ window.HTMLBodyElement, window.HTMLDocument || window.Document, window.HTMLHeadElement ]);
+  function DOMImplementation(impl) {
+    setWrapper(impl, this);
+  }
+  function wrapImplMethod(constructor, name) {
+    var original = document.implementation[name];
+    constructor.prototype[name] = function() {
+      return wrap(original.apply(unsafeUnwrap(this), arguments));
+    };
+  }
+  function forwardImplMethod(constructor, name) {
+    var original = document.implementation[name];
+    constructor.prototype[name] = function() {
+      return original.apply(unsafeUnwrap(this), arguments);
+    };
+  }
+  wrapImplMethod(DOMImplementation, "createDocumentType");
+  wrapImplMethod(DOMImplementation, "createDocument");
+  wrapImplMethod(DOMImplementation, "createHTMLDocument");
+  forwardImplMethod(DOMImplementation, "hasFeature");
+  registerWrapper(window.DOMImplementation, DOMImplementation);
+  forwardMethodsToWrapper([ window.DOMImplementation ], [ "createDocumentType", "createDocument", "createHTMLDocument", "hasFeature" ]);
+  scope.adoptNodeNoRemove = adoptNodeNoRemove;
+  scope.wrappers.DOMImplementation = DOMImplementation;
+  scope.wrappers.Document = Document;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var EventTarget = scope.wrappers.EventTarget;
+  var Selection = scope.wrappers.Selection;
+  var mixin = scope.mixin;
+  var registerWrapper = scope.registerWrapper;
+  var renderAllPending = scope.renderAllPending;
+  var unwrap = scope.unwrap;
+  var unwrapIfNeeded = scope.unwrapIfNeeded;
+  var wrap = scope.wrap;
+  var OriginalWindow = window.Window;
+  var originalGetComputedStyle = window.getComputedStyle;
+  var originalGetDefaultComputedStyle = window.getDefaultComputedStyle;
+  var originalGetSelection = window.getSelection;
+  function Window(impl) {
+    EventTarget.call(this, impl);
+  }
+  Window.prototype = Object.create(EventTarget.prototype);
+  OriginalWindow.prototype.getComputedStyle = function(el, pseudo) {
+    return wrap(this || window).getComputedStyle(unwrapIfNeeded(el), pseudo);
+  };
+  if (originalGetDefaultComputedStyle) {
+    OriginalWindow.prototype.getDefaultComputedStyle = function(el, pseudo) {
+      return wrap(this || window).getDefaultComputedStyle(unwrapIfNeeded(el), pseudo);
+    };
+  }
+  OriginalWindow.prototype.getSelection = function() {
+    return wrap(this || window).getSelection();
+  };
+  delete window.getComputedStyle;
+  delete window.getDefaultComputedStyle;
+  delete window.getSelection;
+  [ "addEventListener", "removeEventListener", "dispatchEvent" ].forEach(function(name) {
+    OriginalWindow.prototype[name] = function() {
+      var w = wrap(this || window);
+      return w[name].apply(w, arguments);
+    };
+    delete window[name];
+  });
+  mixin(Window.prototype, {
+    getComputedStyle: function(el, pseudo) {
+      renderAllPending();
+      return originalGetComputedStyle.call(unwrap(this), unwrapIfNeeded(el), pseudo);
+    },
+    getSelection: function() {
+      renderAllPending();
+      return new Selection(originalGetSelection.call(unwrap(this)));
+    },
+    get document() {
+      return wrap(unwrap(this).document);
+    }
+  });
+  if (originalGetDefaultComputedStyle) {
+    Window.prototype.getDefaultComputedStyle = function(el, pseudo) {
+      renderAllPending();
+      return originalGetDefaultComputedStyle.call(unwrap(this), unwrapIfNeeded(el), pseudo);
+    };
+  }
+  registerWrapper(OriginalWindow, Window, window);
+  scope.wrappers.Window = Window;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var unwrap = scope.unwrap;
+  var OriginalDataTransfer = window.DataTransfer || window.Clipboard;
+  var OriginalDataTransferSetDragImage = OriginalDataTransfer.prototype.setDragImage;
+  if (OriginalDataTransferSetDragImage) {
+    OriginalDataTransfer.prototype.setDragImage = function(image, x, y) {
+      OriginalDataTransferSetDragImage.call(this, unwrap(image), x, y);
+    };
+  }
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var registerWrapper = scope.registerWrapper;
+  var setWrapper = scope.setWrapper;
+  var unwrap = scope.unwrap;
+  var OriginalFormData = window.FormData;
+  if (!OriginalFormData) return;
+  function FormData(formElement) {
+    var impl;
+    if (formElement instanceof OriginalFormData) {
+      impl = formElement;
+    } else {
+      impl = new OriginalFormData(formElement && unwrap(formElement));
+    }
+    setWrapper(impl, this);
+  }
+  registerWrapper(OriginalFormData, FormData, new OriginalFormData());
+  scope.wrappers.FormData = FormData;
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var unwrapIfNeeded = scope.unwrapIfNeeded;
+  var originalSend = XMLHttpRequest.prototype.send;
+  XMLHttpRequest.prototype.send = function(obj) {
+    return originalSend.call(this, unwrapIfNeeded(obj));
+  };
+})(window.ShadowDOMPolyfill);
+
+(function(scope) {
+  "use strict";
+  var isWrapperFor = scope.isWrapperFor;
+  var elements = {
+    a: "HTMLAnchorElement",
+    area: "HTMLAreaElement",
+    audio: "HTMLAudioElement",
+    base: "HTMLBaseElement",
+    body: "HTMLBodyElement",
+    br: "HTMLBRElement",
+    button: "HTMLButtonElement",
+    canvas: "HTMLCanvasElement",
+    caption: "HTMLTableCaptionElement",
+    col: "HTMLTableColElement",
+    content: "HTMLContentElement",
+    data: "HTMLDataElement",
+    datalist: "HTMLDataListElement",
+    del: "HTMLModElement",
+    dir: "HTMLDirectoryElement",
+    div: "HTMLDivElement",
+    dl: "HTMLDListElement",
+    embed: "HTMLEmbedElement",
+    fieldset: "HTMLFieldSetElement",
+    font: "HTMLFontElement",
+    form: "HTMLFormElement",
+    frame: "HTMLFrameElement",
+    frameset: "HTMLFrameSetElement",
+    h1: "HTMLHeadingElement",
+    head: "HTMLHeadElement",
+    hr: "HTMLHRElement",
+    html: "HTMLHtmlElement",
+    iframe: "HTMLIFrameElement",
+    img: "HTMLImageElement",
+    input: "HTMLInputElement",
+    keygen: "HTMLKeygenElement",
+    label: "HTMLLabelElement",
+    legend: "HTMLLegendElement",
+    li: "HTMLLIElement",
+    link: "HTMLLinkElement",
+    map: "HTMLMapElement",
+    marquee: "HTMLMarqueeElement",
+    menu: "HTMLMenuElement",
+    menuitem: "HTMLMenuItemElement",
+    meta: "HTMLMetaElement",
+    meter: "HTMLMeterElement",
+    object: "HTMLObjectElement",
+    ol: "HTMLOListElement",
+    optgroup: "HTMLOptGroupElement",
+    option: "HTMLOptionElement",
+    output: "HTMLOutputElement",
+    p: "HTMLParagraphElement",
+    param: "HTMLParamElement",
+    pre: "HTMLPreElement",
+    progress: "HTMLProgressElement",
+    q: "HTMLQuoteElement",
+    script: "HTMLScriptElement",
+    select: "HTMLSelectElement",
+    shadow: "HTMLShadowElement",
+    source: "HTMLSourceElement",
+    span: "HTMLSpanElement",
+    style: "HTMLStyleElement",
+    table: "HTMLTableElement",
+    tbody: "HTMLTableSectionElement",
+    template: "HTMLTemplateElement",
+    textarea: "HTMLTextAreaElement",
+    thead: "HTMLTableSectionElement",
+    time: "HTMLTimeElement",
+    title: "HTMLTitleElement",
+    tr: "HTMLTableRowElement",
+    track: "HTMLTrackElement",
+    ul: "HTMLUListElement",
+    video: "HTMLVideoElement"
+  };
+  function overrideConstructor(tagName) {
+    var nativeConstructorName = elements[tagName];
+    var nativeConstructor = window[nativeConstructorName];
+    if (!nativeConstructor) return;
+    var element = document.createElement(tagName);
+    var wrapperConstructor = element.constructor;
+    window[nativeConstructorName] = wrapperConstructor;
+  }
+  Object.keys(elements).forEach(overrideConstructor);
+  Object.getOwnPropertyNames(scope.wrappers).forEach(function(name) {
+    window[name] = scope.wrappers[name];
+  });
+})(window.ShadowDOMPolyfill);
\ No newline at end of file
diff --git a/example/bower_components/webcomponentsjs/ShadowDOM.min.js b/example/bower_components/webcomponentsjs/ShadowDOM.min.js
new file mode 100644
index 000000000..72faf74ca
--- /dev/null
+++ b/example/bower_components/webcomponentsjs/ShadowDOM.min.js
@@ -0,0 +1,13 @@
+/**
+ * @license
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// @version 0.5.5
+"undefined"==typeof WeakMap&&!function(){var e=Object.defineProperty,t=Date.now()%1e9,n=function(){this.name="__st"+(1e9*Math.random()>>>0)+(t++ +"__")};n.prototype={set:function(t,n){var r=t[this.name];return r&&r[0]===t?r[1]=n:e(t,this.name,{value:[t,n],writable:!0}),this},get:function(e){var t;return(t=e[this.name])&&t[0]===e?t[1]:void 0},"delete":function(e){var t=e[this.name];return t&&t[0]===e?(t[0]=t[1]=void 0,!0):!1},has:function(e){var t=e[this.name];return t?t[0]===e:!1}},window.WeakMap=n}(),window.ShadowDOMPolyfill={},function(e){"use strict";function t(){if("undefined"!=typeof chrome&&chrome.app&&chrome.app.runtime)return!1;if(navigator.getDeviceStorage)return!1;try{var e=new Function("return true;");return e()}catch(t){return!1}}function n(e){if(!e)throw new Error("Assertion failed")}function r(e,t){for(var n=k(t),r=0;ru;u++)c[u]=new Array(s),c[u][0]=u;for(var l=0;s>l;l++)c[0][l]=l;for(var u=1;a>u;u++)for(var l=1;s>l;l++)if(this.equals(e[t+l-1],r[o+u-1]))c[u][l]=c[u-1][l-1];else{var p=c[u-1][l]+1,d=c[u][l-1]+1;c[u][l]=d>p?p:d}return c},spliceOperationsFromEditDistances:function(e){for(var t=e.length-1,n=e[0].length-1,s=e[t][n],c=[];t>0||n>0;)if(0!=t)if(0!=n){var u,l=e[t-1][n-1],p=e[t-1][n],d=e[t][n-1];u=d>p?l>p?p:l:l>d?d:l,u==l?(l==s?c.push(r):(c.push(o),s=l),t--,n--):u==p?(c.push(a),t--,s=p):(c.push(i),n--,s=d)}else c.push(a),t--;else c.push(i),n--;return c.reverse(),c},calcSplices:function(e,n,s,c,u,l){var p=0,d=0,f=Math.min(s-n,l-u);if(0==n&&0==u&&(p=this.sharedPrefix(e,c,f)),s==e.length&&l==c.length&&(d=this.sharedSuffix(e,c,f-p)),n+=p,u+=p,s-=d,l-=d,s-n==0&&l-u==0)return[];if(n==s){for(var h=t(n,[],0);l>u;)h.removed.push(c[u++]);return[h]}if(u==l)return[t(n,[],s-n)];for(var w=this.spliceOperationsFromEditDistances(this.calcEditDistances(e,n,s,c,u,l)),h=void 0,m=[],g=n,v=u,b=0;br;r++)if(!this.equals(e[r],t[r]))return r;return n},sharedSuffix:function(e,t,n){for(var r=e.length,o=t.length,i=0;n>i&&this.equals(e[--r],t[--o]);)i++;return i},calculateSplices:function(e,t){return this.calcSplices(e,0,e.length,t,0,t.length)},equals:function(e,t){return e===t}},e.ArraySplice=n}(window.ShadowDOMPolyfill),function(e){"use strict";function t(){a=!1;var e=i.slice(0);i=[];for(var t=0;t0){for(var l=0;l0&&r.length>0;){var i=n.pop(),a=r.pop();if(i!==a)break;o=i}return o}function l(e,t,n){t instanceof G.Window&&(t=t.document);var o,i=I(t),a=I(n),s=r(n,e),o=u(i,a);o||(o=a.root);for(var c=o;c;c=c.parent)for(var l=0;l0;i--)if(!v(t[i],e,o,t,r))return!1;return!0}function m(e,t,n,r){var o=it,i=t[0]||n;return v(i,e,o,t,r)}function g(e,t,n,r){for(var o=at,i=1;i0&&v(n,e,o,t,r)}function v(e,t,n,r,o){var i=X.get(e);if(!i)return!0;var a=o||s(r,e);if(a===e){if(n===ot)return!0;n===at&&(n=it)}else if(n===at&&!t.bubbles)return!0;if("relatedTarget"in t){var c=q(t),u=c.relatedTarget;if(u){if(u instanceof Object&&u.addEventListener){var p=V(u),d=l(t,e,p);if(d===a)return!0}else d=null;Z.set(t,d)}}J.set(t,n);var f=t.type,h=!1;Y.set(t,a),$.set(t,e),i.depth++;for(var w=0,m=i.length;m>w;w++){var g=i[w];if(g.removed)h=!0;else if(!(g.type!==f||!g.capture&&n===ot||g.capture&&n===at))try{if("function"==typeof g.handler?g.handler.call(e,t):g.handler.handleEvent(t),et.get(t))return!1}catch(v){W||(W=v)}}if(i.depth--,h&&0===i.depth){var b=i.slice();i.length=0;for(var w=0;wr;r++)t[r]=a(e[r]);return t.length=o,t}function o(e,t){e.prototype[t]=function(){return r(i(this)[t].apply(i(this),arguments))}}var i=e.unsafeUnwrap,a=e.wrap,s={enumerable:!1};n.prototype={item:function(e){return this[e]}},t(n.prototype,"item"),e.wrappers.NodeList=n,e.addWrapNodeListMethod=o,e.wrapNodeList=r}(window.ShadowDOMPolyfill),function(e){"use strict";e.wrapHTMLCollection=e.wrapNodeList,e.wrappers.HTMLCollection=e.wrappers.NodeList}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){L(e instanceof S)}function n(e){var t=new T;return t[0]=e,t.length=1,t}function r(e,t,n){N(t,"childList",{removedNodes:n,previousSibling:e.previousSibling,nextSibling:e.nextSibling})}function o(e,t){N(e,"childList",{removedNodes:t})}function i(e,t,r,o){if(e instanceof DocumentFragment){var i=s(e);B=!0;for(var a=i.length-1;a>=0;a--)e.removeChild(i[a]),i[a].parentNode_=t;B=!1;for(var a=0;ao;o++)r.appendChild(W(t[o]));return r}function m(e){if(void 0!==e.firstChild_)for(var t=e.firstChild_;t;){var n=t;t=t.nextSibling_,n.parentNode_=n.previousSibling_=n.nextSibling_=void 0}e.firstChild_=e.lastChild_=void 0}function g(e){if(e.invalidateShadowRenderer()){for(var t=e.firstChild;t;){L(t.parentNode===e);var n=t.nextSibling,r=W(t),o=r.parentNode;o&&K.call(o,r),t.previousSibling_=t.nextSibling_=t.parentNode_=null,t=n}e.firstChild_=e.lastChild_=null}else for(var n,i=W(e),a=i.firstChild;a;)n=a.nextSibling,K.call(i,a),a=n}function v(e){var t=e.parentNode;return t&&t.invalidateShadowRenderer()}function b(e){for(var t,n=0;ns;s++)i=b(t[s]),!o&&(a=g(i).root)&&a instanceof e.wrappers.ShadowRoot||(r[n++]=i);return n}function n(e){return String(e).replace(/\/deep\/|::shadow/g," ")}function r(e){return String(e).replace(/:host\(([^\s]+)\)/g,"$1").replace(/([^\s]):host/g,"$1").replace(":host","*").replace(/\^|\/shadow\/|\/shadow-deep\/|::shadow|\/deep\/|::content/g," ")}function o(e,t){for(var n,r=e.firstElementChild;r;){if(r.matches(t))return r;if(n=o(r,t))return n;r=r.nextElementSibling}return null}function i(e,t){return e.matches(t)}function a(e,t,n){var r=e.localName;return r===t||r===n&&e.namespaceURI===C}function s(){return!0}function c(e,t,n){return e.localName===n}function u(e,t){return e.namespaceURI===t}function l(e,t,n){return e.namespaceURI===t&&e.localName===n}function p(e,t,n,r,o,i){for(var a=e.firstElementChild;a;)r(a,o,i)&&(n[t++]=a),t=p(a,t,n,r,o,i),a=a.nextElementSibling;return t}function d(n,r,o,i,a){var s,c=v(this),u=g(this).root;if(u instanceof e.wrappers.ShadowRoot)return p(this,r,o,n,i,null);if(c instanceof N)s=M.call(c,i);else{if(!(c instanceof _))return p(this,r,o,n,i,null);s=S.call(c,i)}return t(s,r,o,a)}function f(n,r,o,i,a){var s,c=v(this),u=g(this).root;if(u instanceof e.wrappers.ShadowRoot)return p(this,r,o,n,i,a);if(c instanceof N)s=O.call(c,i,a);else{if(!(c instanceof _))return p(this,r,o,n,i,a);s=T.call(c,i,a)}return t(s,r,o,!1)}function h(n,r,o,i,a){var s,c=v(this),u=g(this).root;if(u instanceof e.wrappers.ShadowRoot)return p(this,r,o,n,i,a);if(c instanceof N)s=j.call(c,i,a);else{if(!(c instanceof _))return p(this,r,o,n,i,a);s=L.call(c,i,a)}return t(s,r,o,!1)}var w=e.wrappers.HTMLCollection,m=e.wrappers.NodeList,g=e.getTreeScope,v=e.unsafeUnwrap,b=e.wrap,y=document.querySelector,E=document.documentElement.querySelector,S=document.querySelectorAll,M=document.documentElement.querySelectorAll,T=document.getElementsByTagName,O=document.documentElement.getElementsByTagName,L=document.getElementsByTagNameNS,j=document.documentElement.getElementsByTagNameNS,N=window.Element,_=window.HTMLDocument||window.Document,C="http://www.w3.org/1999/xhtml",D={querySelector:function(t){var r=n(t),i=r!==t;t=r;var a,s=v(this),c=g(this).root;if(c instanceof e.wrappers.ShadowRoot)return o(this,t);if(s instanceof N)a=b(E.call(s,t));else{if(!(s instanceof _))return o(this,t);a=b(y.call(s,t))}return a&&!i&&(c=g(a).root)&&c instanceof e.wrappers.ShadowRoot?o(this,t):a},querySelectorAll:function(e){var t=n(e),r=t!==e;e=t;var o=new m;return o.length=d.call(this,i,0,o,e,r),o}},H={matches:function(t){return t=r(t),e.originalMatches.call(v(this),t)}},x={getElementsByTagName:function(e){var t=new w,n="*"===e?s:a;return t.length=f.call(this,n,0,t,e,e.toLowerCase()),t},getElementsByClassName:function(e){return this.querySelectorAll("."+e)},getElementsByTagNameNS:function(e,t){var n=new w,r=null;return r="*"===e?"*"===t?s:c:"*"===t?u:l,n.length=h.call(this,r,0,n,e||null,t),n}};e.GetElementsByInterface=x,e.SelectorsInterface=D,e.MatchesInterface=H}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){for(;e&&e.nodeType!==Node.ELEMENT_NODE;)e=e.nextSibling;return e}function n(e){for(;e&&e.nodeType!==Node.ELEMENT_NODE;)e=e.previousSibling;return e}var r=e.wrappers.NodeList,o={get firstElementChild(){return t(this.firstChild)
+},get lastElementChild(){return n(this.lastChild)},get childElementCount(){for(var e=0,t=this.firstElementChild;t;t=t.nextElementSibling)e++;return e},get children(){for(var e=new r,t=0,n=this.firstElementChild;n;n=n.nextElementSibling)e[t++]=n;return e.length=t,e},remove:function(){var e=this.parentNode;e&&e.removeChild(this)}},i={get nextElementSibling(){return t(this.nextSibling)},get previousElementSibling(){return n(this.previousSibling)}};e.ChildNodeInterface=i,e.ParentNodeInterface=o}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){r.call(this,e)}var n=e.ChildNodeInterface,r=e.wrappers.Node,o=e.enqueueMutation,i=e.mixin,a=e.registerWrapper,s=e.unsafeUnwrap,c=window.CharacterData;t.prototype=Object.create(r.prototype),i(t.prototype,{get textContent(){return this.data},set textContent(e){this.data=e},get data(){return s(this).data},set data(e){var t=s(this).data;o(this,"characterData",{oldValue:t}),s(this).data=e}}),i(t.prototype,n),a(c,t,document.createTextNode("")),e.wrappers.CharacterData=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){return e>>>0}function n(e){r.call(this,e)}var r=e.wrappers.CharacterData,o=(e.enqueueMutation,e.mixin),i=e.registerWrapper,a=window.Text;n.prototype=Object.create(r.prototype),o(n.prototype,{splitText:function(e){e=t(e);var n=this.data;if(e>n.length)throw new Error("IndexSizeError");var r=n.slice(0,e),o=n.slice(e);this.data=r;var i=this.ownerDocument.createTextNode(o);return this.parentNode&&this.parentNode.insertBefore(i,this.nextSibling),i}}),i(a,n,document.createTextNode("")),e.wrappers.Text=n}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){return i(e).getAttribute("class")}function n(e,t){a(e,"attributes",{name:"class",namespace:null,oldValue:t})}function r(t){e.invalidateRendererBasedOnAttribute(t,"class")}function o(e,o,i){var a=e.ownerElement_;if(null==a)return o.apply(e,i);var s=t(a),c=o.apply(e,i);return t(a)!==s&&(n(a,s),r(a)),c}if(!window.DOMTokenList)return void console.warn("Missing DOMTokenList prototype, please include a compatible classList polyfill such as http://goo.gl/uTcepH.");var i=e.unsafeUnwrap,a=e.enqueueMutation,s=DOMTokenList.prototype.add;DOMTokenList.prototype.add=function(){o(this,s,arguments)};var c=DOMTokenList.prototype.remove;DOMTokenList.prototype.remove=function(){o(this,c,arguments)};var u=DOMTokenList.prototype.toggle;DOMTokenList.prototype.toggle=function(){return o(this,u,arguments)}}(window.ShadowDOMPolyfill),function(e){"use strict";function t(t,n){var r=t.parentNode;if(r&&r.shadowRoot){var o=e.getRendererForHost(r);o.dependsOnAttribute(n)&&o.invalidate()}}function n(e,t,n){l(e,"attributes",{name:t,namespace:null,oldValue:n})}function r(e){a.call(this,e)}var o=e.ChildNodeInterface,i=e.GetElementsByInterface,a=e.wrappers.Node,s=e.ParentNodeInterface,c=e.SelectorsInterface,u=e.MatchesInterface,l=(e.addWrapNodeListMethod,e.enqueueMutation),p=e.mixin,d=(e.oneOf,e.registerWrapper),f=e.unsafeUnwrap,h=e.wrappers,w=window.Element,m=["matches","mozMatchesSelector","msMatchesSelector","webkitMatchesSelector"].filter(function(e){return w.prototype[e]}),g=m[0],v=w.prototype[g],b=new WeakMap;r.prototype=Object.create(a.prototype),p(r.prototype,{createShadowRoot:function(){var t=new h.ShadowRoot(this);f(this).polymerShadowRoot_=t;var n=e.getRendererForHost(this);return n.invalidate(),t},get shadowRoot(){return f(this).polymerShadowRoot_||null},setAttribute:function(e,r){var o=f(this).getAttribute(e);f(this).setAttribute(e,r),n(this,e,o),t(this,e)},removeAttribute:function(e){var r=f(this).getAttribute(e);f(this).removeAttribute(e),n(this,e,r),t(this,e)},get classList(){var e=b.get(this);if(!e){if(e=f(this).classList,!e)return;e.ownerElement_=this,b.set(this,e)}return e},get className(){return f(this).className},set className(e){this.setAttribute("class",e)},get id(){return f(this).id},set id(e){this.setAttribute("id",e)}}),m.forEach(function(e){"matches"!==e&&(r.prototype[e]=function(e){return this.matches(e)})}),w.prototype.webkitCreateShadowRoot&&(r.prototype.webkitCreateShadowRoot=r.prototype.createShadowRoot),p(r.prototype,o),p(r.prototype,i),p(r.prototype,s),p(r.prototype,c),p(r.prototype,u),d(w,r,document.createElementNS(null,"x")),e.invalidateRendererBasedOnAttribute=t,e.matchesNames=m,e.originalMatches=v,e.wrappers.Element=r}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){switch(e){case"&":return"&";case"<":return"<";case">":return">";case'"':return""";case" ":return" "}}function n(e){return e.replace(L,t)}function r(e){return e.replace(j,t)}function o(e){for(var t={},n=0;n";case Node.TEXT_NODE:var l=e.data;return t&&_[t.localName]?l:r(l);case Node.COMMENT_NODE:return"";default:throw console.error(e),new Error("not implemented")}}function a(e){e instanceof O.HTMLTemplateElement&&(e=e.content);for(var t="",n=e.firstChild;n;n=n.nextSibling)t+=i(n,e);return t}function s(e,t,n){var r=n||"div";e.textContent="";var o=M(e.ownerDocument.createElement(r));o.innerHTML=t;for(var i;i=o.firstChild;)e.appendChild(T(i))}function c(e){h.call(this,e)}function u(e,t){var n=M(e.cloneNode(!1));n.innerHTML=t;for(var r,o=M(document.createDocumentFragment());r=n.firstChild;)o.appendChild(r);return T(o)}function l(t){return function(){return e.renderAllPending(),S(this)[t]}}function p(e){w(c,e,l(e))}function d(t){Object.defineProperty(c.prototype,t,{get:l(t),set:function(n){e.renderAllPending(),S(this)[t]=n},configurable:!0,enumerable:!0})}function f(t){Object.defineProperty(c.prototype,t,{value:function(){return e.renderAllPending(),S(this)[t].apply(S(this),arguments)},configurable:!0,enumerable:!0})}var h=e.wrappers.Element,w=e.defineGetter,m=e.enqueueMutation,g=e.mixin,v=e.nodesWereAdded,b=e.nodesWereRemoved,y=e.registerWrapper,E=e.snapshotNodeList,S=e.unsafeUnwrap,M=e.unwrap,T=e.wrap,O=e.wrappers,L=/[&\u00A0"]/g,j=/[&\u00A0<>]/g,N=o(["area","base","br","col","command","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"]),_=o(["style","script","xmp","iframe","noembed","noframes","plaintext","noscript"]),C=/MSIE/.test(navigator.userAgent),D=window.HTMLElement,H=window.HTMLTemplateElement;c.prototype=Object.create(h.prototype),g(c.prototype,{get innerHTML(){return a(this)},set innerHTML(e){if(C&&_[this.localName])return void(this.textContent=e);var t=E(this.childNodes);this.invalidateShadowRenderer()?this instanceof O.HTMLTemplateElement?s(this.content,e):s(this,e,this.tagName):!H&&this instanceof O.HTMLTemplateElement?s(this.content,e):S(this).innerHTML=e;var n=E(this.childNodes);m(this,"childList",{addedNodes:n,removedNodes:t}),b(t),v(n,this)},get outerHTML(){return i(this,this.parentNode)},set outerHTML(e){var t=this.parentNode;if(t){t.invalidateShadowRenderer();var n=u(t,e);t.replaceChild(n,this)}},insertAdjacentHTML:function(e,t){var n,r;switch(String(e).toLowerCase()){case"beforebegin":n=this.parentNode,r=this;break;case"afterend":n=this.parentNode,r=this.nextSibling;break;case"afterbegin":n=this,r=this.firstChild;break;case"beforeend":n=this,r=null;break;default:return}var o=u(n,t);n.insertBefore(o,r)},get hidden(){return this.hasAttribute("hidden")},set hidden(e){e?this.setAttribute("hidden",""):this.removeAttribute("hidden")}}),["clientHeight","clientLeft","clientTop","clientWidth","offsetHeight","offsetLeft","offsetTop","offsetWidth","scrollHeight","scrollWidth"].forEach(p),["scrollLeft","scrollTop"].forEach(d),["getBoundingClientRect","getClientRects","scrollIntoView"].forEach(f),y(D,c,document.createElement("b")),e.wrappers.HTMLElement=c,e.getInnerHTML=a,e.setInnerHTML=s}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.unsafeUnwrap,a=e.wrap,s=window.HTMLCanvasElement;t.prototype=Object.create(n.prototype),r(t.prototype,{getContext:function(){var e=i(this).getContext.apply(i(this),arguments);return e&&a(e)}}),o(s,t,document.createElement("canvas")),e.wrappers.HTMLCanvasElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=window.HTMLContentElement;t.prototype=Object.create(n.prototype),r(t.prototype,{constructor:t,get select(){return this.getAttribute("select")},set select(e){this.setAttribute("select",e)},setAttribute:function(e,t){n.prototype.setAttribute.call(this,e,t),"select"===String(e).toLowerCase()&&this.invalidateShadowRenderer(!0)}}),i&&o(i,t),e.wrappers.HTMLContentElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.wrapHTMLCollection,a=e.unwrap,s=window.HTMLFormElement;t.prototype=Object.create(n.prototype),r(t.prototype,{get elements(){return i(a(this).elements)}}),o(s,t,document.createElement("form")),e.wrappers.HTMLFormElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){r.call(this,e)}function n(e,t){if(!(this instanceof n))throw new TypeError("DOM object constructor cannot be called as a function.");var o=i(document.createElement("img"));r.call(this,o),a(o,this),void 0!==e&&(o.width=e),void 0!==t&&(o.height=t)}var r=e.wrappers.HTMLElement,o=e.registerWrapper,i=e.unwrap,a=e.rewrap,s=window.HTMLImageElement;t.prototype=Object.create(r.prototype),o(s,t,document.createElement("img")),n.prototype=t.prototype,e.wrappers.HTMLImageElement=t,e.wrappers.Image=n}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=(e.mixin,e.wrappers.NodeList,e.registerWrapper),o=window.HTMLShadowElement;t.prototype=Object.create(n.prototype),t.prototype.constructor=t,o&&r(o,t),e.wrappers.HTMLShadowElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){if(!e.defaultView)return e;var t=p.get(e);if(!t){for(t=e.implementation.createHTMLDocument("");t.lastChild;)t.removeChild(t.lastChild);p.set(e,t)}return t}function n(e){for(var n,r=t(e.ownerDocument),o=c(r.createDocumentFragment());n=e.firstChild;)o.appendChild(n);return o}function r(e){if(o.call(this,e),!d){var t=n(e);l.set(this,u(t))}}var o=e.wrappers.HTMLElement,i=e.mixin,a=e.registerWrapper,s=e.unsafeUnwrap,c=e.unwrap,u=e.wrap,l=new WeakMap,p=new WeakMap,d=window.HTMLTemplateElement;r.prototype=Object.create(o.prototype),i(r.prototype,{constructor:r,get content(){return d?u(s(this).content):l.get(this)}}),d&&a(d,r),e.wrappers.HTMLTemplateElement=r}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.registerWrapper,o=window.HTMLMediaElement;o&&(t.prototype=Object.create(n.prototype),r(o,t,document.createElement("audio")),e.wrappers.HTMLMediaElement=t)}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){r.call(this,e)}function n(e){if(!(this instanceof n))throw new TypeError("DOM object constructor cannot be called as a function.");var t=i(document.createElement("audio"));r.call(this,t),a(t,this),t.setAttribute("preload","auto"),void 0!==e&&t.setAttribute("src",e)}var r=e.wrappers.HTMLMediaElement,o=e.registerWrapper,i=e.unwrap,a=e.rewrap,s=window.HTMLAudioElement;s&&(t.prototype=Object.create(r.prototype),o(s,t,document.createElement("audio")),n.prototype=t.prototype,e.wrappers.HTMLAudioElement=t,e.wrappers.Audio=n)}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){return e.replace(/\s+/g," ").trim()}function n(e){o.call(this,e)}function r(e,t,n,i){if(!(this instanceof r))throw new TypeError("DOM object constructor cannot be called as a function.");var a=c(document.createElement("option"));o.call(this,a),s(a,this),void 0!==e&&(a.text=e),void 0!==t&&a.setAttribute("value",t),n===!0&&a.setAttribute("selected",""),a.selected=i===!0}var o=e.wrappers.HTMLElement,i=e.mixin,a=e.registerWrapper,s=e.rewrap,c=e.unwrap,u=e.wrap,l=window.HTMLOptionElement;n.prototype=Object.create(o.prototype),i(n.prototype,{get text(){return t(this.textContent)},set text(e){this.textContent=t(String(e))},get form(){return u(c(this).form)}}),a(l,n,document.createElement("option")),r.prototype=n.prototype,e.wrappers.HTMLOptionElement=n,e.wrappers.Option=r}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.unwrap,a=e.wrap,s=window.HTMLSelectElement;t.prototype=Object.create(n.prototype),r(t.prototype,{add:function(e,t){"object"==typeof t&&(t=i(t)),i(this).add(i(e),t)},remove:function(e){return void 0===e?void n.prototype.remove.call(this):("object"==typeof e&&(e=i(e)),void i(this).remove(e))},get form(){return a(i(this).form)}}),o(s,t,document.createElement("select")),e.wrappers.HTMLSelectElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.unwrap,a=e.wrap,s=e.wrapHTMLCollection,c=window.HTMLTableElement;t.prototype=Object.create(n.prototype),r(t.prototype,{get caption(){return a(i(this).caption)},createCaption:function(){return a(i(this).createCaption())},get tHead(){return a(i(this).tHead)},createTHead:function(){return a(i(this).createTHead())},createTFoot:function(){return a(i(this).createTFoot())},get tFoot(){return a(i(this).tFoot)},get tBodies(){return s(i(this).tBodies)},createTBody:function(){return a(i(this).createTBody())},get rows(){return s(i(this).rows)},insertRow:function(e){return a(i(this).insertRow(e))}}),o(c,t,document.createElement("table")),e.wrappers.HTMLTableElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.wrapHTMLCollection,a=e.unwrap,s=e.wrap,c=window.HTMLTableSectionElement;t.prototype=Object.create(n.prototype),r(t.prototype,{constructor:t,get rows(){return i(a(this).rows)},insertRow:function(e){return s(a(this).insertRow(e))}}),o(c,t,document.createElement("thead")),e.wrappers.HTMLTableSectionElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.wrapHTMLCollection,a=e.unwrap,s=e.wrap,c=window.HTMLTableRowElement;t.prototype=Object.create(n.prototype),r(t.prototype,{get cells(){return i(a(this).cells)},insertCell:function(e){return s(a(this).insertCell(e))}}),o(c,t,document.createElement("tr")),e.wrappers.HTMLTableRowElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){switch(e.localName){case"content":return new n(e);case"shadow":return new o(e);case"template":return new i(e)}r.call(this,e)}var n=e.wrappers.HTMLContentElement,r=e.wrappers.HTMLElement,o=e.wrappers.HTMLShadowElement,i=e.wrappers.HTMLTemplateElement,a=(e.mixin,e.registerWrapper),s=window.HTMLUnknownElement;t.prototype=Object.create(r.prototype),a(s,t),e.wrappers.HTMLUnknownElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";var t=e.wrappers.Element,n=e.wrappers.HTMLElement,r=e.registerObject,o=e.defineWrapGetter,i="http://www.w3.org/2000/svg",a=document.createElementNS(i,"title"),s=r(a),c=Object.getPrototypeOf(s.prototype).constructor;if(!("classList"in a)){var u=Object.getOwnPropertyDescriptor(t.prototype,"classList");Object.defineProperty(n.prototype,"classList",u),delete t.prototype.classList}o(c,"ownerSVGElement"),e.wrappers.SVGElement=c}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){d.call(this,e)}var n=e.mixin,r=e.registerWrapper,o=e.unwrap,i=e.wrap,a=window.SVGUseElement,s="http://www.w3.org/2000/svg",c=i(document.createElementNS(s,"g")),u=document.createElementNS(s,"use"),l=c.constructor,p=Object.getPrototypeOf(l.prototype),d=p.constructor;t.prototype=Object.create(p),"instanceRoot"in u&&n(t.prototype,{get instanceRoot(){return i(o(this).instanceRoot)},get animatedInstanceRoot(){return i(o(this).animatedInstanceRoot)}}),r(a,t,u),e.wrappers.SVGUseElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.EventTarget,r=e.mixin,o=e.registerWrapper,i=e.unsafeUnwrap,a=e.wrap,s=window.SVGElementInstance;s&&(t.prototype=Object.create(n.prototype),r(t.prototype,{get correspondingElement(){return a(i(this).correspondingElement)},get correspondingUseElement(){return a(i(this).correspondingUseElement)},get parentNode(){return a(i(this).parentNode)},get childNodes(){throw new Error("Not implemented")},get firstChild(){return a(i(this).firstChild)},get lastChild(){return a(i(this).lastChild)},get previousSibling(){return a(i(this).previousSibling)},get nextSibling(){return a(i(this).nextSibling)}}),o(s,t),e.wrappers.SVGElementInstance=t)}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){o(e,this)}var n=e.mixin,r=e.registerWrapper,o=e.setWrapper,i=e.unsafeUnwrap,a=e.unwrap,s=e.unwrapIfNeeded,c=e.wrap,u=window.CanvasRenderingContext2D;n(t.prototype,{get canvas(){return c(i(this).canvas)},drawImage:function(){arguments[0]=s(arguments[0]),i(this).drawImage.apply(i(this),arguments)},createPattern:function(){return arguments[0]=a(arguments[0]),i(this).createPattern.apply(i(this),arguments)}}),r(u,t,document.createElement("canvas").getContext("2d")),e.wrappers.CanvasRenderingContext2D=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){o(e,this)}var n=e.mixin,r=e.registerWrapper,o=e.setWrapper,i=e.unsafeUnwrap,a=e.unwrapIfNeeded,s=e.wrap,c=window.WebGLRenderingContext;if(c){n(t.prototype,{get canvas(){return s(i(this).canvas)},texImage2D:function(){arguments[5]=a(arguments[5]),i(this).texImage2D.apply(i(this),arguments)},texSubImage2D:function(){arguments[6]=a(arguments[6]),i(this).texSubImage2D.apply(i(this),arguments)}});var u=/WebKit/.test(navigator.userAgent)?{drawingBufferHeight:null,drawingBufferWidth:null}:{};r(c,t,u),e.wrappers.WebGLRenderingContext=t}}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){r(e,this)}var n=e.registerWrapper,r=e.setWrapper,o=e.unsafeUnwrap,i=e.unwrap,a=e.unwrapIfNeeded,s=e.wrap,c=window.Range;t.prototype={get startContainer(){return s(o(this).startContainer)},get endContainer(){return s(o(this).endContainer)},get commonAncestorContainer(){return s(o(this).commonAncestorContainer)},setStart:function(e,t){o(this).setStart(a(e),t)},setEnd:function(e,t){o(this).setEnd(a(e),t)},setStartBefore:function(e){o(this).setStartBefore(a(e))},setStartAfter:function(e){o(this).setStartAfter(a(e))},setEndBefore:function(e){o(this).setEndBefore(a(e))},setEndAfter:function(e){o(this).setEndAfter(a(e))},selectNode:function(e){o(this).selectNode(a(e))},selectNodeContents:function(e){o(this).selectNodeContents(a(e))},compareBoundaryPoints:function(e,t){return o(this).compareBoundaryPoints(e,i(t))},extractContents:function(){return s(o(this).extractContents())},cloneContents:function(){return s(o(this).cloneContents())},insertNode:function(e){o(this).insertNode(a(e))},surroundContents:function(e){o(this).surroundContents(a(e))},cloneRange:function(){return s(o(this).cloneRange())},isPointInRange:function(e,t){return o(this).isPointInRange(a(e),t)},comparePoint:function(e,t){return o(this).comparePoint(a(e),t)},intersectsNode:function(e){return o(this).intersectsNode(a(e))},toString:function(){return o(this).toString()}},c.prototype.createContextualFragment&&(t.prototype.createContextualFragment=function(e){return s(o(this).createContextualFragment(e))}),n(window.Range,t,document.createRange()),e.wrappers.Range=t}(window.ShadowDOMPolyfill),function(e){"use strict";var t=e.GetElementsByInterface,n=e.ParentNodeInterface,r=e.SelectorsInterface,o=e.mixin,i=e.registerObject,a=i(document.createDocumentFragment());o(a.prototype,n),o(a.prototype,r),o(a.prototype,t);var s=i(document.createComment(""));e.wrappers.Comment=s,e.wrappers.DocumentFragment=a}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){var t=p(l(e).ownerDocument.createDocumentFragment());n.call(this,t),c(t,this);var o=e.shadowRoot;f.set(this,o),this.treeScope_=new r(this,a(o||e)),d.set(this,e)}var n=e.wrappers.DocumentFragment,r=e.TreeScope,o=e.elementFromPoint,i=e.getInnerHTML,a=e.getTreeScope,s=e.mixin,c=e.rewrap,u=e.setInnerHTML,l=e.unsafeUnwrap,p=e.unwrap,d=new WeakMap,f=new WeakMap,h=/[ \t\n\r\f]/;t.prototype=Object.create(n.prototype),s(t.prototype,{constructor:t,get innerHTML(){return i(this)},set innerHTML(e){u(this,e),this.invalidateShadowRenderer()},get olderShadowRoot(){return f.get(this)||null},get host(){return d.get(this)||null},invalidateShadowRenderer:function(){return d.get(this).invalidateShadowRenderer()},elementFromPoint:function(e,t){return o(this,this.ownerDocument,e,t)},getElementById:function(e){return h.test(e)?null:this.querySelector('[id="'+e+'"]')}}),e.wrappers.ShadowRoot=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){e.previousSibling_=e.previousSibling,e.nextSibling_=e.nextSibling,e.parentNode_=e.parentNode}function n(n,o,i){var a=x(n),s=x(o),c=i?x(i):null;if(r(o),t(o),i)n.firstChild===i&&(n.firstChild_=i),i.previousSibling_=i.previousSibling;else{n.lastChild_=n.lastChild,n.lastChild===n.firstChild&&(n.firstChild_=n.firstChild);var u=R(a.lastChild);u&&(u.nextSibling_=u.nextSibling)}e.originalInsertBefore.call(a,s,c)}function r(n){var r=x(n),o=r.parentNode;if(o){var i=R(o);t(n),n.previousSibling&&(n.previousSibling.nextSibling_=n),n.nextSibling&&(n.nextSibling.previousSibling_=n),i.lastChild===n&&(i.lastChild_=n),i.firstChild===n&&(i.firstChild_=n),e.originalRemoveChild.call(o,r)}}function o(e){W.set(e,[])}function i(e){var t=W.get(e);return t||W.set(e,t=[]),t}function a(e){for(var t=[],n=0,r=e.firstChild;r;r=r.nextSibling)t[n++]=r;return t}function s(){for(var e=0;ew;w++){var m=R(i[l++]);s.get(m)||r(m)}for(var g=f.addedCount,v=i[l]&&R(i[l]),w=0;g>w;w++){var b=o[u++],y=b.node;n(t,y,v),s.set(y,!0),b.sync(s)}p+=g}for(var d=p;d=0;o--){var i=r[o],a=w(i);if(a){var s=i.olderShadowRoot;s&&(n=h(s));for(var c=0;c=0;l--)u=Object.create(u);["createdCallback","attachedCallback","detachedCallback","attributeChangedCallback"].forEach(function(e){var t=o[e];t&&(u[e]=function(){N(this)instanceof r||T(this),t.apply(N(this),arguments)})});var p={prototype:u};i&&(p["extends"]=i),r.prototype=o,r.prototype.constructor=r,e.constructorTable.set(u,r),e.nativePrototypeTable.set(o,u);x.call(j(this),t,p);return r},b([window.HTMLDocument||window.Document],["registerElement"])}b([window.HTMLBodyElement,window.HTMLDocument||window.Document,window.HTMLHeadElement,window.HTMLHtmlElement],["appendChild","compareDocumentPosition","contains","getElementsByClassName","getElementsByTagName","getElementsByTagNameNS","insertBefore","querySelector","querySelectorAll","removeChild","replaceChild"]),b([window.HTMLBodyElement,window.HTMLHeadElement,window.HTMLHtmlElement],y),b([window.HTMLDocument||window.Document],["adoptNode","importNode","contains","createComment","createDocumentFragment","createElement","createElementNS","createEvent","createEventNS","createRange","createTextNode","elementFromPoint","getElementById","getElementsByName","getSelection"]),E(t.prototype,u),E(t.prototype,p),E(t.prototype,f),E(t.prototype,{get implementation(){var e=C.get(this);return e?e:(e=new a(j(this).implementation),C.set(this,e),e)},get defaultView(){return N(j(this).defaultView)}}),S(window.Document,t,document.implementation.createHTMLDocument("")),window.HTMLDocument&&S(window.HTMLDocument,t),_([window.HTMLBodyElement,window.HTMLDocument||window.Document,window.HTMLHeadElement]),s(a,"createDocumentType"),s(a,"createDocument"),s(a,"createHTMLDocument"),c(a,"hasFeature"),S(window.DOMImplementation,a),b([window.DOMImplementation],["createDocumentType","createDocument","createHTMLDocument","hasFeature"]),e.adoptNodeNoRemove=r,e.wrappers.DOMImplementation=a,e.wrappers.Document=t
+}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.EventTarget,r=e.wrappers.Selection,o=e.mixin,i=e.registerWrapper,a=e.renderAllPending,s=e.unwrap,c=e.unwrapIfNeeded,u=e.wrap,l=window.Window,p=window.getComputedStyle,d=window.getDefaultComputedStyle,f=window.getSelection;t.prototype=Object.create(n.prototype),l.prototype.getComputedStyle=function(e,t){return u(this||window).getComputedStyle(c(e),t)},d&&(l.prototype.getDefaultComputedStyle=function(e,t){return u(this||window).getDefaultComputedStyle(c(e),t)}),l.prototype.getSelection=function(){return u(this||window).getSelection()},delete window.getComputedStyle,delete window.getDefaultComputedStyle,delete window.getSelection,["addEventListener","removeEventListener","dispatchEvent"].forEach(function(e){l.prototype[e]=function(){var t=u(this||window);return t[e].apply(t,arguments)},delete window[e]}),o(t.prototype,{getComputedStyle:function(e,t){return a(),p.call(s(this),c(e),t)},getSelection:function(){return a(),new r(f.call(s(this)))},get document(){return u(s(this).document)}}),d&&(t.prototype.getDefaultComputedStyle=function(e,t){return a(),d.call(s(this),c(e),t)}),i(l,t,window),e.wrappers.Window=t}(window.ShadowDOMPolyfill),function(e){"use strict";var t=e.unwrap,n=window.DataTransfer||window.Clipboard,r=n.prototype.setDragImage;r&&(n.prototype.setDragImage=function(e,n,o){r.call(this,t(e),n,o)})}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){var t;t=e instanceof i?e:new i(e&&o(e)),r(t,this)}var n=e.registerWrapper,r=e.setWrapper,o=e.unwrap,i=window.FormData;i&&(n(i,t,new i),e.wrappers.FormData=t)}(window.ShadowDOMPolyfill),function(e){"use strict";var t=e.unwrapIfNeeded,n=XMLHttpRequest.prototype.send;XMLHttpRequest.prototype.send=function(e){return n.call(this,t(e))}}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){var t=n[e],r=window[t];if(r){var o=document.createElement(e),i=o.constructor;window[t]=i}}var n=(e.isWrapperFor,{a:"HTMLAnchorElement",area:"HTMLAreaElement",audio:"HTMLAudioElement",base:"HTMLBaseElement",body:"HTMLBodyElement",br:"HTMLBRElement",button:"HTMLButtonElement",canvas:"HTMLCanvasElement",caption:"HTMLTableCaptionElement",col:"HTMLTableColElement",content:"HTMLContentElement",data:"HTMLDataElement",datalist:"HTMLDataListElement",del:"HTMLModElement",dir:"HTMLDirectoryElement",div:"HTMLDivElement",dl:"HTMLDListElement",embed:"HTMLEmbedElement",fieldset:"HTMLFieldSetElement",font:"HTMLFontElement",form:"HTMLFormElement",frame:"HTMLFrameElement",frameset:"HTMLFrameSetElement",h1:"HTMLHeadingElement",head:"HTMLHeadElement",hr:"HTMLHRElement",html:"HTMLHtmlElement",iframe:"HTMLIFrameElement",img:"HTMLImageElement",input:"HTMLInputElement",keygen:"HTMLKeygenElement",label:"HTMLLabelElement",legend:"HTMLLegendElement",li:"HTMLLIElement",link:"HTMLLinkElement",map:"HTMLMapElement",marquee:"HTMLMarqueeElement",menu:"HTMLMenuElement",menuitem:"HTMLMenuItemElement",meta:"HTMLMetaElement",meter:"HTMLMeterElement",object:"HTMLObjectElement",ol:"HTMLOListElement",optgroup:"HTMLOptGroupElement",option:"HTMLOptionElement",output:"HTMLOutputElement",p:"HTMLParagraphElement",param:"HTMLParamElement",pre:"HTMLPreElement",progress:"HTMLProgressElement",q:"HTMLQuoteElement",script:"HTMLScriptElement",select:"HTMLSelectElement",shadow:"HTMLShadowElement",source:"HTMLSourceElement",span:"HTMLSpanElement",style:"HTMLStyleElement",table:"HTMLTableElement",tbody:"HTMLTableSectionElement",template:"HTMLTemplateElement",textarea:"HTMLTextAreaElement",thead:"HTMLTableSectionElement",time:"HTMLTimeElement",title:"HTMLTitleElement",tr:"HTMLTableRowElement",track:"HTMLTrackElement",ul:"HTMLUListElement",video:"HTMLVideoElement"});Object.keys(n).forEach(t),Object.getOwnPropertyNames(e.wrappers).forEach(function(t){window[t]=e.wrappers[t]})}(window.ShadowDOMPolyfill);
\ No newline at end of file
diff --git a/example/bower_components/webcomponentsjs/bower.json b/example/bower_components/webcomponentsjs/bower.json
new file mode 100644
index 000000000..4129deb3d
--- /dev/null
+++ b/example/bower_components/webcomponentsjs/bower.json
@@ -0,0 +1,14 @@
+{
+  "name": "webcomponentsjs",
+  "main": "webcomponents.js",
+  "version": "0.5.5",
+  "homepage": "http://webcomponents.org",
+  "authors": [
+    "The Polymer Authors"
+  ],
+  "keywords": [
+    "webcomponents"
+  ],
+  "license": "BSD",
+  "ignore": []
+}
\ No newline at end of file
diff --git a/example/bower_components/webcomponentsjs/package.json b/example/bower_components/webcomponentsjs/package.json
new file mode 100644
index 000000000..52fdd0e78
--- /dev/null
+++ b/example/bower_components/webcomponentsjs/package.json
@@ -0,0 +1,31 @@
+{
+  "name": "webcomponents.js",
+  "version": "0.5.5",
+  "description": "webcomponents.js",
+  "main": "webcomponents.js",
+  "directories": {
+    "test": "tests"
+  },
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/webcomponents/webcomponentsjs.git"
+  },
+  "author": "The Polymer Authors",
+  "license": {
+    "type": "BSD-3-Clause",
+    "url": "http://polymer.github.io/LICENSE.txt"
+  },
+  "bugs": {
+    "url": "https://github.com/webcomponents/webcomponentsjs/issues"
+  },
+  "homepage": "http://webcomponents.org",
+  "devDependencies": {
+    "gulp": "^3.8.8",
+    "gulp-audit": "^1.0.0",
+    "gulp-concat": "^2.4.1",
+    "gulp-header": "^1.1.1",
+    "gulp-uglify": "^1.0.1",
+    "run-sequence": "^1.0.1",
+    "web-component-tester": "*"
+  }
+}
diff --git a/example/bower_components/webcomponentsjs/webcomponents-lite.js b/example/bower_components/webcomponentsjs/webcomponents-lite.js
new file mode 100644
index 000000000..a6e17b560
--- /dev/null
+++ b/example/bower_components/webcomponentsjs/webcomponents-lite.js
@@ -0,0 +1,1728 @@
+/**
+ * @license
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// @version 0.5.5
+window.WebComponents = window.WebComponents || {};
+
+(function(scope) {
+  var flags = scope.flags || {};
+  var file = "webcomponents.js";
+  var script = document.querySelector('script[src*="' + file + '"]');
+  if (!flags.noOpts) {
+    location.search.slice(1).split("&").forEach(function(o) {
+      o = o.split("=");
+      o[0] && (flags[o[0]] = o[1] || true);
+    });
+    if (script) {
+      for (var i = 0, a; a = script.attributes[i]; i++) {
+        if (a.name !== "src") {
+          flags[a.name] = a.value || true;
+        }
+      }
+    }
+    if (flags.log) {
+      var parts = flags.log.split(",");
+      flags.log = {};
+      parts.forEach(function(f) {
+        flags.log[f] = true;
+      });
+    } else {
+      flags.log = {};
+    }
+  }
+  flags.shadow = flags.shadow || flags.shadowdom || flags.polyfill;
+  if (flags.shadow === "native") {
+    flags.shadow = false;
+  } else {
+    flags.shadow = flags.shadow || !HTMLElement.prototype.createShadowRoot;
+  }
+  if (flags.register) {
+    window.CustomElements = window.CustomElements || {
+      flags: {}
+    };
+    window.CustomElements.flags.register = flags.register;
+  }
+  scope.flags = flags;
+})(WebComponents);
+
+(function(global) {
+  var registrationsTable = new WeakMap();
+  var setImmediate;
+  if (/Trident|Edge/.test(navigator.userAgent)) {
+    setImmediate = setTimeout;
+  } else if (window.setImmediate) {
+    setImmediate = window.setImmediate;
+  } else {
+    var setImmediateQueue = [];
+    var sentinel = String(Math.random());
+    window.addEventListener("message", function(e) {
+      if (e.data === sentinel) {
+        var queue = setImmediateQueue;
+        setImmediateQueue = [];
+        queue.forEach(function(func) {
+          func();
+        });
+      }
+    });
+    setImmediate = function(func) {
+      setImmediateQueue.push(func);
+      window.postMessage(sentinel, "*");
+    };
+  }
+  var isScheduled = false;
+  var scheduledObservers = [];
+  function scheduleCallback(observer) {
+    scheduledObservers.push(observer);
+    if (!isScheduled) {
+      isScheduled = true;
+      setImmediate(dispatchCallbacks);
+    }
+  }
+  function wrapIfNeeded(node) {
+    return window.ShadowDOMPolyfill && window.ShadowDOMPolyfill.wrapIfNeeded(node) || node;
+  }
+  function dispatchCallbacks() {
+    isScheduled = false;
+    var observers = scheduledObservers;
+    scheduledObservers = [];
+    observers.sort(function(o1, o2) {
+      return o1.uid_ - o2.uid_;
+    });
+    var anyNonEmpty = false;
+    observers.forEach(function(observer) {
+      var queue = observer.takeRecords();
+      removeTransientObserversFor(observer);
+      if (queue.length) {
+        observer.callback_(queue, observer);
+        anyNonEmpty = true;
+      }
+    });
+    if (anyNonEmpty) dispatchCallbacks();
+  }
+  function removeTransientObserversFor(observer) {
+    observer.nodes_.forEach(function(node) {
+      var registrations = registrationsTable.get(node);
+      if (!registrations) return;
+      registrations.forEach(function(registration) {
+        if (registration.observer === observer) registration.removeTransientObservers();
+      });
+    });
+  }
+  function forEachAncestorAndObserverEnqueueRecord(target, callback) {
+    for (var node = target; node; node = node.parentNode) {
+      var registrations = registrationsTable.get(node);
+      if (registrations) {
+        for (var j = 0; j < registrations.length; j++) {
+          var registration = registrations[j];
+          var options = registration.options;
+          if (node !== target && !options.subtree) continue;
+          var record = callback(options);
+          if (record) registration.enqueue(record);
+        }
+      }
+    }
+  }
+  var uidCounter = 0;
+  function JsMutationObserver(callback) {
+    this.callback_ = callback;
+    this.nodes_ = [];
+    this.records_ = [];
+    this.uid_ = ++uidCounter;
+  }
+  JsMutationObserver.prototype = {
+    observe: function(target, options) {
+      target = wrapIfNeeded(target);
+      if (!options.childList && !options.attributes && !options.characterData || options.attributeOldValue && !options.attributes || options.attributeFilter && options.attributeFilter.length && !options.attributes || options.characterDataOldValue && !options.characterData) {
+        throw new SyntaxError();
+      }
+      var registrations = registrationsTable.get(target);
+      if (!registrations) registrationsTable.set(target, registrations = []);
+      var registration;
+      for (var i = 0; i < registrations.length; i++) {
+        if (registrations[i].observer === this) {
+          registration = registrations[i];
+          registration.removeListeners();
+          registration.options = options;
+          break;
+        }
+      }
+      if (!registration) {
+        registration = new Registration(this, target, options);
+        registrations.push(registration);
+        this.nodes_.push(target);
+      }
+      registration.addListeners();
+    },
+    disconnect: function() {
+      this.nodes_.forEach(function(node) {
+        var registrations = registrationsTable.get(node);
+        for (var i = 0; i < registrations.length; i++) {
+          var registration = registrations[i];
+          if (registration.observer === this) {
+            registration.removeListeners();
+            registrations.splice(i, 1);
+            break;
+          }
+        }
+      }, this);
+      this.records_ = [];
+    },
+    takeRecords: function() {
+      var copyOfRecords = this.records_;
+      this.records_ = [];
+      return copyOfRecords;
+    }
+  };
+  function MutationRecord(type, target) {
+    this.type = type;
+    this.target = target;
+    this.addedNodes = [];
+    this.removedNodes = [];
+    this.previousSibling = null;
+    this.nextSibling = null;
+    this.attributeName = null;
+    this.attributeNamespace = null;
+    this.oldValue = null;
+  }
+  function copyMutationRecord(original) {
+    var record = new MutationRecord(original.type, original.target);
+    record.addedNodes = original.addedNodes.slice();
+    record.removedNodes = original.removedNodes.slice();
+    record.previousSibling = original.previousSibling;
+    record.nextSibling = original.nextSibling;
+    record.attributeName = original.attributeName;
+    record.attributeNamespace = original.attributeNamespace;
+    record.oldValue = original.oldValue;
+    return record;
+  }
+  var currentRecord, recordWithOldValue;
+  function getRecord(type, target) {
+    return currentRecord = new MutationRecord(type, target);
+  }
+  function getRecordWithOldValue(oldValue) {
+    if (recordWithOldValue) return recordWithOldValue;
+    recordWithOldValue = copyMutationRecord(currentRecord);
+    recordWithOldValue.oldValue = oldValue;
+    return recordWithOldValue;
+  }
+  function clearRecords() {
+    currentRecord = recordWithOldValue = undefined;
+  }
+  function recordRepresentsCurrentMutation(record) {
+    return record === recordWithOldValue || record === currentRecord;
+  }
+  function selectRecord(lastRecord, newRecord) {
+    if (lastRecord === newRecord) return lastRecord;
+    if (recordWithOldValue && recordRepresentsCurrentMutation(lastRecord)) return recordWithOldValue;
+    return null;
+  }
+  function Registration(observer, target, options) {
+    this.observer = observer;
+    this.target = target;
+    this.options = options;
+    this.transientObservedNodes = [];
+  }
+  Registration.prototype = {
+    enqueue: function(record) {
+      var records = this.observer.records_;
+      var length = records.length;
+      if (records.length > 0) {
+        var lastRecord = records[length - 1];
+        var recordToReplaceLast = selectRecord(lastRecord, record);
+        if (recordToReplaceLast) {
+          records[length - 1] = recordToReplaceLast;
+          return;
+        }
+      } else {
+        scheduleCallback(this.observer);
+      }
+      records[length] = record;
+    },
+    addListeners: function() {
+      this.addListeners_(this.target);
+    },
+    addListeners_: function(node) {
+      var options = this.options;
+      if (options.attributes) node.addEventListener("DOMAttrModified", this, true);
+      if (options.characterData) node.addEventListener("DOMCharacterDataModified", this, true);
+      if (options.childList) node.addEventListener("DOMNodeInserted", this, true);
+      if (options.childList || options.subtree) node.addEventListener("DOMNodeRemoved", this, true);
+    },
+    removeListeners: function() {
+      this.removeListeners_(this.target);
+    },
+    removeListeners_: function(node) {
+      var options = this.options;
+      if (options.attributes) node.removeEventListener("DOMAttrModified", this, true);
+      if (options.characterData) node.removeEventListener("DOMCharacterDataModified", this, true);
+      if (options.childList) node.removeEventListener("DOMNodeInserted", this, true);
+      if (options.childList || options.subtree) node.removeEventListener("DOMNodeRemoved", this, true);
+    },
+    addTransientObserver: function(node) {
+      if (node === this.target) return;
+      this.addListeners_(node);
+      this.transientObservedNodes.push(node);
+      var registrations = registrationsTable.get(node);
+      if (!registrations) registrationsTable.set(node, registrations = []);
+      registrations.push(this);
+    },
+    removeTransientObservers: function() {
+      var transientObservedNodes = this.transientObservedNodes;
+      this.transientObservedNodes = [];
+      transientObservedNodes.forEach(function(node) {
+        this.removeListeners_(node);
+        var registrations = registrationsTable.get(node);
+        for (var i = 0; i < registrations.length; i++) {
+          if (registrations[i] === this) {
+            registrations.splice(i, 1);
+            break;
+          }
+        }
+      }, this);
+    },
+    handleEvent: function(e) {
+      e.stopImmediatePropagation();
+      switch (e.type) {
+       case "DOMAttrModified":
+        var name = e.attrName;
+        var namespace = e.relatedNode.namespaceURI;
+        var target = e.target;
+        var record = new getRecord("attributes", target);
+        record.attributeName = name;
+        record.attributeNamespace = namespace;
+        var oldValue = e.attrChange === MutationEvent.ADDITION ? null : e.prevValue;
+        forEachAncestorAndObserverEnqueueRecord(target, function(options) {
+          if (!options.attributes) return;
+          if (options.attributeFilter && options.attributeFilter.length && options.attributeFilter.indexOf(name) === -1 && options.attributeFilter.indexOf(namespace) === -1) {
+            return;
+          }
+          if (options.attributeOldValue) return getRecordWithOldValue(oldValue);
+          return record;
+        });
+        break;
+
+       case "DOMCharacterDataModified":
+        var target = e.target;
+        var record = getRecord("characterData", target);
+        var oldValue = e.prevValue;
+        forEachAncestorAndObserverEnqueueRecord(target, function(options) {
+          if (!options.characterData) return;
+          if (options.characterDataOldValue) return getRecordWithOldValue(oldValue);
+          return record;
+        });
+        break;
+
+       case "DOMNodeRemoved":
+        this.addTransientObserver(e.target);
+
+       case "DOMNodeInserted":
+        var changedNode = e.target;
+        var addedNodes, removedNodes;
+        if (e.type === "DOMNodeInserted") {
+          addedNodes = [ changedNode ];
+          removedNodes = [];
+        } else {
+          addedNodes = [];
+          removedNodes = [ changedNode ];
+        }
+        var previousSibling = changedNode.previousSibling;
+        var nextSibling = changedNode.nextSibling;
+        var record = getRecord("childList", e.target.parentNode);
+        record.addedNodes = addedNodes;
+        record.removedNodes = removedNodes;
+        record.previousSibling = previousSibling;
+        record.nextSibling = nextSibling;
+        forEachAncestorAndObserverEnqueueRecord(e.relatedNode, function(options) {
+          if (!options.childList) return;
+          return record;
+        });
+      }
+      clearRecords();
+    }
+  };
+  global.JsMutationObserver = JsMutationObserver;
+  if (!global.MutationObserver) global.MutationObserver = JsMutationObserver;
+})(this);
+
+if (typeof WeakMap === "undefined") {
+  (function() {
+    var defineProperty = Object.defineProperty;
+    var counter = Date.now() % 1e9;
+    var WeakMap = function() {
+      this.name = "__st" + (Math.random() * 1e9 >>> 0) + (counter++ + "__");
+    };
+    WeakMap.prototype = {
+      set: function(key, value) {
+        var entry = key[this.name];
+        if (entry && entry[0] === key) entry[1] = value; else defineProperty(key, this.name, {
+          value: [ key, value ],
+          writable: true
+        });
+        return this;
+      },
+      get: function(key) {
+        var entry;
+        return (entry = key[this.name]) && entry[0] === key ? entry[1] : undefined;
+      },
+      "delete": function(key) {
+        var entry = key[this.name];
+        if (!entry || entry[0] !== key) return false;
+        entry[0] = entry[1] = undefined;
+        return true;
+      },
+      has: function(key) {
+        var entry = key[this.name];
+        if (!entry) return false;
+        return entry[0] === key;
+      }
+    };
+    window.WeakMap = WeakMap;
+  })();
+}
+
+window.HTMLImports = window.HTMLImports || {
+  flags: {}
+};
+
+(function(scope) {
+  var IMPORT_LINK_TYPE = "import";
+  var useNative = Boolean(IMPORT_LINK_TYPE in document.createElement("link"));
+  var hasShadowDOMPolyfill = Boolean(window.ShadowDOMPolyfill);
+  var wrap = function(node) {
+    return hasShadowDOMPolyfill ? ShadowDOMPolyfill.wrapIfNeeded(node) : node;
+  };
+  var rootDocument = wrap(document);
+  var currentScriptDescriptor = {
+    get: function() {
+      var script = HTMLImports.currentScript || document.currentScript || (document.readyState !== "complete" ? document.scripts[document.scripts.length - 1] : null);
+      return wrap(script);
+    },
+    configurable: true
+  };
+  Object.defineProperty(document, "_currentScript", currentScriptDescriptor);
+  Object.defineProperty(rootDocument, "_currentScript", currentScriptDescriptor);
+  var isIE = /Trident|Edge/.test(navigator.userAgent);
+  function whenReady(callback, doc) {
+    doc = doc || rootDocument;
+    whenDocumentReady(function() {
+      watchImportsLoad(callback, doc);
+    }, doc);
+  }
+  var requiredReadyState = isIE ? "complete" : "interactive";
+  var READY_EVENT = "readystatechange";
+  function isDocumentReady(doc) {
+    return doc.readyState === "complete" || doc.readyState === requiredReadyState;
+  }
+  function whenDocumentReady(callback, doc) {
+    if (!isDocumentReady(doc)) {
+      var checkReady = function() {
+        if (doc.readyState === "complete" || doc.readyState === requiredReadyState) {
+          doc.removeEventListener(READY_EVENT, checkReady);
+          whenDocumentReady(callback, doc);
+        }
+      };
+      doc.addEventListener(READY_EVENT, checkReady);
+    } else if (callback) {
+      callback();
+    }
+  }
+  function markTargetLoaded(event) {
+    event.target.__loaded = true;
+  }
+  function watchImportsLoad(callback, doc) {
+    var imports = doc.querySelectorAll("link[rel=import]");
+    var loaded = 0, l = imports.length;
+    function checkDone(d) {
+      if (loaded == l && callback) {
+        callback();
+      }
+    }
+    function loadedImport(e) {
+      markTargetLoaded(e);
+      loaded++;
+      checkDone();
+    }
+    if (l) {
+      for (var i = 0, imp; i < l && (imp = imports[i]); i++) {
+        if (isImportLoaded(imp)) {
+          loadedImport.call(imp, {
+            target: imp
+          });
+        } else {
+          imp.addEventListener("load", loadedImport);
+          imp.addEventListener("error", loadedImport);
+        }
+      }
+    } else {
+      checkDone();
+    }
+  }
+  function isImportLoaded(link) {
+    return useNative ? link.__loaded || link.import && link.import.readyState !== "loading" : link.__importParsed;
+  }
+  if (useNative) {
+    new MutationObserver(function(mxns) {
+      for (var i = 0, l = mxns.length, m; i < l && (m = mxns[i]); i++) {
+        if (m.addedNodes) {
+          handleImports(m.addedNodes);
+        }
+      }
+    }).observe(document.head, {
+      childList: true
+    });
+    function handleImports(nodes) {
+      for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {
+        if (isImport(n)) {
+          handleImport(n);
+        }
+      }
+    }
+    function isImport(element) {
+      return element.localName === "link" && element.rel === "import";
+    }
+    function handleImport(element) {
+      var loaded = element.import;
+      if (loaded) {
+        markTargetLoaded({
+          target: element
+        });
+      } else {
+        element.addEventListener("load", markTargetLoaded);
+        element.addEventListener("error", markTargetLoaded);
+      }
+    }
+    (function() {
+      if (document.readyState === "loading") {
+        var imports = document.querySelectorAll("link[rel=import]");
+        for (var i = 0, l = imports.length, imp; i < l && (imp = imports[i]); i++) {
+          handleImport(imp);
+        }
+      }
+    })();
+  }
+  whenReady(function() {
+    HTMLImports.ready = true;
+    HTMLImports.readyTime = new Date().getTime();
+    var evt = rootDocument.createEvent("CustomEvent");
+    evt.initCustomEvent("HTMLImportsLoaded", true, true, {});
+    rootDocument.dispatchEvent(evt);
+  });
+  scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;
+  scope.useNative = useNative;
+  scope.rootDocument = rootDocument;
+  scope.whenReady = whenReady;
+  scope.isIE = isIE;
+})(HTMLImports);
+
+(function(scope) {
+  var modules = [];
+  var addModule = function(module) {
+    modules.push(module);
+  };
+  var initializeModules = function() {
+    modules.forEach(function(module) {
+      module(scope);
+    });
+  };
+  scope.addModule = addModule;
+  scope.initializeModules = initializeModules;
+})(HTMLImports);
+
+HTMLImports.addModule(function(scope) {
+  var CSS_URL_REGEXP = /(url\()([^)]*)(\))/g;
+  var CSS_IMPORT_REGEXP = /(@import[\s]+(?!url\())([^;]*)(;)/g;
+  var path = {
+    resolveUrlsInStyle: function(style) {
+      var doc = style.ownerDocument;
+      var resolver = doc.createElement("a");
+      style.textContent = this.resolveUrlsInCssText(style.textContent, resolver);
+      return style;
+    },
+    resolveUrlsInCssText: function(cssText, urlObj) {
+      var r = this.replaceUrls(cssText, urlObj, CSS_URL_REGEXP);
+      r = this.replaceUrls(r, urlObj, CSS_IMPORT_REGEXP);
+      return r;
+    },
+    replaceUrls: function(text, urlObj, regexp) {
+      return text.replace(regexp, function(m, pre, url, post) {
+        var urlPath = url.replace(/["']/g, "");
+        urlObj.href = urlPath;
+        urlPath = urlObj.href;
+        return pre + "'" + urlPath + "'" + post;
+      });
+    }
+  };
+  scope.path = path;
+});
+
+HTMLImports.addModule(function(scope) {
+  var xhr = {
+    async: true,
+    ok: function(request) {
+      return request.status >= 200 && request.status < 300 || request.status === 304 || request.status === 0;
+    },
+    load: function(url, next, nextContext) {
+      var request = new XMLHttpRequest();
+      if (scope.flags.debug || scope.flags.bust) {
+        url += "?" + Math.random();
+      }
+      request.open("GET", url, xhr.async);
+      request.addEventListener("readystatechange", function(e) {
+        if (request.readyState === 4) {
+          var locationHeader = request.getResponseHeader("Location");
+          var redirectedUrl = null;
+          if (locationHeader) {
+            var redirectedUrl = locationHeader.substr(0, 1) === "/" ? location.origin + locationHeader : locationHeader;
+          }
+          next.call(nextContext, !xhr.ok(request) && request, request.response || request.responseText, redirectedUrl);
+        }
+      });
+      request.send();
+      return request;
+    },
+    loadDocument: function(url, next, nextContext) {
+      this.load(url, next, nextContext).responseType = "document";
+    }
+  };
+  scope.xhr = xhr;
+});
+
+HTMLImports.addModule(function(scope) {
+  var xhr = scope.xhr;
+  var flags = scope.flags;
+  var Loader = function(onLoad, onComplete) {
+    this.cache = {};
+    this.onload = onLoad;
+    this.oncomplete = onComplete;
+    this.inflight = 0;
+    this.pending = {};
+  };
+  Loader.prototype = {
+    addNodes: function(nodes) {
+      this.inflight += nodes.length;
+      for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {
+        this.require(n);
+      }
+      this.checkDone();
+    },
+    addNode: function(node) {
+      this.inflight++;
+      this.require(node);
+      this.checkDone();
+    },
+    require: function(elt) {
+      var url = elt.src || elt.href;
+      elt.__nodeUrl = url;
+      if (!this.dedupe(url, elt)) {
+        this.fetch(url, elt);
+      }
+    },
+    dedupe: function(url, elt) {
+      if (this.pending[url]) {
+        this.pending[url].push(elt);
+        return true;
+      }
+      var resource;
+      if (this.cache[url]) {
+        this.onload(url, elt, this.cache[url]);
+        this.tail();
+        return true;
+      }
+      this.pending[url] = [ elt ];
+      return false;
+    },
+    fetch: function(url, elt) {
+      flags.load && console.log("fetch", url, elt);
+      if (!url) {
+        setTimeout(function() {
+          this.receive(url, elt, {
+            error: "href must be specified"
+          }, null);
+        }.bind(this), 0);
+      } else if (url.match(/^data:/)) {
+        var pieces = url.split(",");
+        var header = pieces[0];
+        var body = pieces[1];
+        if (header.indexOf(";base64") > -1) {
+          body = atob(body);
+        } else {
+          body = decodeURIComponent(body);
+        }
+        setTimeout(function() {
+          this.receive(url, elt, null, body);
+        }.bind(this), 0);
+      } else {
+        var receiveXhr = function(err, resource, redirectedUrl) {
+          this.receive(url, elt, err, resource, redirectedUrl);
+        }.bind(this);
+        xhr.load(url, receiveXhr);
+      }
+    },
+    receive: function(url, elt, err, resource, redirectedUrl) {
+      this.cache[url] = resource;
+      var $p = this.pending[url];
+      for (var i = 0, l = $p.length, p; i < l && (p = $p[i]); i++) {
+        this.onload(url, p, resource, err, redirectedUrl);
+        this.tail();
+      }
+      this.pending[url] = null;
+    },
+    tail: function() {
+      --this.inflight;
+      this.checkDone();
+    },
+    checkDone: function() {
+      if (!this.inflight) {
+        this.oncomplete();
+      }
+    }
+  };
+  scope.Loader = Loader;
+});
+
+HTMLImports.addModule(function(scope) {
+  var Observer = function(addCallback) {
+    this.addCallback = addCallback;
+    this.mo = new MutationObserver(this.handler.bind(this));
+  };
+  Observer.prototype = {
+    handler: function(mutations) {
+      for (var i = 0, l = mutations.length, m; i < l && (m = mutations[i]); i++) {
+        if (m.type === "childList" && m.addedNodes.length) {
+          this.addedNodes(m.addedNodes);
+        }
+      }
+    },
+    addedNodes: function(nodes) {
+      if (this.addCallback) {
+        this.addCallback(nodes);
+      }
+      for (var i = 0, l = nodes.length, n, loading; i < l && (n = nodes[i]); i++) {
+        if (n.children && n.children.length) {
+          this.addedNodes(n.children);
+        }
+      }
+    },
+    observe: function(root) {
+      this.mo.observe(root, {
+        childList: true,
+        subtree: true
+      });
+    }
+  };
+  scope.Observer = Observer;
+});
+
+HTMLImports.addModule(function(scope) {
+  var path = scope.path;
+  var rootDocument = scope.rootDocument;
+  var flags = scope.flags;
+  var isIE = scope.isIE;
+  var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;
+  var IMPORT_SELECTOR = "link[rel=" + IMPORT_LINK_TYPE + "]";
+  var importParser = {
+    documentSelectors: IMPORT_SELECTOR,
+    importsSelectors: [ IMPORT_SELECTOR, "link[rel=stylesheet]", "style", "script:not([type])", 'script[type="text/javascript"]' ].join(","),
+    map: {
+      link: "parseLink",
+      script: "parseScript",
+      style: "parseStyle"
+    },
+    dynamicElements: [],
+    parseNext: function() {
+      var next = this.nextToParse();
+      if (next) {
+        this.parse(next);
+      }
+    },
+    parse: function(elt) {
+      if (this.isParsed(elt)) {
+        flags.parse && console.log("[%s] is already parsed", elt.localName);
+        return;
+      }
+      var fn = this[this.map[elt.localName]];
+      if (fn) {
+        this.markParsing(elt);
+        fn.call(this, elt);
+      }
+    },
+    parseDynamic: function(elt, quiet) {
+      this.dynamicElements.push(elt);
+      if (!quiet) {
+        this.parseNext();
+      }
+    },
+    markParsing: function(elt) {
+      flags.parse && console.log("parsing", elt);
+      this.parsingElement = elt;
+    },
+    markParsingComplete: function(elt) {
+      elt.__importParsed = true;
+      this.markDynamicParsingComplete(elt);
+      if (elt.__importElement) {
+        elt.__importElement.__importParsed = true;
+        this.markDynamicParsingComplete(elt.__importElement);
+      }
+      this.parsingElement = null;
+      flags.parse && console.log("completed", elt);
+    },
+    markDynamicParsingComplete: function(elt) {
+      var i = this.dynamicElements.indexOf(elt);
+      if (i >= 0) {
+        this.dynamicElements.splice(i, 1);
+      }
+    },
+    parseImport: function(elt) {
+      if (HTMLImports.__importsParsingHook) {
+        HTMLImports.__importsParsingHook(elt);
+      }
+      if (elt.import) {
+        elt.import.__importParsed = true;
+      }
+      this.markParsingComplete(elt);
+      if (elt.__resource && !elt.__error) {
+        elt.dispatchEvent(new CustomEvent("load", {
+          bubbles: false
+        }));
+      } else {
+        elt.dispatchEvent(new CustomEvent("error", {
+          bubbles: false
+        }));
+      }
+      if (elt.__pending) {
+        var fn;
+        while (elt.__pending.length) {
+          fn = elt.__pending.shift();
+          if (fn) {
+            fn({
+              target: elt
+            });
+          }
+        }
+      }
+      this.parseNext();
+    },
+    parseLink: function(linkElt) {
+      if (nodeIsImport(linkElt)) {
+        this.parseImport(linkElt);
+      } else {
+        linkElt.href = linkElt.href;
+        this.parseGeneric(linkElt);
+      }
+    },
+    parseStyle: function(elt) {
+      var src = elt;
+      elt = cloneStyle(elt);
+      elt.__importElement = src;
+      this.parseGeneric(elt);
+    },
+    parseGeneric: function(elt) {
+      this.trackElement(elt);
+      this.addElementToDocument(elt);
+    },
+    rootImportForElement: function(elt) {
+      var n = elt;
+      while (n.ownerDocument.__importLink) {
+        n = n.ownerDocument.__importLink;
+      }
+      return n;
+    },
+    addElementToDocument: function(elt) {
+      var port = this.rootImportForElement(elt.__importElement || elt);
+      port.parentNode.insertBefore(elt, port);
+    },
+    trackElement: function(elt, callback) {
+      var self = this;
+      var done = function(e) {
+        if (callback) {
+          callback(e);
+        }
+        self.markParsingComplete(elt);
+        self.parseNext();
+      };
+      elt.addEventListener("load", done);
+      elt.addEventListener("error", done);
+      if (isIE && elt.localName === "style") {
+        var fakeLoad = false;
+        if (elt.textContent.indexOf("@import") == -1) {
+          fakeLoad = true;
+        } else if (elt.sheet) {
+          fakeLoad = true;
+          var csr = elt.sheet.cssRules;
+          var len = csr ? csr.length : 0;
+          for (var i = 0, r; i < len && (r = csr[i]); i++) {
+            if (r.type === CSSRule.IMPORT_RULE) {
+              fakeLoad = fakeLoad && Boolean(r.styleSheet);
+            }
+          }
+        }
+        if (fakeLoad) {
+          elt.dispatchEvent(new CustomEvent("load", {
+            bubbles: false
+          }));
+        }
+      }
+    },
+    parseScript: function(scriptElt) {
+      var script = document.createElement("script");
+      script.__importElement = scriptElt;
+      script.src = scriptElt.src ? scriptElt.src : generateScriptDataUrl(scriptElt);
+      scope.currentScript = scriptElt;
+      this.trackElement(script, function(e) {
+        script.parentNode.removeChild(script);
+        scope.currentScript = null;
+      });
+      this.addElementToDocument(script);
+    },
+    nextToParse: function() {
+      this._mayParse = [];
+      return !this.parsingElement && (this.nextToParseInDoc(rootDocument) || this.nextToParseDynamic());
+    },
+    nextToParseInDoc: function(doc, link) {
+      if (doc && this._mayParse.indexOf(doc) < 0) {
+        this._mayParse.push(doc);
+        var nodes = doc.querySelectorAll(this.parseSelectorsForNode(doc));
+        for (var i = 0, l = nodes.length, p = 0, n; i < l && (n = nodes[i]); i++) {
+          if (!this.isParsed(n)) {
+            if (this.hasResource(n)) {
+              return nodeIsImport(n) ? this.nextToParseInDoc(n.import, n) : n;
+            } else {
+              return;
+            }
+          }
+        }
+      }
+      return link;
+    },
+    nextToParseDynamic: function() {
+      return this.dynamicElements[0];
+    },
+    parseSelectorsForNode: function(node) {
+      var doc = node.ownerDocument || node;
+      return doc === rootDocument ? this.documentSelectors : this.importsSelectors;
+    },
+    isParsed: function(node) {
+      return node.__importParsed;
+    },
+    needsDynamicParsing: function(elt) {
+      return this.dynamicElements.indexOf(elt) >= 0;
+    },
+    hasResource: function(node) {
+      if (nodeIsImport(node) && node.import === undefined) {
+        return false;
+      }
+      return true;
+    }
+  };
+  function nodeIsImport(elt) {
+    return elt.localName === "link" && elt.rel === IMPORT_LINK_TYPE;
+  }
+  function generateScriptDataUrl(script) {
+    var scriptContent = generateScriptContent(script);
+    return "data:text/javascript;charset=utf-8," + encodeURIComponent(scriptContent);
+  }
+  function generateScriptContent(script) {
+    return script.textContent + generateSourceMapHint(script);
+  }
+  function generateSourceMapHint(script) {
+    var owner = script.ownerDocument;
+    owner.__importedScripts = owner.__importedScripts || 0;
+    var moniker = script.ownerDocument.baseURI;
+    var num = owner.__importedScripts ? "-" + owner.__importedScripts : "";
+    owner.__importedScripts++;
+    return "\n//# sourceURL=" + moniker + num + ".js\n";
+  }
+  function cloneStyle(style) {
+    var clone = style.ownerDocument.createElement("style");
+    clone.textContent = style.textContent;
+    path.resolveUrlsInStyle(clone);
+    return clone;
+  }
+  scope.parser = importParser;
+  scope.IMPORT_SELECTOR = IMPORT_SELECTOR;
+});
+
+HTMLImports.addModule(function(scope) {
+  var flags = scope.flags;
+  var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;
+  var IMPORT_SELECTOR = scope.IMPORT_SELECTOR;
+  var rootDocument = scope.rootDocument;
+  var Loader = scope.Loader;
+  var Observer = scope.Observer;
+  var parser = scope.parser;
+  var importer = {
+    documents: {},
+    documentPreloadSelectors: IMPORT_SELECTOR,
+    importsPreloadSelectors: [ IMPORT_SELECTOR ].join(","),
+    loadNode: function(node) {
+      importLoader.addNode(node);
+    },
+    loadSubtree: function(parent) {
+      var nodes = this.marshalNodes(parent);
+      importLoader.addNodes(nodes);
+    },
+    marshalNodes: function(parent) {
+      return parent.querySelectorAll(this.loadSelectorsForNode(parent));
+    },
+    loadSelectorsForNode: function(node) {
+      var doc = node.ownerDocument || node;
+      return doc === rootDocument ? this.documentPreloadSelectors : this.importsPreloadSelectors;
+    },
+    loaded: function(url, elt, resource, err, redirectedUrl) {
+      flags.load && console.log("loaded", url, elt);
+      elt.__resource = resource;
+      elt.__error = err;
+      if (isImportLink(elt)) {
+        var doc = this.documents[url];
+        if (doc === undefined) {
+          doc = err ? null : makeDocument(resource, redirectedUrl || url);
+          if (doc) {
+            doc.__importLink = elt;
+            this.bootDocument(doc);
+          }
+          this.documents[url] = doc;
+        }
+        elt.import = doc;
+      }
+      parser.parseNext();
+    },
+    bootDocument: function(doc) {
+      this.loadSubtree(doc);
+      this.observer.observe(doc);
+      parser.parseNext();
+    },
+    loadedAll: function() {
+      parser.parseNext();
+    }
+  };
+  var importLoader = new Loader(importer.loaded.bind(importer), importer.loadedAll.bind(importer));
+  importer.observer = new Observer();
+  function isImportLink(elt) {
+    return isLinkRel(elt, IMPORT_LINK_TYPE);
+  }
+  function isLinkRel(elt, rel) {
+    return elt.localName === "link" && elt.getAttribute("rel") === rel;
+  }
+  function hasBaseURIAccessor(doc) {
+    return !!Object.getOwnPropertyDescriptor(doc, "baseURI");
+  }
+  function makeDocument(resource, url) {
+    var doc = document.implementation.createHTMLDocument(IMPORT_LINK_TYPE);
+    doc._URL = url;
+    var base = doc.createElement("base");
+    base.setAttribute("href", url);
+    if (!doc.baseURI && !hasBaseURIAccessor(doc)) {
+      Object.defineProperty(doc, "baseURI", {
+        value: url
+      });
+    }
+    var meta = doc.createElement("meta");
+    meta.setAttribute("charset", "utf-8");
+    doc.head.appendChild(meta);
+    doc.head.appendChild(base);
+    doc.body.innerHTML = resource;
+    if (window.HTMLTemplateElement && HTMLTemplateElement.bootstrap) {
+      HTMLTemplateElement.bootstrap(doc);
+    }
+    return doc;
+  }
+  if (!document.baseURI) {
+    var baseURIDescriptor = {
+      get: function() {
+        var base = document.querySelector("base");
+        return base ? base.href : window.location.href;
+      },
+      configurable: true
+    };
+    Object.defineProperty(document, "baseURI", baseURIDescriptor);
+    Object.defineProperty(rootDocument, "baseURI", baseURIDescriptor);
+  }
+  scope.importer = importer;
+  scope.importLoader = importLoader;
+});
+
+HTMLImports.addModule(function(scope) {
+  var parser = scope.parser;
+  var importer = scope.importer;
+  var dynamic = {
+    added: function(nodes) {
+      var owner, parsed, loading;
+      for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {
+        if (!owner) {
+          owner = n.ownerDocument;
+          parsed = parser.isParsed(owner);
+        }
+        loading = this.shouldLoadNode(n);
+        if (loading) {
+          importer.loadNode(n);
+        }
+        if (this.shouldParseNode(n) && parsed) {
+          parser.parseDynamic(n, loading);
+        }
+      }
+    },
+    shouldLoadNode: function(node) {
+      return node.nodeType === 1 && matches.call(node, importer.loadSelectorsForNode(node));
+    },
+    shouldParseNode: function(node) {
+      return node.nodeType === 1 && matches.call(node, parser.parseSelectorsForNode(node));
+    }
+  };
+  importer.observer.addCallback = dynamic.added.bind(dynamic);
+  var matches = HTMLElement.prototype.matches || HTMLElement.prototype.matchesSelector || HTMLElement.prototype.webkitMatchesSelector || HTMLElement.prototype.mozMatchesSelector || HTMLElement.prototype.msMatchesSelector;
+});
+
+(function(scope) {
+  var initializeModules = scope.initializeModules;
+  var isIE = scope.isIE;
+  if (scope.useNative) {
+    return;
+  }
+  if (isIE && typeof window.CustomEvent !== "function") {
+    window.CustomEvent = function(inType, params) {
+      params = params || {};
+      var e = document.createEvent("CustomEvent");
+      e.initCustomEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable), params.detail);
+      return e;
+    };
+    window.CustomEvent.prototype = window.Event.prototype;
+  }
+  initializeModules();
+  var rootDocument = scope.rootDocument;
+  function bootstrap() {
+    HTMLImports.importer.bootDocument(rootDocument);
+  }
+  if (document.readyState === "complete" || document.readyState === "interactive" && !window.attachEvent) {
+    bootstrap();
+  } else {
+    document.addEventListener("DOMContentLoaded", bootstrap);
+  }
+})(HTMLImports);
+
+window.CustomElements = window.CustomElements || {
+  flags: {}
+};
+
+(function(scope) {
+  var flags = scope.flags;
+  var modules = [];
+  var addModule = function(module) {
+    modules.push(module);
+  };
+  var initializeModules = function() {
+    modules.forEach(function(module) {
+      module(scope);
+    });
+  };
+  scope.addModule = addModule;
+  scope.initializeModules = initializeModules;
+  scope.hasNative = Boolean(document.registerElement);
+  scope.useNative = !flags.register && scope.hasNative && !window.ShadowDOMPolyfill && (!window.HTMLImports || HTMLImports.useNative);
+})(CustomElements);
+
+CustomElements.addModule(function(scope) {
+  var IMPORT_LINK_TYPE = window.HTMLImports ? HTMLImports.IMPORT_LINK_TYPE : "none";
+  function forSubtree(node, cb) {
+    findAllElements(node, function(e) {
+      if (cb(e)) {
+        return true;
+      }
+      forRoots(e, cb);
+    });
+    forRoots(node, cb);
+  }
+  function findAllElements(node, find, data) {
+    var e = node.firstElementChild;
+    if (!e) {
+      e = node.firstChild;
+      while (e && e.nodeType !== Node.ELEMENT_NODE) {
+        e = e.nextSibling;
+      }
+    }
+    while (e) {
+      if (find(e, data) !== true) {
+        findAllElements(e, find, data);
+      }
+      e = e.nextElementSibling;
+    }
+    return null;
+  }
+  function forRoots(node, cb) {
+    var root = node.shadowRoot;
+    while (root) {
+      forSubtree(root, cb);
+      root = root.olderShadowRoot;
+    }
+  }
+  var processingDocuments;
+  function forDocumentTree(doc, cb) {
+    processingDocuments = [];
+    _forDocumentTree(doc, cb);
+    processingDocuments = null;
+  }
+  function _forDocumentTree(doc, cb) {
+    doc = wrap(doc);
+    if (processingDocuments.indexOf(doc) >= 0) {
+      return;
+    }
+    processingDocuments.push(doc);
+    var imports = doc.querySelectorAll("link[rel=" + IMPORT_LINK_TYPE + "]");
+    for (var i = 0, l = imports.length, n; i < l && (n = imports[i]); i++) {
+      if (n.import) {
+        _forDocumentTree(n.import, cb);
+      }
+    }
+    cb(doc);
+  }
+  scope.forDocumentTree = forDocumentTree;
+  scope.forSubtree = forSubtree;
+});
+
+CustomElements.addModule(function(scope) {
+  var flags = scope.flags;
+  var forSubtree = scope.forSubtree;
+  var forDocumentTree = scope.forDocumentTree;
+  function addedNode(node) {
+    return added(node) || addedSubtree(node);
+  }
+  function added(node) {
+    if (scope.upgrade(node)) {
+      return true;
+    }
+    attached(node);
+  }
+  function addedSubtree(node) {
+    forSubtree(node, function(e) {
+      if (added(e)) {
+        return true;
+      }
+    });
+  }
+  function attachedNode(node) {
+    attached(node);
+    if (inDocument(node)) {
+      forSubtree(node, function(e) {
+        attached(e);
+      });
+    }
+  }
+  var hasPolyfillMutations = !window.MutationObserver || window.MutationObserver === window.JsMutationObserver;
+  scope.hasPolyfillMutations = hasPolyfillMutations;
+  var isPendingMutations = false;
+  var pendingMutations = [];
+  function deferMutation(fn) {
+    pendingMutations.push(fn);
+    if (!isPendingMutations) {
+      isPendingMutations = true;
+      setTimeout(takeMutations);
+    }
+  }
+  function takeMutations() {
+    isPendingMutations = false;
+    var $p = pendingMutations;
+    for (var i = 0, l = $p.length, p; i < l && (p = $p[i]); i++) {
+      p();
+    }
+    pendingMutations = [];
+  }
+  function attached(element) {
+    if (hasPolyfillMutations) {
+      deferMutation(function() {
+        _attached(element);
+      });
+    } else {
+      _attached(element);
+    }
+  }
+  function _attached(element) {
+    if (element.__upgraded__ && (element.attachedCallback || element.detachedCallback)) {
+      if (!element.__attached && inDocument(element)) {
+        element.__attached = true;
+        if (element.attachedCallback) {
+          element.attachedCallback();
+        }
+      }
+    }
+  }
+  function detachedNode(node) {
+    detached(node);
+    forSubtree(node, function(e) {
+      detached(e);
+    });
+  }
+  function detached(element) {
+    if (hasPolyfillMutations) {
+      deferMutation(function() {
+        _detached(element);
+      });
+    } else {
+      _detached(element);
+    }
+  }
+  function _detached(element) {
+    if (element.__upgraded__ && (element.attachedCallback || element.detachedCallback)) {
+      if (element.__attached && !inDocument(element)) {
+        element.__attached = false;
+        if (element.detachedCallback) {
+          element.detachedCallback();
+        }
+      }
+    }
+  }
+  function inDocument(element) {
+    var p = element;
+    var doc = wrap(document);
+    while (p) {
+      if (p == doc) {
+        return true;
+      }
+      p = p.parentNode || p.host;
+    }
+  }
+  function watchShadow(node) {
+    if (node.shadowRoot && !node.shadowRoot.__watched) {
+      flags.dom && console.log("watching shadow-root for: ", node.localName);
+      var root = node.shadowRoot;
+      while (root) {
+        observe(root);
+        root = root.olderShadowRoot;
+      }
+    }
+  }
+  function handler(mutations) {
+    if (flags.dom) {
+      var mx = mutations[0];
+      if (mx && mx.type === "childList" && mx.addedNodes) {
+        if (mx.addedNodes) {
+          var d = mx.addedNodes[0];
+          while (d && d !== document && !d.host) {
+            d = d.parentNode;
+          }
+          var u = d && (d.URL || d._URL || d.host && d.host.localName) || "";
+          u = u.split("/?").shift().split("/").pop();
+        }
+      }
+      console.group("mutations (%d) [%s]", mutations.length, u || "");
+    }
+    mutations.forEach(function(mx) {
+      if (mx.type === "childList") {
+        forEach(mx.addedNodes, function(n) {
+          if (!n.localName) {
+            return;
+          }
+          addedNode(n);
+        });
+        forEach(mx.removedNodes, function(n) {
+          if (!n.localName) {
+            return;
+          }
+          detachedNode(n);
+        });
+      }
+    });
+    flags.dom && console.groupEnd();
+  }
+  function takeRecords(node) {
+    node = wrap(node);
+    if (!node) {
+      node = wrap(document);
+    }
+    while (node.parentNode) {
+      node = node.parentNode;
+    }
+    var observer = node.__observer;
+    if (observer) {
+      handler(observer.takeRecords());
+      takeMutations();
+    }
+  }
+  var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);
+  function observe(inRoot) {
+    if (inRoot.__observer) {
+      return;
+    }
+    var observer = new MutationObserver(handler);
+    observer.observe(inRoot, {
+      childList: true,
+      subtree: true
+    });
+    inRoot.__observer = observer;
+  }
+  function upgradeDocument(doc) {
+    doc = wrap(doc);
+    flags.dom && console.group("upgradeDocument: ", doc.baseURI.split("/").pop());
+    addedNode(doc);
+    observe(doc);
+    flags.dom && console.groupEnd();
+  }
+  function upgradeDocumentTree(doc) {
+    forDocumentTree(doc, upgradeDocument);
+  }
+  var originalCreateShadowRoot = Element.prototype.createShadowRoot;
+  if (originalCreateShadowRoot) {
+    Element.prototype.createShadowRoot = function() {
+      var root = originalCreateShadowRoot.call(this);
+      CustomElements.watchShadow(this);
+      return root;
+    };
+  }
+  scope.watchShadow = watchShadow;
+  scope.upgradeDocumentTree = upgradeDocumentTree;
+  scope.upgradeSubtree = addedSubtree;
+  scope.upgradeAll = addedNode;
+  scope.attachedNode = attachedNode;
+  scope.takeRecords = takeRecords;
+});
+
+CustomElements.addModule(function(scope) {
+  var flags = scope.flags;
+  function upgrade(node) {
+    if (!node.__upgraded__ && node.nodeType === Node.ELEMENT_NODE) {
+      var is = node.getAttribute("is");
+      var definition = scope.getRegisteredDefinition(is || node.localName);
+      if (definition) {
+        if (is && definition.tag == node.localName) {
+          return upgradeWithDefinition(node, definition);
+        } else if (!is && !definition.extends) {
+          return upgradeWithDefinition(node, definition);
+        }
+      }
+    }
+  }
+  function upgradeWithDefinition(element, definition) {
+    flags.upgrade && console.group("upgrade:", element.localName);
+    if (definition.is) {
+      element.setAttribute("is", definition.is);
+    }
+    implementPrototype(element, definition);
+    element.__upgraded__ = true;
+    created(element);
+    scope.attachedNode(element);
+    scope.upgradeSubtree(element);
+    flags.upgrade && console.groupEnd();
+    return element;
+  }
+  function implementPrototype(element, definition) {
+    if (Object.__proto__) {
+      element.__proto__ = definition.prototype;
+    } else {
+      customMixin(element, definition.prototype, definition.native);
+      element.__proto__ = definition.prototype;
+    }
+  }
+  function customMixin(inTarget, inSrc, inNative) {
+    var used = {};
+    var p = inSrc;
+    while (p !== inNative && p !== HTMLElement.prototype) {
+      var keys = Object.getOwnPropertyNames(p);
+      for (var i = 0, k; k = keys[i]; i++) {
+        if (!used[k]) {
+          Object.defineProperty(inTarget, k, Object.getOwnPropertyDescriptor(p, k));
+          used[k] = 1;
+        }
+      }
+      p = Object.getPrototypeOf(p);
+    }
+  }
+  function created(element) {
+    if (element.createdCallback) {
+      element.createdCallback();
+    }
+  }
+  scope.upgrade = upgrade;
+  scope.upgradeWithDefinition = upgradeWithDefinition;
+  scope.implementPrototype = implementPrototype;
+});
+
+CustomElements.addModule(function(scope) {
+  var upgradeDocumentTree = scope.upgradeDocumentTree;
+  var upgrade = scope.upgrade;
+  var upgradeWithDefinition = scope.upgradeWithDefinition;
+  var implementPrototype = scope.implementPrototype;
+  var useNative = scope.useNative;
+  function register(name, options) {
+    var definition = options || {};
+    if (!name) {
+      throw new Error("document.registerElement: first argument `name` must not be empty");
+    }
+    if (name.indexOf("-") < 0) {
+      throw new Error("document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '" + String(name) + "'.");
+    }
+    if (isReservedTag(name)) {
+      throw new Error("Failed to execute 'registerElement' on 'Document': Registration failed for type '" + String(name) + "'. The type name is invalid.");
+    }
+    if (getRegisteredDefinition(name)) {
+      throw new Error("DuplicateDefinitionError: a type with name '" + String(name) + "' is already registered");
+    }
+    if (!definition.prototype) {
+      definition.prototype = Object.create(HTMLElement.prototype);
+    }
+    definition.__name = name.toLowerCase();
+    definition.lifecycle = definition.lifecycle || {};
+    definition.ancestry = ancestry(definition.extends);
+    resolveTagName(definition);
+    resolvePrototypeChain(definition);
+    overrideAttributeApi(definition.prototype);
+    registerDefinition(definition.__name, definition);
+    definition.ctor = generateConstructor(definition);
+    definition.ctor.prototype = definition.prototype;
+    definition.prototype.constructor = definition.ctor;
+    if (scope.ready) {
+      upgradeDocumentTree(document);
+    }
+    return definition.ctor;
+  }
+  function overrideAttributeApi(prototype) {
+    if (prototype.setAttribute._polyfilled) {
+      return;
+    }
+    var setAttribute = prototype.setAttribute;
+    prototype.setAttribute = function(name, value) {
+      changeAttribute.call(this, name, value, setAttribute);
+    };
+    var removeAttribute = prototype.removeAttribute;
+    prototype.removeAttribute = function(name) {
+      changeAttribute.call(this, name, null, removeAttribute);
+    };
+    prototype.setAttribute._polyfilled = true;
+  }
+  function changeAttribute(name, value, operation) {
+    name = name.toLowerCase();
+    var oldValue = this.getAttribute(name);
+    operation.apply(this, arguments);
+    var newValue = this.getAttribute(name);
+    if (this.attributeChangedCallback && newValue !== oldValue) {
+      this.attributeChangedCallback(name, oldValue, newValue);
+    }
+  }
+  function isReservedTag(name) {
+    for (var i = 0; i < reservedTagList.length; i++) {
+      if (name === reservedTagList[i]) {
+        return true;
+      }
+    }
+  }
+  var reservedTagList = [ "annotation-xml", "color-profile", "font-face", "font-face-src", "font-face-uri", "font-face-format", "font-face-name", "missing-glyph" ];
+  function ancestry(extnds) {
+    var extendee = getRegisteredDefinition(extnds);
+    if (extendee) {
+      return ancestry(extendee.extends).concat([ extendee ]);
+    }
+    return [];
+  }
+  function resolveTagName(definition) {
+    var baseTag = definition.extends;
+    for (var i = 0, a; a = definition.ancestry[i]; i++) {
+      baseTag = a.is && a.tag;
+    }
+    definition.tag = baseTag || definition.__name;
+    if (baseTag) {
+      definition.is = definition.__name;
+    }
+  }
+  function resolvePrototypeChain(definition) {
+    if (!Object.__proto__) {
+      var nativePrototype = HTMLElement.prototype;
+      if (definition.is) {
+        var inst = document.createElement(definition.tag);
+        var expectedPrototype = Object.getPrototypeOf(inst);
+        if (expectedPrototype === definition.prototype) {
+          nativePrototype = expectedPrototype;
+        }
+      }
+      var proto = definition.prototype, ancestor;
+      while (proto && proto !== nativePrototype) {
+        ancestor = Object.getPrototypeOf(proto);
+        proto.__proto__ = ancestor;
+        proto = ancestor;
+      }
+      definition.native = nativePrototype;
+    }
+  }
+  function instantiate(definition) {
+    return upgradeWithDefinition(domCreateElement(definition.tag), definition);
+  }
+  var registry = {};
+  function getRegisteredDefinition(name) {
+    if (name) {
+      return registry[name.toLowerCase()];
+    }
+  }
+  function registerDefinition(name, definition) {
+    registry[name] = definition;
+  }
+  function generateConstructor(definition) {
+    return function() {
+      return instantiate(definition);
+    };
+  }
+  var HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
+  function createElementNS(namespace, tag, typeExtension) {
+    if (namespace === HTML_NAMESPACE) {
+      return createElement(tag, typeExtension);
+    } else {
+      return domCreateElementNS(namespace, tag);
+    }
+  }
+  function createElement(tag, typeExtension) {
+    var definition = getRegisteredDefinition(typeExtension || tag);
+    if (definition) {
+      if (tag == definition.tag && typeExtension == definition.is) {
+        return new definition.ctor();
+      }
+      if (!typeExtension && !definition.is) {
+        return new definition.ctor();
+      }
+    }
+    var element;
+    if (typeExtension) {
+      element = createElement(tag);
+      element.setAttribute("is", typeExtension);
+      return element;
+    }
+    element = domCreateElement(tag);
+    if (tag.indexOf("-") >= 0) {
+      implementPrototype(element, HTMLElement);
+    }
+    return element;
+  }
+  function cloneNode(deep) {
+    var n = domCloneNode.call(this, deep);
+    upgrade(n);
+    return n;
+  }
+  var domCreateElement = document.createElement.bind(document);
+  var domCreateElementNS = document.createElementNS.bind(document);
+  var domCloneNode = Node.prototype.cloneNode;
+  var isInstance;
+  if (!Object.__proto__ && !useNative) {
+    isInstance = function(obj, ctor) {
+      var p = obj;
+      while (p) {
+        if (p === ctor.prototype) {
+          return true;
+        }
+        p = p.__proto__;
+      }
+      return false;
+    };
+  } else {
+    isInstance = function(obj, base) {
+      return obj instanceof base;
+    };
+  }
+  document.registerElement = register;
+  document.createElement = createElement;
+  document.createElementNS = createElementNS;
+  Node.prototype.cloneNode = cloneNode;
+  scope.registry = registry;
+  scope.instanceof = isInstance;
+  scope.reservedTagList = reservedTagList;
+  scope.getRegisteredDefinition = getRegisteredDefinition;
+  document.register = document.registerElement;
+});
+
+(function(scope) {
+  var useNative = scope.useNative;
+  var initializeModules = scope.initializeModules;
+  var isIE11OrOlder = /Trident/.test(navigator.userAgent);
+  if (useNative) {
+    var nop = function() {};
+    scope.watchShadow = nop;
+    scope.upgrade = nop;
+    scope.upgradeAll = nop;
+    scope.upgradeDocumentTree = nop;
+    scope.upgradeSubtree = nop;
+    scope.takeRecords = nop;
+    scope.instanceof = function(obj, base) {
+      return obj instanceof base;
+    };
+  } else {
+    initializeModules();
+  }
+  var upgradeDocumentTree = scope.upgradeDocumentTree;
+  if (!window.wrap) {
+    if (window.ShadowDOMPolyfill) {
+      window.wrap = ShadowDOMPolyfill.wrapIfNeeded;
+      window.unwrap = ShadowDOMPolyfill.unwrapIfNeeded;
+    } else {
+      window.wrap = window.unwrap = function(node) {
+        return node;
+      };
+    }
+  }
+  function bootstrap() {
+    upgradeDocumentTree(wrap(document));
+    if (window.HTMLImports) {
+      HTMLImports.__importsParsingHook = function(elt) {
+        upgradeDocumentTree(wrap(elt.import));
+      };
+    }
+    CustomElements.ready = true;
+    setTimeout(function() {
+      CustomElements.readyTime = Date.now();
+      if (window.HTMLImports) {
+        CustomElements.elapsed = CustomElements.readyTime - HTMLImports.readyTime;
+      }
+      document.dispatchEvent(new CustomEvent("WebComponentsReady", {
+        bubbles: true
+      }));
+    });
+  }
+  if (isIE11OrOlder && typeof window.CustomEvent !== "function") {
+    window.CustomEvent = function(inType, params) {
+      params = params || {};
+      var e = document.createEvent("CustomEvent");
+      e.initCustomEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable), params.detail);
+      return e;
+    };
+    window.CustomEvent.prototype = window.Event.prototype;
+  }
+  if (document.readyState === "complete" || scope.flags.eager) {
+    bootstrap();
+  } else if (document.readyState === "interactive" && !window.attachEvent && (!window.HTMLImports || window.HTMLImports.ready)) {
+    bootstrap();
+  } else {
+    var loadEvent = window.HTMLImports && !HTMLImports.ready ? "HTMLImportsLoaded" : "DOMContentLoaded";
+    window.addEventListener(loadEvent, bootstrap);
+  }
+})(window.CustomElements);
+
+if (typeof HTMLTemplateElement === "undefined") {
+  (function() {
+    var TEMPLATE_TAG = "template";
+    HTMLTemplateElement = function() {};
+    HTMLTemplateElement.prototype = Object.create(HTMLElement.prototype);
+    HTMLTemplateElement.decorate = function(template) {
+      if (!template.content) {
+        template.content = template.ownerDocument.createDocumentFragment();
+        var child;
+        while (child = template.firstChild) {
+          template.content.appendChild(child);
+        }
+      }
+    };
+    HTMLTemplateElement.bootstrap = function(doc) {
+      var templates = doc.querySelectorAll(TEMPLATE_TAG);
+      for (var i = 0, l = templates.length, t; i < l && (t = templates[i]); i++) {
+        HTMLTemplateElement.decorate(t);
+      }
+    };
+    addEventListener("DOMContentLoaded", function() {
+      HTMLTemplateElement.bootstrap(document);
+    });
+  })();
+}
+
+(function(scope) {
+  var style = document.createElement("style");
+  style.textContent = "" + "body {" + "transition: opacity ease-in 0.2s;" + " } \n" + "body[unresolved] {" + "opacity: 0; display: block; overflow: hidden; position: relative;" + " } \n";
+  var head = document.querySelector("head");
+  head.insertBefore(style, head.firstChild);
+})(window.WebComponents);
\ No newline at end of file
diff --git a/example/bower_components/webcomponentsjs/webcomponents-lite.min.js b/example/bower_components/webcomponentsjs/webcomponents-lite.min.js
new file mode 100644
index 000000000..db80a800e
--- /dev/null
+++ b/example/bower_components/webcomponentsjs/webcomponents-lite.min.js
@@ -0,0 +1,11 @@
+/**
+ * @license
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// @version 0.5.5
+window.WebComponents=window.WebComponents||{},function(e){var t=e.flags||{},n="webcomponents.js",o=document.querySelector('script[src*="'+n+'"]');if(!t.noOpts){if(location.search.slice(1).split("&").forEach(function(e){e=e.split("="),e[0]&&(t[e[0]]=e[1]||!0)}),o)for(var r,i=0;r=o.attributes[i];i++)"src"!==r.name&&(t[r.name]=r.value||!0);if(t.log){var a=t.log.split(",");t.log={},a.forEach(function(e){t.log[e]=!0})}else t.log={}}t.shadow=t.shadow||t.shadowdom||t.polyfill,t.shadow="native"===t.shadow?!1:t.shadow||!HTMLElement.prototype.createShadowRoot,t.register&&(window.CustomElements=window.CustomElements||{flags:{}},window.CustomElements.flags.register=t.register),e.flags=t}(WebComponents),function(e){function t(e){_.push(e),w||(w=!0,h(o))}function n(e){return window.ShadowDOMPolyfill&&window.ShadowDOMPolyfill.wrapIfNeeded(e)||e}function o(){w=!1;var e=_;_=[],e.sort(function(e,t){return e.uid_-t.uid_});var t=!1;e.forEach(function(e){var n=e.takeRecords();r(e),n.length&&(e.callback_(n,e),t=!0)}),t&&o()}function r(e){e.nodes_.forEach(function(t){var n=v.get(t);n&&n.forEach(function(t){t.observer===e&&t.removeTransientObservers()})})}function i(e,t){for(var n=e;n;n=n.parentNode){var o=v.get(n);if(o)for(var r=0;r0){var r=n[o-1],i=m(r,e);if(i)return void(n[o-1]=i)}else t(this.observer);n[o]=e},addListeners:function(){this.addListeners_(this.target)},addListeners_:function(e){var t=this.options;t.attributes&&e.addEventListener("DOMAttrModified",this,!0),t.characterData&&e.addEventListener("DOMCharacterDataModified",this,!0),t.childList&&e.addEventListener("DOMNodeInserted",this,!0),(t.childList||t.subtree)&&e.addEventListener("DOMNodeRemoved",this,!0)},removeListeners:function(){this.removeListeners_(this.target)},removeListeners_:function(e){var t=this.options;t.attributes&&e.removeEventListener("DOMAttrModified",this,!0),t.characterData&&e.removeEventListener("DOMCharacterDataModified",this,!0),t.childList&&e.removeEventListener("DOMNodeInserted",this,!0),(t.childList||t.subtree)&&e.removeEventListener("DOMNodeRemoved",this,!0)},addTransientObserver:function(e){if(e!==this.target){this.addListeners_(e),this.transientObservedNodes.push(e);var t=v.get(e);t||v.set(e,t=[]),t.push(this)}},removeTransientObservers:function(){var e=this.transientObservedNodes;this.transientObservedNodes=[],e.forEach(function(e){this.removeListeners_(e);for(var t=v.get(e),n=0;n>>0)+(t++ +"__")};n.prototype={set:function(t,n){var o=t[this.name];return o&&o[0]===t?o[1]=n:e(t,this.name,{value:[t,n],writable:!0}),this},get:function(e){var t;return(t=e[this.name])&&t[0]===e?t[1]:void 0},"delete":function(e){var t=e[this.name];return t&&t[0]===e?(t[0]=t[1]=void 0,!0):!1},has:function(e){var t=e[this.name];return t?t[0]===e:!1}},window.WeakMap=n}(),window.HTMLImports=window.HTMLImports||{flags:{}},function(e){function t(e,t){t=t||p,o(function(){i(e,t)},t)}function n(e){return"complete"===e.readyState||e.readyState===g}function o(e,t){if(n(t))e&&e();else{var r=function(){("complete"===t.readyState||t.readyState===g)&&(t.removeEventListener(b,r),o(e,t))};t.addEventListener(b,r)}}function r(e){e.target.__loaded=!0}function i(e,t){function n(){s==d&&e&&e()}function o(e){r(e),s++,n()}var i=t.querySelectorAll("link[rel=import]"),s=0,d=i.length;if(d)for(var c,u=0;d>u&&(c=i[u]);u++)a(c)?o.call(c,{target:c}):(c.addEventListener("load",o),c.addEventListener("error",o));else n()}function a(e){return l?e.__loaded||e["import"]&&"loading"!==e["import"].readyState:e.__importParsed}function s(e){for(var t,n=0,o=e.length;o>n&&(t=e[n]);n++)d(t)&&c(t)}function d(e){return"link"===e.localName&&"import"===e.rel}function c(e){var t=e["import"];t?r({target:e}):(e.addEventListener("load",r),e.addEventListener("error",r))}var u="import",l=Boolean(u in document.createElement("link")),f=Boolean(window.ShadowDOMPolyfill),m=function(e){return f?ShadowDOMPolyfill.wrapIfNeeded(e):e},p=m(document),h={get:function(){var e=HTMLImports.currentScript||document.currentScript||("complete"!==document.readyState?document.scripts[document.scripts.length-1]:null);return m(e)},configurable:!0};Object.defineProperty(document,"_currentScript",h),Object.defineProperty(p,"_currentScript",h);var v=/Trident|Edge/.test(navigator.userAgent),g=v?"complete":"interactive",b="readystatechange";l&&(new MutationObserver(function(e){for(var t,n=0,o=e.length;o>n&&(t=e[n]);n++)t.addedNodes&&s(t.addedNodes)}).observe(document.head,{childList:!0}),function(){if("loading"===document.readyState)for(var e,t=document.querySelectorAll("link[rel=import]"),n=0,o=t.length;o>n&&(e=t[n]);n++)c(e)}()),t(function(){HTMLImports.ready=!0,HTMLImports.readyTime=(new Date).getTime();var e=p.createEvent("CustomEvent");e.initCustomEvent("HTMLImportsLoaded",!0,!0,{}),p.dispatchEvent(e)}),e.IMPORT_LINK_TYPE=u,e.useNative=l,e.rootDocument=p,e.whenReady=t,e.isIE=v}(HTMLImports),function(e){var t=[],n=function(e){t.push(e)},o=function(){t.forEach(function(t){t(e)})};e.addModule=n,e.initializeModules=o}(HTMLImports),HTMLImports.addModule(function(e){var t=/(url\()([^)]*)(\))/g,n=/(@import[\s]+(?!url\())([^;]*)(;)/g,o={resolveUrlsInStyle:function(e){var t=e.ownerDocument,n=t.createElement("a");return e.textContent=this.resolveUrlsInCssText(e.textContent,n),e},resolveUrlsInCssText:function(e,o){var r=this.replaceUrls(e,o,t);return r=this.replaceUrls(r,o,n)},replaceUrls:function(e,t,n){return e.replace(n,function(e,n,o,r){var i=o.replace(/["']/g,"");return t.href=i,i=t.href,n+"'"+i+"'"+r})}};e.path=o}),HTMLImports.addModule(function(e){var t={async:!0,ok:function(e){return e.status>=200&&e.status<300||304===e.status||0===e.status},load:function(n,o,r){var i=new XMLHttpRequest;return(e.flags.debug||e.flags.bust)&&(n+="?"+Math.random()),i.open("GET",n,t.async),i.addEventListener("readystatechange",function(){if(4===i.readyState){var e=i.getResponseHeader("Location"),n=null;if(e)var n="/"===e.substr(0,1)?location.origin+e:e;o.call(r,!t.ok(i)&&i,i.response||i.responseText,n)}}),i.send(),i},loadDocument:function(e,t,n){this.load(e,t,n).responseType="document"}};e.xhr=t}),HTMLImports.addModule(function(e){var t=e.xhr,n=e.flags,o=function(e,t){this.cache={},this.onload=e,this.oncomplete=t,this.inflight=0,this.pending={}};o.prototype={addNodes:function(e){this.inflight+=e.length;for(var t,n=0,o=e.length;o>n&&(t=e[n]);n++)this.require(t);this.checkDone()},addNode:function(e){this.inflight++,this.require(e),this.checkDone()},require:function(e){var t=e.src||e.href;e.__nodeUrl=t,this.dedupe(t,e)||this.fetch(t,e)},dedupe:function(e,t){if(this.pending[e])return this.pending[e].push(t),!0;return this.cache[e]?(this.onload(e,t,this.cache[e]),this.tail(),!0):(this.pending[e]=[t],!1)},fetch:function(e,o){if(n.load&&console.log("fetch",e,o),e)if(e.match(/^data:/)){var r=e.split(","),i=r[0],a=r[1];a=i.indexOf(";base64")>-1?atob(a):decodeURIComponent(a),setTimeout(function(){this.receive(e,o,null,a)}.bind(this),0)}else{var s=function(t,n,r){this.receive(e,o,t,n,r)}.bind(this);t.load(e,s)}else setTimeout(function(){this.receive(e,o,{error:"href must be specified"},null)}.bind(this),0)},receive:function(e,t,n,o,r){this.cache[e]=o;for(var i,a=this.pending[e],s=0,d=a.length;d>s&&(i=a[s]);s++)this.onload(e,i,o,n,r),this.tail();this.pending[e]=null},tail:function(){--this.inflight,this.checkDone()},checkDone:function(){this.inflight||this.oncomplete()}},e.Loader=o}),HTMLImports.addModule(function(e){var t=function(e){this.addCallback=e,this.mo=new MutationObserver(this.handler.bind(this))};t.prototype={handler:function(e){for(var t,n=0,o=e.length;o>n&&(t=e[n]);n++)"childList"===t.type&&t.addedNodes.length&&this.addedNodes(t.addedNodes)},addedNodes:function(e){this.addCallback&&this.addCallback(e);for(var t,n=0,o=e.length;o>n&&(t=e[n]);n++)t.children&&t.children.length&&this.addedNodes(t.children)},observe:function(e){this.mo.observe(e,{childList:!0,subtree:!0})}},e.Observer=t}),HTMLImports.addModule(function(e){function t(e){return"link"===e.localName&&e.rel===u}function n(e){var t=o(e);return"data:text/javascript;charset=utf-8,"+encodeURIComponent(t)}function o(e){return e.textContent+r(e)}function r(e){var t=e.ownerDocument;t.__importedScripts=t.__importedScripts||0;var n=e.ownerDocument.baseURI,o=t.__importedScripts?"-"+t.__importedScripts:"";return t.__importedScripts++,"\n//# sourceURL="+n+o+".js\n"}function i(e){var t=e.ownerDocument.createElement("style");return t.textContent=e.textContent,a.resolveUrlsInStyle(t),t}var a=e.path,s=e.rootDocument,d=e.flags,c=e.isIE,u=e.IMPORT_LINK_TYPE,l="link[rel="+u+"]",f={documentSelectors:l,importsSelectors:[l,"link[rel=stylesheet]","style","script:not([type])",'script[type="text/javascript"]'].join(","),map:{link:"parseLink",script:"parseScript",style:"parseStyle"},dynamicElements:[],parseNext:function(){var e=this.nextToParse();e&&this.parse(e)},parse:function(e){if(this.isParsed(e))return void(d.parse&&console.log("[%s] is already parsed",e.localName));var t=this[this.map[e.localName]];t&&(this.markParsing(e),t.call(this,e))},parseDynamic:function(e,t){this.dynamicElements.push(e),t||this.parseNext()},markParsing:function(e){d.parse&&console.log("parsing",e),this.parsingElement=e},markParsingComplete:function(e){e.__importParsed=!0,this.markDynamicParsingComplete(e),e.__importElement&&(e.__importElement.__importParsed=!0,this.markDynamicParsingComplete(e.__importElement)),this.parsingElement=null,d.parse&&console.log("completed",e)},markDynamicParsingComplete:function(e){var t=this.dynamicElements.indexOf(e);t>=0&&this.dynamicElements.splice(t,1)},parseImport:function(e){if(HTMLImports.__importsParsingHook&&HTMLImports.__importsParsingHook(e),e["import"]&&(e["import"].__importParsed=!0),this.markParsingComplete(e),e.dispatchEvent(e.__resource&&!e.__error?new CustomEvent("load",{bubbles:!1}):new CustomEvent("error",{bubbles:!1})),e.__pending)for(var t;e.__pending.length;)t=e.__pending.shift(),t&&t({target:e});this.parseNext()},parseLink:function(e){t(e)?this.parseImport(e):(e.href=e.href,this.parseGeneric(e))},parseStyle:function(e){var t=e;e=i(e),e.__importElement=t,this.parseGeneric(e)},parseGeneric:function(e){this.trackElement(e),this.addElementToDocument(e)},rootImportForElement:function(e){for(var t=e;t.ownerDocument.__importLink;)t=t.ownerDocument.__importLink;return t},addElementToDocument:function(e){var t=this.rootImportForElement(e.__importElement||e);t.parentNode.insertBefore(e,t)},trackElement:function(e,t){var n=this,o=function(o){t&&t(o),n.markParsingComplete(e),n.parseNext()};if(e.addEventListener("load",o),e.addEventListener("error",o),c&&"style"===e.localName){var r=!1;if(-1==e.textContent.indexOf("@import"))r=!0;else if(e.sheet){r=!0;for(var i,a=e.sheet.cssRules,s=a?a.length:0,d=0;s>d&&(i=a[d]);d++)i.type===CSSRule.IMPORT_RULE&&(r=r&&Boolean(i.styleSheet))}r&&e.dispatchEvent(new CustomEvent("load",{bubbles:!1}))}},parseScript:function(t){var o=document.createElement("script");o.__importElement=t,o.src=t.src?t.src:n(t),e.currentScript=t,this.trackElement(o,function(){o.parentNode.removeChild(o),e.currentScript=null}),this.addElementToDocument(o)},nextToParse:function(){return this._mayParse=[],!this.parsingElement&&(this.nextToParseInDoc(s)||this.nextToParseDynamic())},nextToParseInDoc:function(e,n){if(e&&this._mayParse.indexOf(e)<0){this._mayParse.push(e);for(var o,r=e.querySelectorAll(this.parseSelectorsForNode(e)),i=0,a=r.length;a>i&&(o=r[i]);i++)if(!this.isParsed(o))return this.hasResource(o)?t(o)?this.nextToParseInDoc(o["import"],o):o:void 0}return n},nextToParseDynamic:function(){return this.dynamicElements[0]},parseSelectorsForNode:function(e){var t=e.ownerDocument||e;return t===s?this.documentSelectors:this.importsSelectors},isParsed:function(e){return e.__importParsed},needsDynamicParsing:function(e){return this.dynamicElements.indexOf(e)>=0},hasResource:function(e){return t(e)&&void 0===e["import"]?!1:!0}};e.parser=f,e.IMPORT_SELECTOR=l}),HTMLImports.addModule(function(e){function t(e){return n(e,a)}function n(e,t){return"link"===e.localName&&e.getAttribute("rel")===t}function o(e){return!!Object.getOwnPropertyDescriptor(e,"baseURI")}function r(e,t){var n=document.implementation.createHTMLDocument(a);n._URL=t;var r=n.createElement("base");r.setAttribute("href",t),n.baseURI||o(n)||Object.defineProperty(n,"baseURI",{value:t});var i=n.createElement("meta");return i.setAttribute("charset","utf-8"),n.head.appendChild(i),n.head.appendChild(r),n.body.innerHTML=e,window.HTMLTemplateElement&&HTMLTemplateElement.bootstrap&&HTMLTemplateElement.bootstrap(n),n}var i=e.flags,a=e.IMPORT_LINK_TYPE,s=e.IMPORT_SELECTOR,d=e.rootDocument,c=e.Loader,u=e.Observer,l=e.parser,f={documents:{},documentPreloadSelectors:s,importsPreloadSelectors:[s].join(","),loadNode:function(e){m.addNode(e)},loadSubtree:function(e){var t=this.marshalNodes(e);m.addNodes(t)},marshalNodes:function(e){return e.querySelectorAll(this.loadSelectorsForNode(e))},loadSelectorsForNode:function(e){var t=e.ownerDocument||e;return t===d?this.documentPreloadSelectors:this.importsPreloadSelectors},loaded:function(e,n,o,a,s){if(i.load&&console.log("loaded",e,n),n.__resource=o,n.__error=a,t(n)){var d=this.documents[e];void 0===d&&(d=a?null:r(o,s||e),d&&(d.__importLink=n,this.bootDocument(d)),this.documents[e]=d),n["import"]=d}l.parseNext()},bootDocument:function(e){this.loadSubtree(e),this.observer.observe(e),l.parseNext()},loadedAll:function(){l.parseNext()}},m=new c(f.loaded.bind(f),f.loadedAll.bind(f));if(f.observer=new u,!document.baseURI){var p={get:function(){var e=document.querySelector("base");return e?e.href:window.location.href},configurable:!0};Object.defineProperty(document,"baseURI",p),Object.defineProperty(d,"baseURI",p)}e.importer=f,e.importLoader=m}),HTMLImports.addModule(function(e){var t=e.parser,n=e.importer,o={added:function(e){for(var o,r,i,a,s=0,d=e.length;d>s&&(a=e[s]);s++)o||(o=a.ownerDocument,r=t.isParsed(o)),i=this.shouldLoadNode(a),i&&n.loadNode(a),this.shouldParseNode(a)&&r&&t.parseDynamic(a,i)},shouldLoadNode:function(e){return 1===e.nodeType&&r.call(e,n.loadSelectorsForNode(e))},shouldParseNode:function(e){return 1===e.nodeType&&r.call(e,t.parseSelectorsForNode(e))}};n.observer.addCallback=o.added.bind(o);var r=HTMLElement.prototype.matches||HTMLElement.prototype.matchesSelector||HTMLElement.prototype.webkitMatchesSelector||HTMLElement.prototype.mozMatchesSelector||HTMLElement.prototype.msMatchesSelector}),function(e){function t(){HTMLImports.importer.bootDocument(r)}var n=e.initializeModules,o=e.isIE;if(!e.useNative){o&&"function"!=typeof window.CustomEvent&&(window.CustomEvent=function(e,t){t=t||{};var n=document.createEvent("CustomEvent");return n.initCustomEvent(e,Boolean(t.bubbles),Boolean(t.cancelable),t.detail),n},window.CustomEvent.prototype=window.Event.prototype),n();var r=e.rootDocument;"complete"===document.readyState||"interactive"===document.readyState&&!window.attachEvent?t():document.addEventListener("DOMContentLoaded",t)}}(HTMLImports),window.CustomElements=window.CustomElements||{flags:{}},function(e){var t=e.flags,n=[],o=function(e){n.push(e)},r=function(){n.forEach(function(t){t(e)})};e.addModule=o,e.initializeModules=r,e.hasNative=Boolean(document.registerElement),e.useNative=!t.register&&e.hasNative&&!window.ShadowDOMPolyfill&&(!window.HTMLImports||HTMLImports.useNative)}(CustomElements),CustomElements.addModule(function(e){function t(e,t){n(e,function(e){return t(e)?!0:void o(e,t)}),o(e,t)}function n(e,t,o){var r=e.firstElementChild;if(!r)for(r=e.firstChild;r&&r.nodeType!==Node.ELEMENT_NODE;)r=r.nextSibling;for(;r;)t(r,o)!==!0&&n(r,t,o),r=r.nextElementSibling;return null}function o(e,n){for(var o=e.shadowRoot;o;)t(o,n),o=o.olderShadowRoot}function r(e,t){a=[],i(e,t),a=null}function i(e,t){if(e=wrap(e),!(a.indexOf(e)>=0)){a.push(e);for(var n,o=e.querySelectorAll("link[rel="+s+"]"),r=0,d=o.length;d>r&&(n=o[r]);r++)n["import"]&&i(n["import"],t);t(e)}}var a,s=window.HTMLImports?HTMLImports.IMPORT_LINK_TYPE:"none";e.forDocumentTree=r,e.forSubtree=t}),CustomElements.addModule(function(e){function t(e){return n(e)||o(e)}function n(t){return e.upgrade(t)?!0:void s(t)}function o(e){_(e,function(e){return n(e)?!0:void 0})}function r(e){s(e),f(e)&&_(e,function(e){s(e)})}function i(e){M.push(e),L||(L=!0,setTimeout(a))}function a(){L=!1;for(var e,t=M,n=0,o=t.length;o>n&&(e=t[n]);n++)e();M=[]}function s(e){y?i(function(){d(e)}):d(e)}function d(e){e.__upgraded__&&(e.attachedCallback||e.detachedCallback)&&!e.__attached&&f(e)&&(e.__attached=!0,e.attachedCallback&&e.attachedCallback())}function c(e){u(e),_(e,function(e){u(e)})}function u(e){y?i(function(){l(e)}):l(e)}function l(e){e.__upgraded__&&(e.attachedCallback||e.detachedCallback)&&e.__attached&&!f(e)&&(e.__attached=!1,e.detachedCallback&&e.detachedCallback())}function f(e){for(var t=e,n=wrap(document);t;){if(t==n)return!0;t=t.parentNode||t.host}}function m(e){if(e.shadowRoot&&!e.shadowRoot.__watched){w.dom&&console.log("watching shadow-root for: ",e.localName);for(var t=e.shadowRoot;t;)v(t),t=t.olderShadowRoot}}function p(e){if(w.dom){var n=e[0];if(n&&"childList"===n.type&&n.addedNodes&&n.addedNodes){for(var o=n.addedNodes[0];o&&o!==document&&!o.host;)o=o.parentNode;var r=o&&(o.URL||o._URL||o.host&&o.host.localName)||"";r=r.split("/?").shift().split("/").pop()}console.group("mutations (%d) [%s]",e.length,r||"")}e.forEach(function(e){"childList"===e.type&&(T(e.addedNodes,function(e){e.localName&&t(e)}),T(e.removedNodes,function(e){e.localName&&c(e)}))}),w.dom&&console.groupEnd()}function h(e){for(e=wrap(e),e||(e=wrap(document));e.parentNode;)e=e.parentNode;var t=e.__observer;t&&(p(t.takeRecords()),a())}function v(e){if(!e.__observer){var t=new MutationObserver(p);t.observe(e,{childList:!0,subtree:!0}),e.__observer=t}}function g(e){e=wrap(e),w.dom&&console.group("upgradeDocument: ",e.baseURI.split("/").pop()),t(e),v(e),w.dom&&console.groupEnd()}function b(e){E(e,g)}var w=e.flags,_=e.forSubtree,E=e.forDocumentTree,y=!window.MutationObserver||window.MutationObserver===window.JsMutationObserver;e.hasPolyfillMutations=y;var L=!1,M=[],T=Array.prototype.forEach.call.bind(Array.prototype.forEach),N=Element.prototype.createShadowRoot;N&&(Element.prototype.createShadowRoot=function(){var e=N.call(this);return CustomElements.watchShadow(this),e}),e.watchShadow=m,e.upgradeDocumentTree=b,e.upgradeSubtree=o,e.upgradeAll=t,e.attachedNode=r,e.takeRecords=h}),CustomElements.addModule(function(e){function t(t){if(!t.__upgraded__&&t.nodeType===Node.ELEMENT_NODE){var o=t.getAttribute("is"),r=e.getRegisteredDefinition(o||t.localName);if(r){if(o&&r.tag==t.localName)return n(t,r);if(!o&&!r["extends"])return n(t,r)}}}function n(t,n){return a.upgrade&&console.group("upgrade:",t.localName),n.is&&t.setAttribute("is",n.is),o(t,n),t.__upgraded__=!0,i(t),e.attachedNode(t),e.upgradeSubtree(t),a.upgrade&&console.groupEnd(),t}function o(e,t){Object.__proto__?e.__proto__=t.prototype:(r(e,t.prototype,t["native"]),e.__proto__=t.prototype)}function r(e,t,n){for(var o={},r=t;r!==n&&r!==HTMLElement.prototype;){for(var i,a=Object.getOwnPropertyNames(r),s=0;i=a[s];s++)o[i]||(Object.defineProperty(e,i,Object.getOwnPropertyDescriptor(r,i)),o[i]=1);r=Object.getPrototypeOf(r)}}function i(e){e.createdCallback&&e.createdCallback()}var a=e.flags;e.upgrade=t,e.upgradeWithDefinition=n,e.implementPrototype=o}),CustomElements.addModule(function(e){function t(t,o){var d=o||{};if(!t)throw new Error("document.registerElement: first argument `name` must not be empty");if(t.indexOf("-")<0)throw new Error("document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '"+String(t)+"'.");if(r(t))throw new Error("Failed to execute 'registerElement' on 'Document': Registration failed for type '"+String(t)+"'. The type name is invalid.");if(c(t))throw new Error("DuplicateDefinitionError: a type with name '"+String(t)+"' is already registered");return d.prototype||(d.prototype=Object.create(HTMLElement.prototype)),d.__name=t.toLowerCase(),d.lifecycle=d.lifecycle||{},d.ancestry=i(d["extends"]),a(d),s(d),n(d.prototype),u(d.__name,d),d.ctor=l(d),d.ctor.prototype=d.prototype,d.prototype.constructor=d.ctor,e.ready&&v(document),d.ctor}function n(e){if(!e.setAttribute._polyfilled){var t=e.setAttribute;e.setAttribute=function(e,n){o.call(this,e,n,t)};var n=e.removeAttribute;e.removeAttribute=function(e){o.call(this,e,null,n)},e.setAttribute._polyfilled=!0}}function o(e,t,n){e=e.toLowerCase();var o=this.getAttribute(e);n.apply(this,arguments);var r=this.getAttribute(e);this.attributeChangedCallback&&r!==o&&this.attributeChangedCallback(e,o,r)}function r(e){for(var t=0;t=0&&w(o,HTMLElement),o)}function p(e){var t=N.call(this,e);return g(t),t}var h,v=e.upgradeDocumentTree,g=e.upgrade,b=e.upgradeWithDefinition,w=e.implementPrototype,_=e.useNative,E=["annotation-xml","color-profile","font-face","font-face-src","font-face-uri","font-face-format","font-face-name","missing-glyph"],y={},L="http://www.w3.org/1999/xhtml",M=document.createElement.bind(document),T=document.createElementNS.bind(document),N=Node.prototype.cloneNode;h=Object.__proto__||_?function(e,t){return e instanceof t}:function(e,t){for(var n=e;n;){if(n===t.prototype)return!0;n=n.__proto__}return!1},document.registerElement=t,document.createElement=m,document.createElementNS=f,Node.prototype.cloneNode=p,e.registry=y,e["instanceof"]=h,e.reservedTagList=E,e.getRegisteredDefinition=c,document.register=document.registerElement}),function(e){function t(){a(wrap(document)),window.HTMLImports&&(HTMLImports.__importsParsingHook=function(e){a(wrap(e["import"]))}),CustomElements.ready=!0,setTimeout(function(){CustomElements.readyTime=Date.now(),window.HTMLImports&&(CustomElements.elapsed=CustomElements.readyTime-HTMLImports.readyTime),document.dispatchEvent(new CustomEvent("WebComponentsReady",{bubbles:!0}))})}var n=e.useNative,o=e.initializeModules,r=/Trident/.test(navigator.userAgent);if(n){var i=function(){};e.watchShadow=i,e.upgrade=i,e.upgradeAll=i,e.upgradeDocumentTree=i,e.upgradeSubtree=i,e.takeRecords=i,e["instanceof"]=function(e,t){return e instanceof t}}else o();var a=e.upgradeDocumentTree;if(window.wrap||(window.ShadowDOMPolyfill?(window.wrap=ShadowDOMPolyfill.wrapIfNeeded,window.unwrap=ShadowDOMPolyfill.unwrapIfNeeded):window.wrap=window.unwrap=function(e){return e}),r&&"function"!=typeof window.CustomEvent&&(window.CustomEvent=function(e,t){t=t||{};var n=document.createEvent("CustomEvent");return n.initCustomEvent(e,Boolean(t.bubbles),Boolean(t.cancelable),t.detail),n},window.CustomEvent.prototype=window.Event.prototype),"complete"===document.readyState||e.flags.eager)t();else if("interactive"!==document.readyState||window.attachEvent||window.HTMLImports&&!window.HTMLImports.ready){var s=window.HTMLImports&&!HTMLImports.ready?"HTMLImportsLoaded":"DOMContentLoaded";window.addEventListener(s,t)}else t()}(window.CustomElements),"undefined"==typeof HTMLTemplateElement&&!function(){var e="template";HTMLTemplateElement=function(){},HTMLTemplateElement.prototype=Object.create(HTMLElement.prototype),HTMLTemplateElement.decorate=function(e){if(!e.content){e.content=e.ownerDocument.createDocumentFragment();for(var t;t=e.firstChild;)e.content.appendChild(t)}},HTMLTemplateElement.bootstrap=function(t){for(var n,o=t.querySelectorAll(e),r=0,i=o.length;i>r&&(n=o[r]);r++)HTMLTemplateElement.decorate(n)},addEventListener("DOMContentLoaded",function(){HTMLTemplateElement.bootstrap(document)})}(),function(){var e=document.createElement("style");e.textContent="body {transition: opacity ease-in 0.2s; } \nbody[unresolved] {opacity: 0; display: block; overflow: hidden; position: relative; } \n";var t=document.querySelector("head");t.insertBefore(e,t.firstChild)}(window.WebComponents);
\ No newline at end of file
diff --git a/example/bower_components/webcomponentsjs/webcomponents.js b/example/bower_components/webcomponentsjs/webcomponents.js
new file mode 100644
index 000000000..26f5d5bf6
--- /dev/null
+++ b/example/bower_components/webcomponentsjs/webcomponents.js
@@ -0,0 +1,6114 @@
+/**
+ * @license
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// @version 0.5.5
+window.WebComponents = window.WebComponents || {};
+
+(function(scope) {
+  var flags = scope.flags || {};
+  var file = "webcomponents.js";
+  var script = document.querySelector('script[src*="' + file + '"]');
+  if (!flags.noOpts) {
+    location.search.slice(1).split("&").forEach(function(o) {
+      o = o.split("=");
+      o[0] && (flags[o[0]] = o[1] || true);
+    });
+    if (script) {
+      for (var i = 0, a; a = script.attributes[i]; i++) {
+        if (a.name !== "src") {
+          flags[a.name] = a.value || true;
+        }
+      }
+    }
+    if (flags.log) {
+      var parts = flags.log.split(",");
+      flags.log = {};
+      parts.forEach(function(f) {
+        flags.log[f] = true;
+      });
+    } else {
+      flags.log = {};
+    }
+  }
+  flags.shadow = flags.shadow || flags.shadowdom || flags.polyfill;
+  if (flags.shadow === "native") {
+    flags.shadow = false;
+  } else {
+    flags.shadow = flags.shadow || !HTMLElement.prototype.createShadowRoot;
+  }
+  if (flags.register) {
+    window.CustomElements = window.CustomElements || {
+      flags: {}
+    };
+    window.CustomElements.flags.register = flags.register;
+  }
+  scope.flags = flags;
+})(WebComponents);
+
+if (WebComponents.flags.shadow) {
+  if (typeof WeakMap === "undefined") {
+    (function() {
+      var defineProperty = Object.defineProperty;
+      var counter = Date.now() % 1e9;
+      var WeakMap = function() {
+        this.name = "__st" + (Math.random() * 1e9 >>> 0) + (counter++ + "__");
+      };
+      WeakMap.prototype = {
+        set: function(key, value) {
+          var entry = key[this.name];
+          if (entry && entry[0] === key) entry[1] = value; else defineProperty(key, this.name, {
+            value: [ key, value ],
+            writable: true
+          });
+          return this;
+        },
+        get: function(key) {
+          var entry;
+          return (entry = key[this.name]) && entry[0] === key ? entry[1] : undefined;
+        },
+        "delete": function(key) {
+          var entry = key[this.name];
+          if (!entry || entry[0] !== key) return false;
+          entry[0] = entry[1] = undefined;
+          return true;
+        },
+        has: function(key) {
+          var entry = key[this.name];
+          if (!entry) return false;
+          return entry[0] === key;
+        }
+      };
+      window.WeakMap = WeakMap;
+    })();
+  }
+  window.ShadowDOMPolyfill = {};
+  (function(scope) {
+    "use strict";
+    var constructorTable = new WeakMap();
+    var nativePrototypeTable = new WeakMap();
+    var wrappers = Object.create(null);
+    function detectEval() {
+      if (typeof chrome !== "undefined" && chrome.app && chrome.app.runtime) {
+        return false;
+      }
+      if (navigator.getDeviceStorage) {
+        return false;
+      }
+      try {
+        var f = new Function("return true;");
+        return f();
+      } catch (ex) {
+        return false;
+      }
+    }
+    var hasEval = detectEval();
+    function assert(b) {
+      if (!b) throw new Error("Assertion failed");
+    }
+    var defineProperty = Object.defineProperty;
+    var getOwnPropertyNames = Object.getOwnPropertyNames;
+    var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
+    function mixin(to, from) {
+      var names = getOwnPropertyNames(from);
+      for (var i = 0; i < names.length; i++) {
+        var name = names[i];
+        defineProperty(to, name, getOwnPropertyDescriptor(from, name));
+      }
+      return to;
+    }
+    function mixinStatics(to, from) {
+      var names = getOwnPropertyNames(from);
+      for (var i = 0; i < names.length; i++) {
+        var name = names[i];
+        switch (name) {
+         case "arguments":
+         case "caller":
+         case "length":
+         case "name":
+         case "prototype":
+         case "toString":
+          continue;
+        }
+        defineProperty(to, name, getOwnPropertyDescriptor(from, name));
+      }
+      return to;
+    }
+    function oneOf(object, propertyNames) {
+      for (var i = 0; i < propertyNames.length; i++) {
+        if (propertyNames[i] in object) return propertyNames[i];
+      }
+    }
+    var nonEnumerableDataDescriptor = {
+      value: undefined,
+      configurable: true,
+      enumerable: false,
+      writable: true
+    };
+    function defineNonEnumerableDataProperty(object, name, value) {
+      nonEnumerableDataDescriptor.value = value;
+      defineProperty(object, name, nonEnumerableDataDescriptor);
+    }
+    getOwnPropertyNames(window);
+    function getWrapperConstructor(node) {
+      var nativePrototype = node.__proto__ || Object.getPrototypeOf(node);
+      if (isFirefox) {
+        try {
+          getOwnPropertyNames(nativePrototype);
+        } catch (error) {
+          nativePrototype = nativePrototype.__proto__;
+        }
+      }
+      var wrapperConstructor = constructorTable.get(nativePrototype);
+      if (wrapperConstructor) return wrapperConstructor;
+      var parentWrapperConstructor = getWrapperConstructor(nativePrototype);
+      var GeneratedWrapper = createWrapperConstructor(parentWrapperConstructor);
+      registerInternal(nativePrototype, GeneratedWrapper, node);
+      return GeneratedWrapper;
+    }
+    function addForwardingProperties(nativePrototype, wrapperPrototype) {
+      installProperty(nativePrototype, wrapperPrototype, true);
+    }
+    function registerInstanceProperties(wrapperPrototype, instanceObject) {
+      installProperty(instanceObject, wrapperPrototype, false);
+    }
+    var isFirefox = /Firefox/.test(navigator.userAgent);
+    var dummyDescriptor = {
+      get: function() {},
+      set: function(v) {},
+      configurable: true,
+      enumerable: true
+    };
+    function isEventHandlerName(name) {
+      return /^on[a-z]+$/.test(name);
+    }
+    function isIdentifierName(name) {
+      return /^\w[a-zA-Z_0-9]*$/.test(name);
+    }
+    function getGetter(name) {
+      return hasEval && isIdentifierName(name) ? new Function("return this.__impl4cf1e782hg__." + name) : function() {
+        return this.__impl4cf1e782hg__[name];
+      };
+    }
+    function getSetter(name) {
+      return hasEval && isIdentifierName(name) ? new Function("v", "this.__impl4cf1e782hg__." + name + " = v") : function(v) {
+        this.__impl4cf1e782hg__[name] = v;
+      };
+    }
+    function getMethod(name) {
+      return hasEval && isIdentifierName(name) ? new Function("return this.__impl4cf1e782hg__." + name + ".apply(this.__impl4cf1e782hg__, arguments)") : function() {
+        return this.__impl4cf1e782hg__[name].apply(this.__impl4cf1e782hg__, arguments);
+      };
+    }
+    function getDescriptor(source, name) {
+      try {
+        return Object.getOwnPropertyDescriptor(source, name);
+      } catch (ex) {
+        return dummyDescriptor;
+      }
+    }
+    var isBrokenSafari = function() {
+      var descr = Object.getOwnPropertyDescriptor(Node.prototype, "nodeType");
+      return descr && !descr.get && !descr.set;
+    }();
+    function installProperty(source, target, allowMethod, opt_blacklist) {
+      var names = getOwnPropertyNames(source);
+      for (var i = 0; i < names.length; i++) {
+        var name = names[i];
+        if (name === "polymerBlackList_") continue;
+        if (name in target) continue;
+        if (source.polymerBlackList_ && source.polymerBlackList_[name]) continue;
+        if (isFirefox) {
+          source.__lookupGetter__(name);
+        }
+        var descriptor = getDescriptor(source, name);
+        var getter, setter;
+        if (allowMethod && typeof descriptor.value === "function") {
+          target[name] = getMethod(name);
+          continue;
+        }
+        var isEvent = isEventHandlerName(name);
+        if (isEvent) getter = scope.getEventHandlerGetter(name); else getter = getGetter(name);
+        if (descriptor.writable || descriptor.set || isBrokenSafari) {
+          if (isEvent) setter = scope.getEventHandlerSetter(name); else setter = getSetter(name);
+        }
+        var configurable = isBrokenSafari || descriptor.configurable;
+        defineProperty(target, name, {
+          get: getter,
+          set: setter,
+          configurable: configurable,
+          enumerable: descriptor.enumerable
+        });
+      }
+    }
+    function register(nativeConstructor, wrapperConstructor, opt_instance) {
+      var nativePrototype = nativeConstructor.prototype;
+      registerInternal(nativePrototype, wrapperConstructor, opt_instance);
+      mixinStatics(wrapperConstructor, nativeConstructor);
+    }
+    function registerInternal(nativePrototype, wrapperConstructor, opt_instance) {
+      var wrapperPrototype = wrapperConstructor.prototype;
+      assert(constructorTable.get(nativePrototype) === undefined);
+      constructorTable.set(nativePrototype, wrapperConstructor);
+      nativePrototypeTable.set(wrapperPrototype, nativePrototype);
+      addForwardingProperties(nativePrototype, wrapperPrototype);
+      if (opt_instance) registerInstanceProperties(wrapperPrototype, opt_instance);
+      defineNonEnumerableDataProperty(wrapperPrototype, "constructor", wrapperConstructor);
+      wrapperConstructor.prototype = wrapperPrototype;
+    }
+    function isWrapperFor(wrapperConstructor, nativeConstructor) {
+      return constructorTable.get(nativeConstructor.prototype) === wrapperConstructor;
+    }
+    function registerObject(object) {
+      var nativePrototype = Object.getPrototypeOf(object);
+      var superWrapperConstructor = getWrapperConstructor(nativePrototype);
+      var GeneratedWrapper = createWrapperConstructor(superWrapperConstructor);
+      registerInternal(nativePrototype, GeneratedWrapper, object);
+      return GeneratedWrapper;
+    }
+    function createWrapperConstructor(superWrapperConstructor) {
+      function GeneratedWrapper(node) {
+        superWrapperConstructor.call(this, node);
+      }
+      var p = Object.create(superWrapperConstructor.prototype);
+      p.constructor = GeneratedWrapper;
+      GeneratedWrapper.prototype = p;
+      return GeneratedWrapper;
+    }
+    function isWrapper(object) {
+      return object && object.__impl4cf1e782hg__;
+    }
+    function isNative(object) {
+      return !isWrapper(object);
+    }
+    function wrap(impl) {
+      if (impl === null) return null;
+      assert(isNative(impl));
+      return impl.__wrapper8e3dd93a60__ || (impl.__wrapper8e3dd93a60__ = new (getWrapperConstructor(impl))(impl));
+    }
+    function unwrap(wrapper) {
+      if (wrapper === null) return null;
+      assert(isWrapper(wrapper));
+      return wrapper.__impl4cf1e782hg__;
+    }
+    function unsafeUnwrap(wrapper) {
+      return wrapper.__impl4cf1e782hg__;
+    }
+    function setWrapper(impl, wrapper) {
+      wrapper.__impl4cf1e782hg__ = impl;
+      impl.__wrapper8e3dd93a60__ = wrapper;
+    }
+    function unwrapIfNeeded(object) {
+      return object && isWrapper(object) ? unwrap(object) : object;
+    }
+    function wrapIfNeeded(object) {
+      return object && !isWrapper(object) ? wrap(object) : object;
+    }
+    function rewrap(node, wrapper) {
+      if (wrapper === null) return;
+      assert(isNative(node));
+      assert(wrapper === undefined || isWrapper(wrapper));
+      node.__wrapper8e3dd93a60__ = wrapper;
+    }
+    var getterDescriptor = {
+      get: undefined,
+      configurable: true,
+      enumerable: true
+    };
+    function defineGetter(constructor, name, getter) {
+      getterDescriptor.get = getter;
+      defineProperty(constructor.prototype, name, getterDescriptor);
+    }
+    function defineWrapGetter(constructor, name) {
+      defineGetter(constructor, name, function() {
+        return wrap(this.__impl4cf1e782hg__[name]);
+      });
+    }
+    function forwardMethodsToWrapper(constructors, names) {
+      constructors.forEach(function(constructor) {
+        names.forEach(function(name) {
+          constructor.prototype[name] = function() {
+            var w = wrapIfNeeded(this);
+            return w[name].apply(w, arguments);
+          };
+        });
+      });
+    }
+    scope.assert = assert;
+    scope.constructorTable = constructorTable;
+    scope.defineGetter = defineGetter;
+    scope.defineWrapGetter = defineWrapGetter;
+    scope.forwardMethodsToWrapper = forwardMethodsToWrapper;
+    scope.isWrapper = isWrapper;
+    scope.isWrapperFor = isWrapperFor;
+    scope.mixin = mixin;
+    scope.nativePrototypeTable = nativePrototypeTable;
+    scope.oneOf = oneOf;
+    scope.registerObject = registerObject;
+    scope.registerWrapper = register;
+    scope.rewrap = rewrap;
+    scope.setWrapper = setWrapper;
+    scope.unsafeUnwrap = unsafeUnwrap;
+    scope.unwrap = unwrap;
+    scope.unwrapIfNeeded = unwrapIfNeeded;
+    scope.wrap = wrap;
+    scope.wrapIfNeeded = wrapIfNeeded;
+    scope.wrappers = wrappers;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    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;
+      }
+    };
+    scope.ArraySplice = ArraySplice;
+  })(window.ShadowDOMPolyfill);
+  (function(context) {
+    "use strict";
+    var OriginalMutationObserver = window.MutationObserver;
+    var callbacks = [];
+    var pending = false;
+    var timerFunc;
+    function handle() {
+      pending = false;
+      var copies = callbacks.slice(0);
+      callbacks = [];
+      for (var i = 0; i < copies.length; i++) {
+        (0, copies[i])();
+      }
+    }
+    if (OriginalMutationObserver) {
+      var counter = 1;
+      var observer = new OriginalMutationObserver(handle);
+      var textNode = document.createTextNode(counter);
+      observer.observe(textNode, {
+        characterData: true
+      });
+      timerFunc = function() {
+        counter = (counter + 1) % 2;
+        textNode.data = counter;
+      };
+    } else {
+      timerFunc = window.setTimeout;
+    }
+    function setEndOfMicrotask(func) {
+      callbacks.push(func);
+      if (pending) return;
+      pending = true;
+      timerFunc(handle, 0);
+    }
+    context.setEndOfMicrotask = setEndOfMicrotask;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var setEndOfMicrotask = scope.setEndOfMicrotask;
+    var wrapIfNeeded = scope.wrapIfNeeded;
+    var wrappers = scope.wrappers;
+    var registrationsTable = new WeakMap();
+    var globalMutationObservers = [];
+    var isScheduled = false;
+    function scheduleCallback(observer) {
+      if (observer.scheduled_) return;
+      observer.scheduled_ = true;
+      globalMutationObservers.push(observer);
+      if (isScheduled) return;
+      setEndOfMicrotask(notifyObservers);
+      isScheduled = true;
+    }
+    function notifyObservers() {
+      isScheduled = false;
+      while (globalMutationObservers.length) {
+        var notifyList = globalMutationObservers;
+        globalMutationObservers = [];
+        notifyList.sort(function(x, y) {
+          return x.uid_ - y.uid_;
+        });
+        for (var i = 0; i < notifyList.length; i++) {
+          var mo = notifyList[i];
+          mo.scheduled_ = false;
+          var queue = mo.takeRecords();
+          removeTransientObserversFor(mo);
+          if (queue.length) {
+            mo.callback_(queue, mo);
+          }
+        }
+      }
+    }
+    function MutationRecord(type, target) {
+      this.type = type;
+      this.target = target;
+      this.addedNodes = new wrappers.NodeList();
+      this.removedNodes = new wrappers.NodeList();
+      this.previousSibling = null;
+      this.nextSibling = null;
+      this.attributeName = null;
+      this.attributeNamespace = null;
+      this.oldValue = null;
+    }
+    function registerTransientObservers(ancestor, node) {
+      for (;ancestor; ancestor = ancestor.parentNode) {
+        var registrations = registrationsTable.get(ancestor);
+        if (!registrations) continue;
+        for (var i = 0; i < registrations.length; i++) {
+          var registration = registrations[i];
+          if (registration.options.subtree) registration.addTransientObserver(node);
+        }
+      }
+    }
+    function removeTransientObserversFor(observer) {
+      for (var i = 0; i < observer.nodes_.length; i++) {
+        var node = observer.nodes_[i];
+        var registrations = registrationsTable.get(node);
+        if (!registrations) return;
+        for (var j = 0; j < registrations.length; j++) {
+          var registration = registrations[j];
+          if (registration.observer === observer) registration.removeTransientObservers();
+        }
+      }
+    }
+    function enqueueMutation(target, type, data) {
+      var interestedObservers = Object.create(null);
+      var associatedStrings = Object.create(null);
+      for (var node = target; node; node = node.parentNode) {
+        var registrations = registrationsTable.get(node);
+        if (!registrations) continue;
+        for (var j = 0; j < registrations.length; j++) {
+          var registration = registrations[j];
+          var options = registration.options;
+          if (node !== target && !options.subtree) continue;
+          if (type === "attributes" && !options.attributes) continue;
+          if (type === "attributes" && options.attributeFilter && (data.namespace !== null || options.attributeFilter.indexOf(data.name) === -1)) {
+            continue;
+          }
+          if (type === "characterData" && !options.characterData) continue;
+          if (type === "childList" && !options.childList) continue;
+          var observer = registration.observer;
+          interestedObservers[observer.uid_] = observer;
+          if (type === "attributes" && options.attributeOldValue || type === "characterData" && options.characterDataOldValue) {
+            associatedStrings[observer.uid_] = data.oldValue;
+          }
+        }
+      }
+      for (var uid in interestedObservers) {
+        var observer = interestedObservers[uid];
+        var record = new MutationRecord(type, target);
+        if ("name" in data && "namespace" in data) {
+          record.attributeName = data.name;
+          record.attributeNamespace = data.namespace;
+        }
+        if (data.addedNodes) record.addedNodes = data.addedNodes;
+        if (data.removedNodes) record.removedNodes = data.removedNodes;
+        if (data.previousSibling) record.previousSibling = data.previousSibling;
+        if (data.nextSibling) record.nextSibling = data.nextSibling;
+        if (associatedStrings[uid] !== undefined) record.oldValue = associatedStrings[uid];
+        scheduleCallback(observer);
+        observer.records_.push(record);
+      }
+    }
+    var slice = Array.prototype.slice;
+    function MutationObserverOptions(options) {
+      this.childList = !!options.childList;
+      this.subtree = !!options.subtree;
+      if (!("attributes" in options) && ("attributeOldValue" in options || "attributeFilter" in options)) {
+        this.attributes = true;
+      } else {
+        this.attributes = !!options.attributes;
+      }
+      if ("characterDataOldValue" in options && !("characterData" in options)) this.characterData = true; else this.characterData = !!options.characterData;
+      if (!this.attributes && (options.attributeOldValue || "attributeFilter" in options) || !this.characterData && options.characterDataOldValue) {
+        throw new TypeError();
+      }
+      this.characterData = !!options.characterData;
+      this.attributeOldValue = !!options.attributeOldValue;
+      this.characterDataOldValue = !!options.characterDataOldValue;
+      if ("attributeFilter" in options) {
+        if (options.attributeFilter == null || typeof options.attributeFilter !== "object") {
+          throw new TypeError();
+        }
+        this.attributeFilter = slice.call(options.attributeFilter);
+      } else {
+        this.attributeFilter = null;
+      }
+    }
+    var uidCounter = 0;
+    function MutationObserver(callback) {
+      this.callback_ = callback;
+      this.nodes_ = [];
+      this.records_ = [];
+      this.uid_ = ++uidCounter;
+      this.scheduled_ = false;
+    }
+    MutationObserver.prototype = {
+      constructor: MutationObserver,
+      observe: function(target, options) {
+        target = wrapIfNeeded(target);
+        var newOptions = new MutationObserverOptions(options);
+        var registration;
+        var registrations = registrationsTable.get(target);
+        if (!registrations) registrationsTable.set(target, registrations = []);
+        for (var i = 0; i < registrations.length; i++) {
+          if (registrations[i].observer === this) {
+            registration = registrations[i];
+            registration.removeTransientObservers();
+            registration.options = newOptions;
+          }
+        }
+        if (!registration) {
+          registration = new Registration(this, target, newOptions);
+          registrations.push(registration);
+          this.nodes_.push(target);
+        }
+      },
+      disconnect: function() {
+        this.nodes_.forEach(function(node) {
+          var registrations = registrationsTable.get(node);
+          for (var i = 0; i < registrations.length; i++) {
+            var registration = registrations[i];
+            if (registration.observer === this) {
+              registrations.splice(i, 1);
+              break;
+            }
+          }
+        }, this);
+        this.records_ = [];
+      },
+      takeRecords: function() {
+        var copyOfRecords = this.records_;
+        this.records_ = [];
+        return copyOfRecords;
+      }
+    };
+    function Registration(observer, target, options) {
+      this.observer = observer;
+      this.target = target;
+      this.options = options;
+      this.transientObservedNodes = [];
+    }
+    Registration.prototype = {
+      addTransientObserver: function(node) {
+        if (node === this.target) return;
+        scheduleCallback(this.observer);
+        this.transientObservedNodes.push(node);
+        var registrations = registrationsTable.get(node);
+        if (!registrations) registrationsTable.set(node, registrations = []);
+        registrations.push(this);
+      },
+      removeTransientObservers: function() {
+        var transientObservedNodes = this.transientObservedNodes;
+        this.transientObservedNodes = [];
+        for (var i = 0; i < transientObservedNodes.length; i++) {
+          var node = transientObservedNodes[i];
+          var registrations = registrationsTable.get(node);
+          for (var j = 0; j < registrations.length; j++) {
+            if (registrations[j] === this) {
+              registrations.splice(j, 1);
+              break;
+            }
+          }
+        }
+      }
+    };
+    scope.enqueueMutation = enqueueMutation;
+    scope.registerTransientObservers = registerTransientObservers;
+    scope.wrappers.MutationObserver = MutationObserver;
+    scope.wrappers.MutationRecord = MutationRecord;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    function TreeScope(root, parent) {
+      this.root = root;
+      this.parent = parent;
+    }
+    TreeScope.prototype = {
+      get renderer() {
+        if (this.root instanceof scope.wrappers.ShadowRoot) {
+          return scope.getRendererForHost(this.root.host);
+        }
+        return null;
+      },
+      contains: function(treeScope) {
+        for (;treeScope; treeScope = treeScope.parent) {
+          if (treeScope === this) return true;
+        }
+        return false;
+      }
+    };
+    function setTreeScope(node, treeScope) {
+      if (node.treeScope_ !== treeScope) {
+        node.treeScope_ = treeScope;
+        for (var sr = node.shadowRoot; sr; sr = sr.olderShadowRoot) {
+          sr.treeScope_.parent = treeScope;
+        }
+        for (var child = node.firstChild; child; child = child.nextSibling) {
+          setTreeScope(child, treeScope);
+        }
+      }
+    }
+    function getTreeScope(node) {
+      if (node instanceof scope.wrappers.Window) {
+        debugger;
+      }
+      if (node.treeScope_) return node.treeScope_;
+      var parent = node.parentNode;
+      var treeScope;
+      if (parent) treeScope = getTreeScope(parent); else treeScope = new TreeScope(node, null);
+      return node.treeScope_ = treeScope;
+    }
+    scope.TreeScope = TreeScope;
+    scope.getTreeScope = getTreeScope;
+    scope.setTreeScope = setTreeScope;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
+    var getTreeScope = scope.getTreeScope;
+    var mixin = scope.mixin;
+    var registerWrapper = scope.registerWrapper;
+    var setWrapper = scope.setWrapper;
+    var unsafeUnwrap = scope.unsafeUnwrap;
+    var unwrap = scope.unwrap;
+    var wrap = scope.wrap;
+    var wrappers = scope.wrappers;
+    var wrappedFuns = new WeakMap();
+    var listenersTable = new WeakMap();
+    var handledEventsTable = new WeakMap();
+    var currentlyDispatchingEvents = new WeakMap();
+    var targetTable = new WeakMap();
+    var currentTargetTable = new WeakMap();
+    var relatedTargetTable = new WeakMap();
+    var eventPhaseTable = new WeakMap();
+    var stopPropagationTable = new WeakMap();
+    var stopImmediatePropagationTable = new WeakMap();
+    var eventHandlersTable = new WeakMap();
+    var eventPathTable = new WeakMap();
+    function isShadowRoot(node) {
+      return node instanceof wrappers.ShadowRoot;
+    }
+    function rootOfNode(node) {
+      return getTreeScope(node).root;
+    }
+    function getEventPath(node, event) {
+      var path = [];
+      var current = node;
+      path.push(current);
+      while (current) {
+        var destinationInsertionPoints = getDestinationInsertionPoints(current);
+        if (destinationInsertionPoints && destinationInsertionPoints.length > 0) {
+          for (var i = 0; i < destinationInsertionPoints.length; i++) {
+            var insertionPoint = destinationInsertionPoints[i];
+            if (isShadowInsertionPoint(insertionPoint)) {
+              var shadowRoot = rootOfNode(insertionPoint);
+              var olderShadowRoot = shadowRoot.olderShadowRoot;
+              if (olderShadowRoot) path.push(olderShadowRoot);
+            }
+            path.push(insertionPoint);
+          }
+          current = destinationInsertionPoints[destinationInsertionPoints.length - 1];
+        } else {
+          if (isShadowRoot(current)) {
+            if (inSameTree(node, current) && eventMustBeStopped(event)) {
+              break;
+            }
+            current = current.host;
+            path.push(current);
+          } else {
+            current = current.parentNode;
+            if (current) path.push(current);
+          }
+        }
+      }
+      return path;
+    }
+    function eventMustBeStopped(event) {
+      if (!event) return false;
+      switch (event.type) {
+       case "abort":
+       case "error":
+       case "select":
+       case "change":
+       case "load":
+       case "reset":
+       case "resize":
+       case "scroll":
+       case "selectstart":
+        return true;
+      }
+      return false;
+    }
+    function isShadowInsertionPoint(node) {
+      return node instanceof HTMLShadowElement;
+    }
+    function getDestinationInsertionPoints(node) {
+      return scope.getDestinationInsertionPoints(node);
+    }
+    function eventRetargetting(path, currentTarget) {
+      if (path.length === 0) return currentTarget;
+      if (currentTarget instanceof wrappers.Window) currentTarget = currentTarget.document;
+      var currentTargetTree = getTreeScope(currentTarget);
+      var originalTarget = path[0];
+      var originalTargetTree = getTreeScope(originalTarget);
+      var relativeTargetTree = lowestCommonInclusiveAncestor(currentTargetTree, originalTargetTree);
+      for (var i = 0; i < path.length; i++) {
+        var node = path[i];
+        if (getTreeScope(node) === relativeTargetTree) return node;
+      }
+      return path[path.length - 1];
+    }
+    function getTreeScopeAncestors(treeScope) {
+      var ancestors = [];
+      for (;treeScope; treeScope = treeScope.parent) {
+        ancestors.push(treeScope);
+      }
+      return ancestors;
+    }
+    function lowestCommonInclusiveAncestor(tsA, tsB) {
+      var ancestorsA = getTreeScopeAncestors(tsA);
+      var ancestorsB = getTreeScopeAncestors(tsB);
+      var result = null;
+      while (ancestorsA.length > 0 && ancestorsB.length > 0) {
+        var a = ancestorsA.pop();
+        var b = ancestorsB.pop();
+        if (a === b) result = a; else break;
+      }
+      return result;
+    }
+    function getTreeScopeRoot(ts) {
+      if (!ts.parent) return ts;
+      return getTreeScopeRoot(ts.parent);
+    }
+    function relatedTargetResolution(event, currentTarget, relatedTarget) {
+      if (currentTarget instanceof wrappers.Window) currentTarget = currentTarget.document;
+      var currentTargetTree = getTreeScope(currentTarget);
+      var relatedTargetTree = getTreeScope(relatedTarget);
+      var relatedTargetEventPath = getEventPath(relatedTarget, event);
+      var lowestCommonAncestorTree;
+      var lowestCommonAncestorTree = lowestCommonInclusiveAncestor(currentTargetTree, relatedTargetTree);
+      if (!lowestCommonAncestorTree) lowestCommonAncestorTree = relatedTargetTree.root;
+      for (var commonAncestorTree = lowestCommonAncestorTree; commonAncestorTree; commonAncestorTree = commonAncestorTree.parent) {
+        var adjustedRelatedTarget;
+        for (var i = 0; i < relatedTargetEventPath.length; i++) {
+          var node = relatedTargetEventPath[i];
+          if (getTreeScope(node) === commonAncestorTree) return node;
+        }
+      }
+      return null;
+    }
+    function inSameTree(a, b) {
+      return getTreeScope(a) === getTreeScope(b);
+    }
+    var NONE = 0;
+    var CAPTURING_PHASE = 1;
+    var AT_TARGET = 2;
+    var BUBBLING_PHASE = 3;
+    var pendingError;
+    function dispatchOriginalEvent(originalEvent) {
+      if (handledEventsTable.get(originalEvent)) return;
+      handledEventsTable.set(originalEvent, true);
+      dispatchEvent(wrap(originalEvent), wrap(originalEvent.target));
+      if (pendingError) {
+        var err = pendingError;
+        pendingError = null;
+        throw err;
+      }
+    }
+    function isLoadLikeEvent(event) {
+      switch (event.type) {
+       case "load":
+       case "beforeunload":
+       case "unload":
+        return true;
+      }
+      return false;
+    }
+    function dispatchEvent(event, originalWrapperTarget) {
+      if (currentlyDispatchingEvents.get(event)) throw new Error("InvalidStateError");
+      currentlyDispatchingEvents.set(event, true);
+      scope.renderAllPending();
+      var eventPath;
+      var overrideTarget;
+      var win;
+      if (isLoadLikeEvent(event) && !event.bubbles) {
+        var doc = originalWrapperTarget;
+        if (doc instanceof wrappers.Document && (win = doc.defaultView)) {
+          overrideTarget = doc;
+          eventPath = [];
+        }
+      }
+      if (!eventPath) {
+        if (originalWrapperTarget instanceof wrappers.Window) {
+          win = originalWrapperTarget;
+          eventPath = [];
+        } else {
+          eventPath = getEventPath(originalWrapperTarget, event);
+          if (!isLoadLikeEvent(event)) {
+            var doc = eventPath[eventPath.length - 1];
+            if (doc instanceof wrappers.Document) win = doc.defaultView;
+          }
+        }
+      }
+      eventPathTable.set(event, eventPath);
+      if (dispatchCapturing(event, eventPath, win, overrideTarget)) {
+        if (dispatchAtTarget(event, eventPath, win, overrideTarget)) {
+          dispatchBubbling(event, eventPath, win, overrideTarget);
+        }
+      }
+      eventPhaseTable.set(event, NONE);
+      currentTargetTable.delete(event, null);
+      currentlyDispatchingEvents.delete(event);
+      return event.defaultPrevented;
+    }
+    function dispatchCapturing(event, eventPath, win, overrideTarget) {
+      var phase = CAPTURING_PHASE;
+      if (win) {
+        if (!invoke(win, event, phase, eventPath, overrideTarget)) return false;
+      }
+      for (var i = eventPath.length - 1; i > 0; i--) {
+        if (!invoke(eventPath[i], event, phase, eventPath, overrideTarget)) return false;
+      }
+      return true;
+    }
+    function dispatchAtTarget(event, eventPath, win, overrideTarget) {
+      var phase = AT_TARGET;
+      var currentTarget = eventPath[0] || win;
+      return invoke(currentTarget, event, phase, eventPath, overrideTarget);
+    }
+    function dispatchBubbling(event, eventPath, win, overrideTarget) {
+      var phase = BUBBLING_PHASE;
+      for (var i = 1; i < eventPath.length; i++) {
+        if (!invoke(eventPath[i], event, phase, eventPath, overrideTarget)) return;
+      }
+      if (win && eventPath.length > 0) {
+        invoke(win, event, phase, eventPath, overrideTarget);
+      }
+    }
+    function invoke(currentTarget, event, phase, eventPath, overrideTarget) {
+      var listeners = listenersTable.get(currentTarget);
+      if (!listeners) return true;
+      var target = overrideTarget || eventRetargetting(eventPath, currentTarget);
+      if (target === currentTarget) {
+        if (phase === CAPTURING_PHASE) return true;
+        if (phase === BUBBLING_PHASE) phase = AT_TARGET;
+      } else if (phase === BUBBLING_PHASE && !event.bubbles) {
+        return true;
+      }
+      if ("relatedTarget" in event) {
+        var originalEvent = unwrap(event);
+        var unwrappedRelatedTarget = originalEvent.relatedTarget;
+        if (unwrappedRelatedTarget) {
+          if (unwrappedRelatedTarget instanceof Object && unwrappedRelatedTarget.addEventListener) {
+            var relatedTarget = wrap(unwrappedRelatedTarget);
+            var adjusted = relatedTargetResolution(event, currentTarget, relatedTarget);
+            if (adjusted === target) return true;
+          } else {
+            adjusted = null;
+          }
+          relatedTargetTable.set(event, adjusted);
+        }
+      }
+      eventPhaseTable.set(event, phase);
+      var type = event.type;
+      var anyRemoved = false;
+      targetTable.set(event, target);
+      currentTargetTable.set(event, currentTarget);
+      listeners.depth++;
+      for (var i = 0, len = listeners.length; i < len; i++) {
+        var listener = listeners[i];
+        if (listener.removed) {
+          anyRemoved = true;
+          continue;
+        }
+        if (listener.type !== type || !listener.capture && phase === CAPTURING_PHASE || listener.capture && phase === BUBBLING_PHASE) {
+          continue;
+        }
+        try {
+          if (typeof listener.handler === "function") listener.handler.call(currentTarget, event); else listener.handler.handleEvent(event);
+          if (stopImmediatePropagationTable.get(event)) return false;
+        } catch (ex) {
+          if (!pendingError) pendingError = ex;
+        }
+      }
+      listeners.depth--;
+      if (anyRemoved && listeners.depth === 0) {
+        var copy = listeners.slice();
+        listeners.length = 0;
+        for (var i = 0; i < copy.length; i++) {
+          if (!copy[i].removed) listeners.push(copy[i]);
+        }
+      }
+      return !stopPropagationTable.get(event);
+    }
+    function Listener(type, handler, capture) {
+      this.type = type;
+      this.handler = handler;
+      this.capture = Boolean(capture);
+    }
+    Listener.prototype = {
+      equals: function(that) {
+        return this.handler === that.handler && this.type === that.type && this.capture === that.capture;
+      },
+      get removed() {
+        return this.handler === null;
+      },
+      remove: function() {
+        this.handler = null;
+      }
+    };
+    var OriginalEvent = window.Event;
+    OriginalEvent.prototype.polymerBlackList_ = {
+      returnValue: true,
+      keyLocation: true
+    };
+    function Event(type, options) {
+      if (type instanceof OriginalEvent) {
+        var impl = type;
+        if (!OriginalBeforeUnloadEvent && impl.type === "beforeunload" && !(this instanceof BeforeUnloadEvent)) {
+          return new BeforeUnloadEvent(impl);
+        }
+        setWrapper(impl, this);
+      } else {
+        return wrap(constructEvent(OriginalEvent, "Event", type, options));
+      }
+    }
+    Event.prototype = {
+      get target() {
+        return targetTable.get(this);
+      },
+      get currentTarget() {
+        return currentTargetTable.get(this);
+      },
+      get eventPhase() {
+        return eventPhaseTable.get(this);
+      },
+      get path() {
+        var eventPath = eventPathTable.get(this);
+        if (!eventPath) return [];
+        return eventPath.slice();
+      },
+      stopPropagation: function() {
+        stopPropagationTable.set(this, true);
+      },
+      stopImmediatePropagation: function() {
+        stopPropagationTable.set(this, true);
+        stopImmediatePropagationTable.set(this, true);
+      }
+    };
+    registerWrapper(OriginalEvent, Event, document.createEvent("Event"));
+    function unwrapOptions(options) {
+      if (!options || !options.relatedTarget) return options;
+      return Object.create(options, {
+        relatedTarget: {
+          value: unwrap(options.relatedTarget)
+        }
+      });
+    }
+    function registerGenericEvent(name, SuperEvent, prototype) {
+      var OriginalEvent = window[name];
+      var GenericEvent = function(type, options) {
+        if (type instanceof OriginalEvent) setWrapper(type, this); else return wrap(constructEvent(OriginalEvent, name, type, options));
+      };
+      GenericEvent.prototype = Object.create(SuperEvent.prototype);
+      if (prototype) mixin(GenericEvent.prototype, prototype);
+      if (OriginalEvent) {
+        try {
+          registerWrapper(OriginalEvent, GenericEvent, new OriginalEvent("temp"));
+        } catch (ex) {
+          registerWrapper(OriginalEvent, GenericEvent, document.createEvent(name));
+        }
+      }
+      return GenericEvent;
+    }
+    var UIEvent = registerGenericEvent("UIEvent", Event);
+    var CustomEvent = registerGenericEvent("CustomEvent", Event);
+    var relatedTargetProto = {
+      get relatedTarget() {
+        var relatedTarget = relatedTargetTable.get(this);
+        if (relatedTarget !== undefined) return relatedTarget;
+        return wrap(unwrap(this).relatedTarget);
+      }
+    };
+    function getInitFunction(name, relatedTargetIndex) {
+      return function() {
+        arguments[relatedTargetIndex] = unwrap(arguments[relatedTargetIndex]);
+        var impl = unwrap(this);
+        impl[name].apply(impl, arguments);
+      };
+    }
+    var mouseEventProto = mixin({
+      initMouseEvent: getInitFunction("initMouseEvent", 14)
+    }, relatedTargetProto);
+    var focusEventProto = mixin({
+      initFocusEvent: getInitFunction("initFocusEvent", 5)
+    }, relatedTargetProto);
+    var MouseEvent = registerGenericEvent("MouseEvent", UIEvent, mouseEventProto);
+    var FocusEvent = registerGenericEvent("FocusEvent", UIEvent, focusEventProto);
+    var defaultInitDicts = Object.create(null);
+    var supportsEventConstructors = function() {
+      try {
+        new window.FocusEvent("focus");
+      } catch (ex) {
+        return false;
+      }
+      return true;
+    }();
+    function constructEvent(OriginalEvent, name, type, options) {
+      if (supportsEventConstructors) return new OriginalEvent(type, unwrapOptions(options));
+      var event = unwrap(document.createEvent(name));
+      var defaultDict = defaultInitDicts[name];
+      var args = [ type ];
+      Object.keys(defaultDict).forEach(function(key) {
+        var v = options != null && key in options ? options[key] : defaultDict[key];
+        if (key === "relatedTarget") v = unwrap(v);
+        args.push(v);
+      });
+      event["init" + name].apply(event, args);
+      return event;
+    }
+    if (!supportsEventConstructors) {
+      var configureEventConstructor = function(name, initDict, superName) {
+        if (superName) {
+          var superDict = defaultInitDicts[superName];
+          initDict = mixin(mixin({}, superDict), initDict);
+        }
+        defaultInitDicts[name] = initDict;
+      };
+      configureEventConstructor("Event", {
+        bubbles: false,
+        cancelable: false
+      });
+      configureEventConstructor("CustomEvent", {
+        detail: null
+      }, "Event");
+      configureEventConstructor("UIEvent", {
+        view: null,
+        detail: 0
+      }, "Event");
+      configureEventConstructor("MouseEvent", {
+        screenX: 0,
+        screenY: 0,
+        clientX: 0,
+        clientY: 0,
+        ctrlKey: false,
+        altKey: false,
+        shiftKey: false,
+        metaKey: false,
+        button: 0,
+        relatedTarget: null
+      }, "UIEvent");
+      configureEventConstructor("FocusEvent", {
+        relatedTarget: null
+      }, "UIEvent");
+    }
+    var OriginalBeforeUnloadEvent = window.BeforeUnloadEvent;
+    function BeforeUnloadEvent(impl) {
+      Event.call(this, impl);
+    }
+    BeforeUnloadEvent.prototype = Object.create(Event.prototype);
+    mixin(BeforeUnloadEvent.prototype, {
+      get returnValue() {
+        return unsafeUnwrap(this).returnValue;
+      },
+      set returnValue(v) {
+        unsafeUnwrap(this).returnValue = v;
+      }
+    });
+    if (OriginalBeforeUnloadEvent) registerWrapper(OriginalBeforeUnloadEvent, BeforeUnloadEvent);
+    function isValidListener(fun) {
+      if (typeof fun === "function") return true;
+      return fun && fun.handleEvent;
+    }
+    function isMutationEvent(type) {
+      switch (type) {
+       case "DOMAttrModified":
+       case "DOMAttributeNameChanged":
+       case "DOMCharacterDataModified":
+       case "DOMElementNameChanged":
+       case "DOMNodeInserted":
+       case "DOMNodeInsertedIntoDocument":
+       case "DOMNodeRemoved":
+       case "DOMNodeRemovedFromDocument":
+       case "DOMSubtreeModified":
+        return true;
+      }
+      return false;
+    }
+    var OriginalEventTarget = window.EventTarget;
+    function EventTarget(impl) {
+      setWrapper(impl, this);
+    }
+    var methodNames = [ "addEventListener", "removeEventListener", "dispatchEvent" ];
+    [ Node, Window ].forEach(function(constructor) {
+      var p = constructor.prototype;
+      methodNames.forEach(function(name) {
+        Object.defineProperty(p, name + "_", {
+          value: p[name]
+        });
+      });
+    });
+    function getTargetToListenAt(wrapper) {
+      if (wrapper instanceof wrappers.ShadowRoot) wrapper = wrapper.host;
+      return unwrap(wrapper);
+    }
+    EventTarget.prototype = {
+      addEventListener: function(type, fun, capture) {
+        if (!isValidListener(fun) || isMutationEvent(type)) return;
+        var listener = new Listener(type, fun, capture);
+        var listeners = listenersTable.get(this);
+        if (!listeners) {
+          listeners = [];
+          listeners.depth = 0;
+          listenersTable.set(this, listeners);
+        } else {
+          for (var i = 0; i < listeners.length; i++) {
+            if (listener.equals(listeners[i])) return;
+          }
+        }
+        listeners.push(listener);
+        var target = getTargetToListenAt(this);
+        target.addEventListener_(type, dispatchOriginalEvent, true);
+      },
+      removeEventListener: function(type, fun, capture) {
+        capture = Boolean(capture);
+        var listeners = listenersTable.get(this);
+        if (!listeners) return;
+        var count = 0, found = false;
+        for (var i = 0; i < listeners.length; i++) {
+          if (listeners[i].type === type && listeners[i].capture === capture) {
+            count++;
+            if (listeners[i].handler === fun) {
+              found = true;
+              listeners[i].remove();
+            }
+          }
+        }
+        if (found && count === 1) {
+          var target = getTargetToListenAt(this);
+          target.removeEventListener_(type, dispatchOriginalEvent, true);
+        }
+      },
+      dispatchEvent: function(event) {
+        var nativeEvent = unwrap(event);
+        var eventType = nativeEvent.type;
+        handledEventsTable.set(nativeEvent, false);
+        scope.renderAllPending();
+        var tempListener;
+        if (!hasListenerInAncestors(this, eventType)) {
+          tempListener = function() {};
+          this.addEventListener(eventType, tempListener, true);
+        }
+        try {
+          return unwrap(this).dispatchEvent_(nativeEvent);
+        } finally {
+          if (tempListener) this.removeEventListener(eventType, tempListener, true);
+        }
+      }
+    };
+    function hasListener(node, type) {
+      var listeners = listenersTable.get(node);
+      if (listeners) {
+        for (var i = 0; i < listeners.length; i++) {
+          if (!listeners[i].removed && listeners[i].type === type) return true;
+        }
+      }
+      return false;
+    }
+    function hasListenerInAncestors(target, type) {
+      for (var node = unwrap(target); node; node = node.parentNode) {
+        if (hasListener(wrap(node), type)) return true;
+      }
+      return false;
+    }
+    if (OriginalEventTarget) registerWrapper(OriginalEventTarget, EventTarget);
+    function wrapEventTargetMethods(constructors) {
+      forwardMethodsToWrapper(constructors, methodNames);
+    }
+    var originalElementFromPoint = document.elementFromPoint;
+    function elementFromPoint(self, document, x, y) {
+      scope.renderAllPending();
+      var element = wrap(originalElementFromPoint.call(unsafeUnwrap(document), x, y));
+      if (!element) return null;
+      var path = getEventPath(element, null);
+      var idx = path.lastIndexOf(self);
+      if (idx == -1) return null; else path = path.slice(0, idx);
+      return eventRetargetting(path, self);
+    }
+    function getEventHandlerGetter(name) {
+      return function() {
+        var inlineEventHandlers = eventHandlersTable.get(this);
+        return inlineEventHandlers && inlineEventHandlers[name] && inlineEventHandlers[name].value || null;
+      };
+    }
+    function getEventHandlerSetter(name) {
+      var eventType = name.slice(2);
+      return function(value) {
+        var inlineEventHandlers = eventHandlersTable.get(this);
+        if (!inlineEventHandlers) {
+          inlineEventHandlers = Object.create(null);
+          eventHandlersTable.set(this, inlineEventHandlers);
+        }
+        var old = inlineEventHandlers[name];
+        if (old) this.removeEventListener(eventType, old.wrapped, false);
+        if (typeof value === "function") {
+          var wrapped = function(e) {
+            var rv = value.call(this, e);
+            if (rv === false) e.preventDefault(); else if (name === "onbeforeunload" && typeof rv === "string") e.returnValue = rv;
+          };
+          this.addEventListener(eventType, wrapped, false);
+          inlineEventHandlers[name] = {
+            value: value,
+            wrapped: wrapped
+          };
+        }
+      };
+    }
+    scope.elementFromPoint = elementFromPoint;
+    scope.getEventHandlerGetter = getEventHandlerGetter;
+    scope.getEventHandlerSetter = getEventHandlerSetter;
+    scope.wrapEventTargetMethods = wrapEventTargetMethods;
+    scope.wrappers.BeforeUnloadEvent = BeforeUnloadEvent;
+    scope.wrappers.CustomEvent = CustomEvent;
+    scope.wrappers.Event = Event;
+    scope.wrappers.EventTarget = EventTarget;
+    scope.wrappers.FocusEvent = FocusEvent;
+    scope.wrappers.MouseEvent = MouseEvent;
+    scope.wrappers.UIEvent = UIEvent;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var UIEvent = scope.wrappers.UIEvent;
+    var mixin = scope.mixin;
+    var registerWrapper = scope.registerWrapper;
+    var setWrapper = scope.setWrapper;
+    var unsafeUnwrap = scope.unsafeUnwrap;
+    var wrap = scope.wrap;
+    var OriginalTouchEvent = window.TouchEvent;
+    if (!OriginalTouchEvent) return;
+    var nativeEvent;
+    try {
+      nativeEvent = document.createEvent("TouchEvent");
+    } catch (ex) {
+      return;
+    }
+    var nonEnumDescriptor = {
+      enumerable: false
+    };
+    function nonEnum(obj, prop) {
+      Object.defineProperty(obj, prop, nonEnumDescriptor);
+    }
+    function Touch(impl) {
+      setWrapper(impl, this);
+    }
+    Touch.prototype = {
+      get target() {
+        return wrap(unsafeUnwrap(this).target);
+      }
+    };
+    var descr = {
+      configurable: true,
+      enumerable: true,
+      get: null
+    };
+    [ "clientX", "clientY", "screenX", "screenY", "pageX", "pageY", "identifier", "webkitRadiusX", "webkitRadiusY", "webkitRotationAngle", "webkitForce" ].forEach(function(name) {
+      descr.get = function() {
+        return unsafeUnwrap(this)[name];
+      };
+      Object.defineProperty(Touch.prototype, name, descr);
+    });
+    function TouchList() {
+      this.length = 0;
+      nonEnum(this, "length");
+    }
+    TouchList.prototype = {
+      item: function(index) {
+        return this[index];
+      }
+    };
+    function wrapTouchList(nativeTouchList) {
+      var list = new TouchList();
+      for (var i = 0; i < nativeTouchList.length; i++) {
+        list[i] = new Touch(nativeTouchList[i]);
+      }
+      list.length = i;
+      return list;
+    }
+    function TouchEvent(impl) {
+      UIEvent.call(this, impl);
+    }
+    TouchEvent.prototype = Object.create(UIEvent.prototype);
+    mixin(TouchEvent.prototype, {
+      get touches() {
+        return wrapTouchList(unsafeUnwrap(this).touches);
+      },
+      get targetTouches() {
+        return wrapTouchList(unsafeUnwrap(this).targetTouches);
+      },
+      get changedTouches() {
+        return wrapTouchList(unsafeUnwrap(this).changedTouches);
+      },
+      initTouchEvent: function() {
+        throw new Error("Not implemented");
+      }
+    });
+    registerWrapper(OriginalTouchEvent, TouchEvent, nativeEvent);
+    scope.wrappers.Touch = Touch;
+    scope.wrappers.TouchEvent = TouchEvent;
+    scope.wrappers.TouchList = TouchList;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var unsafeUnwrap = scope.unsafeUnwrap;
+    var wrap = scope.wrap;
+    var nonEnumDescriptor = {
+      enumerable: false
+    };
+    function nonEnum(obj, prop) {
+      Object.defineProperty(obj, prop, nonEnumDescriptor);
+    }
+    function NodeList() {
+      this.length = 0;
+      nonEnum(this, "length");
+    }
+    NodeList.prototype = {
+      item: function(index) {
+        return this[index];
+      }
+    };
+    nonEnum(NodeList.prototype, "item");
+    function wrapNodeList(list) {
+      if (list == null) return list;
+      var wrapperList = new NodeList();
+      for (var i = 0, length = list.length; i < length; i++) {
+        wrapperList[i] = wrap(list[i]);
+      }
+      wrapperList.length = length;
+      return wrapperList;
+    }
+    function addWrapNodeListMethod(wrapperConstructor, name) {
+      wrapperConstructor.prototype[name] = function() {
+        return wrapNodeList(unsafeUnwrap(this)[name].apply(unsafeUnwrap(this), arguments));
+      };
+    }
+    scope.wrappers.NodeList = NodeList;
+    scope.addWrapNodeListMethod = addWrapNodeListMethod;
+    scope.wrapNodeList = wrapNodeList;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    scope.wrapHTMLCollection = scope.wrapNodeList;
+    scope.wrappers.HTMLCollection = scope.wrappers.NodeList;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var EventTarget = scope.wrappers.EventTarget;
+    var NodeList = scope.wrappers.NodeList;
+    var TreeScope = scope.TreeScope;
+    var assert = scope.assert;
+    var defineWrapGetter = scope.defineWrapGetter;
+    var enqueueMutation = scope.enqueueMutation;
+    var getTreeScope = scope.getTreeScope;
+    var isWrapper = scope.isWrapper;
+    var mixin = scope.mixin;
+    var registerTransientObservers = scope.registerTransientObservers;
+    var registerWrapper = scope.registerWrapper;
+    var setTreeScope = scope.setTreeScope;
+    var unsafeUnwrap = scope.unsafeUnwrap;
+    var unwrap = scope.unwrap;
+    var unwrapIfNeeded = scope.unwrapIfNeeded;
+    var wrap = scope.wrap;
+    var wrapIfNeeded = scope.wrapIfNeeded;
+    var wrappers = scope.wrappers;
+    function assertIsNodeWrapper(node) {
+      assert(node instanceof Node);
+    }
+    function createOneElementNodeList(node) {
+      var nodes = new NodeList();
+      nodes[0] = node;
+      nodes.length = 1;
+      return nodes;
+    }
+    var surpressMutations = false;
+    function enqueueRemovalForInsertedNodes(node, parent, nodes) {
+      enqueueMutation(parent, "childList", {
+        removedNodes: nodes,
+        previousSibling: node.previousSibling,
+        nextSibling: node.nextSibling
+      });
+    }
+    function enqueueRemovalForInsertedDocumentFragment(df, nodes) {
+      enqueueMutation(df, "childList", {
+        removedNodes: nodes
+      });
+    }
+    function collectNodes(node, parentNode, previousNode, nextNode) {
+      if (node instanceof DocumentFragment) {
+        var nodes = collectNodesForDocumentFragment(node);
+        surpressMutations = true;
+        for (var i = nodes.length - 1; i >= 0; i--) {
+          node.removeChild(nodes[i]);
+          nodes[i].parentNode_ = parentNode;
+        }
+        surpressMutations = false;
+        for (var i = 0; i < nodes.length; i++) {
+          nodes[i].previousSibling_ = nodes[i - 1] || previousNode;
+          nodes[i].nextSibling_ = nodes[i + 1] || nextNode;
+        }
+        if (previousNode) previousNode.nextSibling_ = nodes[0];
+        if (nextNode) nextNode.previousSibling_ = nodes[nodes.length - 1];
+        return nodes;
+      }
+      var nodes = createOneElementNodeList(node);
+      var oldParent = node.parentNode;
+      if (oldParent) {
+        oldParent.removeChild(node);
+      }
+      node.parentNode_ = parentNode;
+      node.previousSibling_ = previousNode;
+      node.nextSibling_ = nextNode;
+      if (previousNode) previousNode.nextSibling_ = node;
+      if (nextNode) nextNode.previousSibling_ = node;
+      return nodes;
+    }
+    function collectNodesNative(node) {
+      if (node instanceof DocumentFragment) return collectNodesForDocumentFragment(node);
+      var nodes = createOneElementNodeList(node);
+      var oldParent = node.parentNode;
+      if (oldParent) enqueueRemovalForInsertedNodes(node, oldParent, nodes);
+      return nodes;
+    }
+    function collectNodesForDocumentFragment(node) {
+      var nodes = new NodeList();
+      var i = 0;
+      for (var child = node.firstChild; child; child = child.nextSibling) {
+        nodes[i++] = child;
+      }
+      nodes.length = i;
+      enqueueRemovalForInsertedDocumentFragment(node, nodes);
+      return nodes;
+    }
+    function snapshotNodeList(nodeList) {
+      return nodeList;
+    }
+    function nodeWasAdded(node, treeScope) {
+      setTreeScope(node, treeScope);
+      node.nodeIsInserted_();
+    }
+    function nodesWereAdded(nodes, parent) {
+      var treeScope = getTreeScope(parent);
+      for (var i = 0; i < nodes.length; i++) {
+        nodeWasAdded(nodes[i], treeScope);
+      }
+    }
+    function nodeWasRemoved(node) {
+      setTreeScope(node, new TreeScope(node, null));
+    }
+    function nodesWereRemoved(nodes) {
+      for (var i = 0; i < nodes.length; i++) {
+        nodeWasRemoved(nodes[i]);
+      }
+    }
+    function ensureSameOwnerDocument(parent, child) {
+      var ownerDoc = parent.nodeType === Node.DOCUMENT_NODE ? parent : parent.ownerDocument;
+      if (ownerDoc !== child.ownerDocument) ownerDoc.adoptNode(child);
+    }
+    function adoptNodesIfNeeded(owner, nodes) {
+      if (!nodes.length) return;
+      var ownerDoc = owner.ownerDocument;
+      if (ownerDoc === nodes[0].ownerDocument) return;
+      for (var i = 0; i < nodes.length; i++) {
+        scope.adoptNodeNoRemove(nodes[i], ownerDoc);
+      }
+    }
+    function unwrapNodesForInsertion(owner, nodes) {
+      adoptNodesIfNeeded(owner, nodes);
+      var length = nodes.length;
+      if (length === 1) return unwrap(nodes[0]);
+      var df = unwrap(owner.ownerDocument.createDocumentFragment());
+      for (var i = 0; i < length; i++) {
+        df.appendChild(unwrap(nodes[i]));
+      }
+      return df;
+    }
+    function clearChildNodes(wrapper) {
+      if (wrapper.firstChild_ !== undefined) {
+        var child = wrapper.firstChild_;
+        while (child) {
+          var tmp = child;
+          child = child.nextSibling_;
+          tmp.parentNode_ = tmp.previousSibling_ = tmp.nextSibling_ = undefined;
+        }
+      }
+      wrapper.firstChild_ = wrapper.lastChild_ = undefined;
+    }
+    function removeAllChildNodes(wrapper) {
+      if (wrapper.invalidateShadowRenderer()) {
+        var childWrapper = wrapper.firstChild;
+        while (childWrapper) {
+          assert(childWrapper.parentNode === wrapper);
+          var nextSibling = childWrapper.nextSibling;
+          var childNode = unwrap(childWrapper);
+          var parentNode = childNode.parentNode;
+          if (parentNode) originalRemoveChild.call(parentNode, childNode);
+          childWrapper.previousSibling_ = childWrapper.nextSibling_ = childWrapper.parentNode_ = null;
+          childWrapper = nextSibling;
+        }
+        wrapper.firstChild_ = wrapper.lastChild_ = null;
+      } else {
+        var node = unwrap(wrapper);
+        var child = node.firstChild;
+        var nextSibling;
+        while (child) {
+          nextSibling = child.nextSibling;
+          originalRemoveChild.call(node, child);
+          child = nextSibling;
+        }
+      }
+    }
+    function invalidateParent(node) {
+      var p = node.parentNode;
+      return p && p.invalidateShadowRenderer();
+    }
+    function cleanupNodes(nodes) {
+      for (var i = 0, n; i < nodes.length; i++) {
+        n = nodes[i];
+        n.parentNode.removeChild(n);
+      }
+    }
+    var originalImportNode = document.importNode;
+    var originalCloneNode = window.Node.prototype.cloneNode;
+    function cloneNode(node, deep, opt_doc) {
+      var clone;
+      if (opt_doc) clone = wrap(originalImportNode.call(opt_doc, unsafeUnwrap(node), false)); else clone = wrap(originalCloneNode.call(unsafeUnwrap(node), false));
+      if (deep) {
+        for (var child = node.firstChild; child; child = child.nextSibling) {
+          clone.appendChild(cloneNode(child, true, opt_doc));
+        }
+        if (node instanceof wrappers.HTMLTemplateElement) {
+          var cloneContent = clone.content;
+          for (var child = node.content.firstChild; child; child = child.nextSibling) {
+            cloneContent.appendChild(cloneNode(child, true, opt_doc));
+          }
+        }
+      }
+      return clone;
+    }
+    function contains(self, child) {
+      if (!child || getTreeScope(self) !== getTreeScope(child)) return false;
+      for (var node = child; node; node = node.parentNode) {
+        if (node === self) return true;
+      }
+      return false;
+    }
+    var OriginalNode = window.Node;
+    function Node(original) {
+      assert(original instanceof OriginalNode);
+      EventTarget.call(this, original);
+      this.parentNode_ = undefined;
+      this.firstChild_ = undefined;
+      this.lastChild_ = undefined;
+      this.nextSibling_ = undefined;
+      this.previousSibling_ = undefined;
+      this.treeScope_ = undefined;
+    }
+    var OriginalDocumentFragment = window.DocumentFragment;
+    var originalAppendChild = OriginalNode.prototype.appendChild;
+    var originalCompareDocumentPosition = OriginalNode.prototype.compareDocumentPosition;
+    var originalInsertBefore = OriginalNode.prototype.insertBefore;
+    var originalRemoveChild = OriginalNode.prototype.removeChild;
+    var originalReplaceChild = OriginalNode.prototype.replaceChild;
+    var isIe = /Trident|Edge/.test(navigator.userAgent);
+    var removeChildOriginalHelper = isIe ? function(parent, child) {
+      try {
+        originalRemoveChild.call(parent, child);
+      } catch (ex) {
+        if (!(parent instanceof OriginalDocumentFragment)) throw ex;
+      }
+    } : function(parent, child) {
+      originalRemoveChild.call(parent, child);
+    };
+    Node.prototype = Object.create(EventTarget.prototype);
+    mixin(Node.prototype, {
+      appendChild: function(childWrapper) {
+        return this.insertBefore(childWrapper, null);
+      },
+      insertBefore: function(childWrapper, refWrapper) {
+        assertIsNodeWrapper(childWrapper);
+        var refNode;
+        if (refWrapper) {
+          if (isWrapper(refWrapper)) {
+            refNode = unwrap(refWrapper);
+          } else {
+            refNode = refWrapper;
+            refWrapper = wrap(refNode);
+          }
+        } else {
+          refWrapper = null;
+          refNode = null;
+        }
+        refWrapper && assert(refWrapper.parentNode === this);
+        var nodes;
+        var previousNode = refWrapper ? refWrapper.previousSibling : this.lastChild;
+        var useNative = !this.invalidateShadowRenderer() && !invalidateParent(childWrapper);
+        if (useNative) nodes = collectNodesNative(childWrapper); else nodes = collectNodes(childWrapper, this, previousNode, refWrapper);
+        if (useNative) {
+          ensureSameOwnerDocument(this, childWrapper);
+          clearChildNodes(this);
+          originalInsertBefore.call(unsafeUnwrap(this), unwrap(childWrapper), refNode);
+        } else {
+          if (!previousNode) this.firstChild_ = nodes[0];
+          if (!refWrapper) {
+            this.lastChild_ = nodes[nodes.length - 1];
+            if (this.firstChild_ === undefined) this.firstChild_ = this.firstChild;
+          }
+          var parentNode = refNode ? refNode.parentNode : unsafeUnwrap(this);
+          if (parentNode) {
+            originalInsertBefore.call(parentNode, unwrapNodesForInsertion(this, nodes), refNode);
+          } else {
+            adoptNodesIfNeeded(this, nodes);
+          }
+        }
+        enqueueMutation(this, "childList", {
+          addedNodes: nodes,
+          nextSibling: refWrapper,
+          previousSibling: previousNode
+        });
+        nodesWereAdded(nodes, this);
+        return childWrapper;
+      },
+      removeChild: function(childWrapper) {
+        assertIsNodeWrapper(childWrapper);
+        if (childWrapper.parentNode !== this) {
+          var found = false;
+          var childNodes = this.childNodes;
+          for (var ieChild = this.firstChild; ieChild; ieChild = ieChild.nextSibling) {
+            if (ieChild === childWrapper) {
+              found = true;
+              break;
+            }
+          }
+          if (!found) {
+            throw new Error("NotFoundError");
+          }
+        }
+        var childNode = unwrap(childWrapper);
+        var childWrapperNextSibling = childWrapper.nextSibling;
+        var childWrapperPreviousSibling = childWrapper.previousSibling;
+        if (this.invalidateShadowRenderer()) {
+          var thisFirstChild = this.firstChild;
+          var thisLastChild = this.lastChild;
+          var parentNode = childNode.parentNode;
+          if (parentNode) removeChildOriginalHelper(parentNode, childNode);
+          if (thisFirstChild === childWrapper) this.firstChild_ = childWrapperNextSibling;
+          if (thisLastChild === childWrapper) this.lastChild_ = childWrapperPreviousSibling;
+          if (childWrapperPreviousSibling) childWrapperPreviousSibling.nextSibling_ = childWrapperNextSibling;
+          if (childWrapperNextSibling) {
+            childWrapperNextSibling.previousSibling_ = childWrapperPreviousSibling;
+          }
+          childWrapper.previousSibling_ = childWrapper.nextSibling_ = childWrapper.parentNode_ = undefined;
+        } else {
+          clearChildNodes(this);
+          removeChildOriginalHelper(unsafeUnwrap(this), childNode);
+        }
+        if (!surpressMutations) {
+          enqueueMutation(this, "childList", {
+            removedNodes: createOneElementNodeList(childWrapper),
+            nextSibling: childWrapperNextSibling,
+            previousSibling: childWrapperPreviousSibling
+          });
+        }
+        registerTransientObservers(this, childWrapper);
+        return childWrapper;
+      },
+      replaceChild: function(newChildWrapper, oldChildWrapper) {
+        assertIsNodeWrapper(newChildWrapper);
+        var oldChildNode;
+        if (isWrapper(oldChildWrapper)) {
+          oldChildNode = unwrap(oldChildWrapper);
+        } else {
+          oldChildNode = oldChildWrapper;
+          oldChildWrapper = wrap(oldChildNode);
+        }
+        if (oldChildWrapper.parentNode !== this) {
+          throw new Error("NotFoundError");
+        }
+        var nextNode = oldChildWrapper.nextSibling;
+        var previousNode = oldChildWrapper.previousSibling;
+        var nodes;
+        var useNative = !this.invalidateShadowRenderer() && !invalidateParent(newChildWrapper);
+        if (useNative) {
+          nodes = collectNodesNative(newChildWrapper);
+        } else {
+          if (nextNode === newChildWrapper) nextNode = newChildWrapper.nextSibling;
+          nodes = collectNodes(newChildWrapper, this, previousNode, nextNode);
+        }
+        if (!useNative) {
+          if (this.firstChild === oldChildWrapper) this.firstChild_ = nodes[0];
+          if (this.lastChild === oldChildWrapper) this.lastChild_ = nodes[nodes.length - 1];
+          oldChildWrapper.previousSibling_ = oldChildWrapper.nextSibling_ = oldChildWrapper.parentNode_ = undefined;
+          if (oldChildNode.parentNode) {
+            originalReplaceChild.call(oldChildNode.parentNode, unwrapNodesForInsertion(this, nodes), oldChildNode);
+          }
+        } else {
+          ensureSameOwnerDocument(this, newChildWrapper);
+          clearChildNodes(this);
+          originalReplaceChild.call(unsafeUnwrap(this), unwrap(newChildWrapper), oldChildNode);
+        }
+        enqueueMutation(this, "childList", {
+          addedNodes: nodes,
+          removedNodes: createOneElementNodeList(oldChildWrapper),
+          nextSibling: nextNode,
+          previousSibling: previousNode
+        });
+        nodeWasRemoved(oldChildWrapper);
+        nodesWereAdded(nodes, this);
+        return oldChildWrapper;
+      },
+      nodeIsInserted_: function() {
+        for (var child = this.firstChild; child; child = child.nextSibling) {
+          child.nodeIsInserted_();
+        }
+      },
+      hasChildNodes: function() {
+        return this.firstChild !== null;
+      },
+      get parentNode() {
+        return this.parentNode_ !== undefined ? this.parentNode_ : wrap(unsafeUnwrap(this).parentNode);
+      },
+      get firstChild() {
+        return this.firstChild_ !== undefined ? this.firstChild_ : wrap(unsafeUnwrap(this).firstChild);
+      },
+      get lastChild() {
+        return this.lastChild_ !== undefined ? this.lastChild_ : wrap(unsafeUnwrap(this).lastChild);
+      },
+      get nextSibling() {
+        return this.nextSibling_ !== undefined ? this.nextSibling_ : wrap(unsafeUnwrap(this).nextSibling);
+      },
+      get previousSibling() {
+        return this.previousSibling_ !== undefined ? this.previousSibling_ : wrap(unsafeUnwrap(this).previousSibling);
+      },
+      get parentElement() {
+        var p = this.parentNode;
+        while (p && p.nodeType !== Node.ELEMENT_NODE) {
+          p = p.parentNode;
+        }
+        return p;
+      },
+      get textContent() {
+        var s = "";
+        for (var child = this.firstChild; child; child = child.nextSibling) {
+          if (child.nodeType != Node.COMMENT_NODE) {
+            s += child.textContent;
+          }
+        }
+        return s;
+      },
+      set textContent(textContent) {
+        if (textContent == null) textContent = "";
+        var removedNodes = snapshotNodeList(this.childNodes);
+        if (this.invalidateShadowRenderer()) {
+          removeAllChildNodes(this);
+          if (textContent !== "") {
+            var textNode = unsafeUnwrap(this).ownerDocument.createTextNode(textContent);
+            this.appendChild(textNode);
+          }
+        } else {
+          clearChildNodes(this);
+          unsafeUnwrap(this).textContent = textContent;
+        }
+        var addedNodes = snapshotNodeList(this.childNodes);
+        enqueueMutation(this, "childList", {
+          addedNodes: addedNodes,
+          removedNodes: removedNodes
+        });
+        nodesWereRemoved(removedNodes);
+        nodesWereAdded(addedNodes, this);
+      },
+      get childNodes() {
+        var wrapperList = new NodeList();
+        var i = 0;
+        for (var child = this.firstChild; child; child = child.nextSibling) {
+          wrapperList[i++] = child;
+        }
+        wrapperList.length = i;
+        return wrapperList;
+      },
+      cloneNode: function(deep) {
+        return cloneNode(this, deep);
+      },
+      contains: function(child) {
+        return contains(this, wrapIfNeeded(child));
+      },
+      compareDocumentPosition: function(otherNode) {
+        return originalCompareDocumentPosition.call(unsafeUnwrap(this), unwrapIfNeeded(otherNode));
+      },
+      normalize: function() {
+        var nodes = snapshotNodeList(this.childNodes);
+        var remNodes = [];
+        var s = "";
+        var modNode;
+        for (var i = 0, n; i < nodes.length; i++) {
+          n = nodes[i];
+          if (n.nodeType === Node.TEXT_NODE) {
+            if (!modNode && !n.data.length) this.removeChild(n); else if (!modNode) modNode = n; else {
+              s += n.data;
+              remNodes.push(n);
+            }
+          } else {
+            if (modNode && remNodes.length) {
+              modNode.data += s;
+              cleanupNodes(remNodes);
+            }
+            remNodes = [];
+            s = "";
+            modNode = null;
+            if (n.childNodes.length) n.normalize();
+          }
+        }
+        if (modNode && remNodes.length) {
+          modNode.data += s;
+          cleanupNodes(remNodes);
+        }
+      }
+    });
+    defineWrapGetter(Node, "ownerDocument");
+    registerWrapper(OriginalNode, Node, document.createDocumentFragment());
+    delete Node.prototype.querySelector;
+    delete Node.prototype.querySelectorAll;
+    Node.prototype = mixin(Object.create(EventTarget.prototype), Node.prototype);
+    scope.cloneNode = cloneNode;
+    scope.nodeWasAdded = nodeWasAdded;
+    scope.nodeWasRemoved = nodeWasRemoved;
+    scope.nodesWereAdded = nodesWereAdded;
+    scope.nodesWereRemoved = nodesWereRemoved;
+    scope.originalInsertBefore = originalInsertBefore;
+    scope.originalRemoveChild = originalRemoveChild;
+    scope.snapshotNodeList = snapshotNodeList;
+    scope.wrappers.Node = Node;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var HTMLCollection = scope.wrappers.HTMLCollection;
+    var NodeList = scope.wrappers.NodeList;
+    var getTreeScope = scope.getTreeScope;
+    var unsafeUnwrap = scope.unsafeUnwrap;
+    var wrap = scope.wrap;
+    var originalDocumentQuerySelector = document.querySelector;
+    var originalElementQuerySelector = document.documentElement.querySelector;
+    var originalDocumentQuerySelectorAll = document.querySelectorAll;
+    var originalElementQuerySelectorAll = document.documentElement.querySelectorAll;
+    var originalDocumentGetElementsByTagName = document.getElementsByTagName;
+    var originalElementGetElementsByTagName = document.documentElement.getElementsByTagName;
+    var originalDocumentGetElementsByTagNameNS = document.getElementsByTagNameNS;
+    var originalElementGetElementsByTagNameNS = document.documentElement.getElementsByTagNameNS;
+    var OriginalElement = window.Element;
+    var OriginalDocument = window.HTMLDocument || window.Document;
+    function filterNodeList(list, index, result, deep) {
+      var wrappedItem = null;
+      var root = null;
+      for (var i = 0, length = list.length; i < length; i++) {
+        wrappedItem = wrap(list[i]);
+        if (!deep && (root = getTreeScope(wrappedItem).root)) {
+          if (root instanceof scope.wrappers.ShadowRoot) {
+            continue;
+          }
+        }
+        result[index++] = wrappedItem;
+      }
+      return index;
+    }
+    function shimSelector(selector) {
+      return String(selector).replace(/\/deep\/|::shadow/g, " ");
+    }
+    function shimMatchesSelector(selector) {
+      return String(selector).replace(/:host\(([^\s]+)\)/g, "$1").replace(/([^\s]):host/g, "$1").replace(":host", "*").replace(/\^|\/shadow\/|\/shadow-deep\/|::shadow|\/deep\/|::content/g, " ");
+    }
+    function findOne(node, selector) {
+      var m, el = node.firstElementChild;
+      while (el) {
+        if (el.matches(selector)) return el;
+        m = findOne(el, selector);
+        if (m) return m;
+        el = el.nextElementSibling;
+      }
+      return null;
+    }
+    function matchesSelector(el, selector) {
+      return el.matches(selector);
+    }
+    var XHTML_NS = "http://www.w3.org/1999/xhtml";
+    function matchesTagName(el, localName, localNameLowerCase) {
+      var ln = el.localName;
+      return ln === localName || ln === localNameLowerCase && el.namespaceURI === XHTML_NS;
+    }
+    function matchesEveryThing() {
+      return true;
+    }
+    function matchesLocalNameOnly(el, ns, localName) {
+      return el.localName === localName;
+    }
+    function matchesNameSpace(el, ns) {
+      return el.namespaceURI === ns;
+    }
+    function matchesLocalNameNS(el, ns, localName) {
+      return el.namespaceURI === ns && el.localName === localName;
+    }
+    function findElements(node, index, result, p, arg0, arg1) {
+      var el = node.firstElementChild;
+      while (el) {
+        if (p(el, arg0, arg1)) result[index++] = el;
+        index = findElements(el, index, result, p, arg0, arg1);
+        el = el.nextElementSibling;
+      }
+      return index;
+    }
+    function querySelectorAllFiltered(p, index, result, selector, deep) {
+      var target = unsafeUnwrap(this);
+      var list;
+      var root = getTreeScope(this).root;
+      if (root instanceof scope.wrappers.ShadowRoot) {
+        return findElements(this, index, result, p, selector, null);
+      } else if (target instanceof OriginalElement) {
+        list = originalElementQuerySelectorAll.call(target, selector);
+      } else if (target instanceof OriginalDocument) {
+        list = originalDocumentQuerySelectorAll.call(target, selector);
+      } else {
+        return findElements(this, index, result, p, selector, null);
+      }
+      return filterNodeList(list, index, result, deep);
+    }
+    var SelectorsInterface = {
+      querySelector: function(selector) {
+        var shimmed = shimSelector(selector);
+        var deep = shimmed !== selector;
+        selector = shimmed;
+        var target = unsafeUnwrap(this);
+        var wrappedItem;
+        var root = getTreeScope(this).root;
+        if (root instanceof scope.wrappers.ShadowRoot) {
+          return findOne(this, selector);
+        } else if (target instanceof OriginalElement) {
+          wrappedItem = wrap(originalElementQuerySelector.call(target, selector));
+        } else if (target instanceof OriginalDocument) {
+          wrappedItem = wrap(originalDocumentQuerySelector.call(target, selector));
+        } else {
+          return findOne(this, selector);
+        }
+        if (!wrappedItem) {
+          return wrappedItem;
+        } else if (!deep && (root = getTreeScope(wrappedItem).root)) {
+          if (root instanceof scope.wrappers.ShadowRoot) {
+            return findOne(this, selector);
+          }
+        }
+        return wrappedItem;
+      },
+      querySelectorAll: function(selector) {
+        var shimmed = shimSelector(selector);
+        var deep = shimmed !== selector;
+        selector = shimmed;
+        var result = new NodeList();
+        result.length = querySelectorAllFiltered.call(this, matchesSelector, 0, result, selector, deep);
+        return result;
+      }
+    };
+    var MatchesInterface = {
+      matches: function(selector) {
+        selector = shimMatchesSelector(selector);
+        return scope.originalMatches.call(unsafeUnwrap(this), selector);
+      }
+    };
+    function getElementsByTagNameFiltered(p, index, result, localName, lowercase) {
+      var target = unsafeUnwrap(this);
+      var list;
+      var root = getTreeScope(this).root;
+      if (root instanceof scope.wrappers.ShadowRoot) {
+        return findElements(this, index, result, p, localName, lowercase);
+      } else if (target instanceof OriginalElement) {
+        list = originalElementGetElementsByTagName.call(target, localName, lowercase);
+      } else if (target instanceof OriginalDocument) {
+        list = originalDocumentGetElementsByTagName.call(target, localName, lowercase);
+      } else {
+        return findElements(this, index, result, p, localName, lowercase);
+      }
+      return filterNodeList(list, index, result, false);
+    }
+    function getElementsByTagNameNSFiltered(p, index, result, ns, localName) {
+      var target = unsafeUnwrap(this);
+      var list;
+      var root = getTreeScope(this).root;
+      if (root instanceof scope.wrappers.ShadowRoot) {
+        return findElements(this, index, result, p, ns, localName);
+      } else if (target instanceof OriginalElement) {
+        list = originalElementGetElementsByTagNameNS.call(target, ns, localName);
+      } else if (target instanceof OriginalDocument) {
+        list = originalDocumentGetElementsByTagNameNS.call(target, ns, localName);
+      } else {
+        return findElements(this, index, result, p, ns, localName);
+      }
+      return filterNodeList(list, index, result, false);
+    }
+    var GetElementsByInterface = {
+      getElementsByTagName: function(localName) {
+        var result = new HTMLCollection();
+        var match = localName === "*" ? matchesEveryThing : matchesTagName;
+        result.length = getElementsByTagNameFiltered.call(this, match, 0, result, localName, localName.toLowerCase());
+        return result;
+      },
+      getElementsByClassName: function(className) {
+        return this.querySelectorAll("." + className);
+      },
+      getElementsByTagNameNS: function(ns, localName) {
+        var result = new HTMLCollection();
+        var match = null;
+        if (ns === "*") {
+          match = localName === "*" ? matchesEveryThing : matchesLocalNameOnly;
+        } else {
+          match = localName === "*" ? matchesNameSpace : matchesLocalNameNS;
+        }
+        result.length = getElementsByTagNameNSFiltered.call(this, match, 0, result, ns || null, localName);
+        return result;
+      }
+    };
+    scope.GetElementsByInterface = GetElementsByInterface;
+    scope.SelectorsInterface = SelectorsInterface;
+    scope.MatchesInterface = MatchesInterface;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var NodeList = scope.wrappers.NodeList;
+    function forwardElement(node) {
+      while (node && node.nodeType !== Node.ELEMENT_NODE) {
+        node = node.nextSibling;
+      }
+      return node;
+    }
+    function backwardsElement(node) {
+      while (node && node.nodeType !== Node.ELEMENT_NODE) {
+        node = node.previousSibling;
+      }
+      return node;
+    }
+    var ParentNodeInterface = {
+      get firstElementChild() {
+        return forwardElement(this.firstChild);
+      },
+      get lastElementChild() {
+        return backwardsElement(this.lastChild);
+      },
+      get childElementCount() {
+        var count = 0;
+        for (var child = this.firstElementChild; child; child = child.nextElementSibling) {
+          count++;
+        }
+        return count;
+      },
+      get children() {
+        var wrapperList = new NodeList();
+        var i = 0;
+        for (var child = this.firstElementChild; child; child = child.nextElementSibling) {
+          wrapperList[i++] = child;
+        }
+        wrapperList.length = i;
+        return wrapperList;
+      },
+      remove: function() {
+        var p = this.parentNode;
+        if (p) p.removeChild(this);
+      }
+    };
+    var ChildNodeInterface = {
+      get nextElementSibling() {
+        return forwardElement(this.nextSibling);
+      },
+      get previousElementSibling() {
+        return backwardsElement(this.previousSibling);
+      }
+    };
+    scope.ChildNodeInterface = ChildNodeInterface;
+    scope.ParentNodeInterface = ParentNodeInterface;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var ChildNodeInterface = scope.ChildNodeInterface;
+    var Node = scope.wrappers.Node;
+    var enqueueMutation = scope.enqueueMutation;
+    var mixin = scope.mixin;
+    var registerWrapper = scope.registerWrapper;
+    var unsafeUnwrap = scope.unsafeUnwrap;
+    var OriginalCharacterData = window.CharacterData;
+    function CharacterData(node) {
+      Node.call(this, node);
+    }
+    CharacterData.prototype = Object.create(Node.prototype);
+    mixin(CharacterData.prototype, {
+      get textContent() {
+        return this.data;
+      },
+      set textContent(value) {
+        this.data = value;
+      },
+      get data() {
+        return unsafeUnwrap(this).data;
+      },
+      set data(value) {
+        var oldValue = unsafeUnwrap(this).data;
+        enqueueMutation(this, "characterData", {
+          oldValue: oldValue
+        });
+        unsafeUnwrap(this).data = value;
+      }
+    });
+    mixin(CharacterData.prototype, ChildNodeInterface);
+    registerWrapper(OriginalCharacterData, CharacterData, document.createTextNode(""));
+    scope.wrappers.CharacterData = CharacterData;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var CharacterData = scope.wrappers.CharacterData;
+    var enqueueMutation = scope.enqueueMutation;
+    var mixin = scope.mixin;
+    var registerWrapper = scope.registerWrapper;
+    function toUInt32(x) {
+      return x >>> 0;
+    }
+    var OriginalText = window.Text;
+    function Text(node) {
+      CharacterData.call(this, node);
+    }
+    Text.prototype = Object.create(CharacterData.prototype);
+    mixin(Text.prototype, {
+      splitText: function(offset) {
+        offset = toUInt32(offset);
+        var s = this.data;
+        if (offset > s.length) throw new Error("IndexSizeError");
+        var head = s.slice(0, offset);
+        var tail = s.slice(offset);
+        this.data = head;
+        var newTextNode = this.ownerDocument.createTextNode(tail);
+        if (this.parentNode) this.parentNode.insertBefore(newTextNode, this.nextSibling);
+        return newTextNode;
+      }
+    });
+    registerWrapper(OriginalText, Text, document.createTextNode(""));
+    scope.wrappers.Text = Text;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    if (!window.DOMTokenList) {
+      console.warn("Missing DOMTokenList prototype, please include a " + "compatible classList polyfill such as http://goo.gl/uTcepH.");
+      return;
+    }
+    var unsafeUnwrap = scope.unsafeUnwrap;
+    var enqueueMutation = scope.enqueueMutation;
+    function getClass(el) {
+      return unsafeUnwrap(el).getAttribute("class");
+    }
+    function enqueueClassAttributeChange(el, oldValue) {
+      enqueueMutation(el, "attributes", {
+        name: "class",
+        namespace: null,
+        oldValue: oldValue
+      });
+    }
+    function invalidateClass(el) {
+      scope.invalidateRendererBasedOnAttribute(el, "class");
+    }
+    function changeClass(tokenList, method, args) {
+      var ownerElement = tokenList.ownerElement_;
+      if (ownerElement == null) {
+        return method.apply(tokenList, args);
+      }
+      var oldValue = getClass(ownerElement);
+      var retv = method.apply(tokenList, args);
+      if (getClass(ownerElement) !== oldValue) {
+        enqueueClassAttributeChange(ownerElement, oldValue);
+        invalidateClass(ownerElement);
+      }
+      return retv;
+    }
+    var oldAdd = DOMTokenList.prototype.add;
+    DOMTokenList.prototype.add = function() {
+      changeClass(this, oldAdd, arguments);
+    };
+    var oldRemove = DOMTokenList.prototype.remove;
+    DOMTokenList.prototype.remove = function() {
+      changeClass(this, oldRemove, arguments);
+    };
+    var oldToggle = DOMTokenList.prototype.toggle;
+    DOMTokenList.prototype.toggle = function() {
+      return changeClass(this, oldToggle, arguments);
+    };
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var ChildNodeInterface = scope.ChildNodeInterface;
+    var GetElementsByInterface = scope.GetElementsByInterface;
+    var Node = scope.wrappers.Node;
+    var ParentNodeInterface = scope.ParentNodeInterface;
+    var SelectorsInterface = scope.SelectorsInterface;
+    var MatchesInterface = scope.MatchesInterface;
+    var addWrapNodeListMethod = scope.addWrapNodeListMethod;
+    var enqueueMutation = scope.enqueueMutation;
+    var mixin = scope.mixin;
+    var oneOf = scope.oneOf;
+    var registerWrapper = scope.registerWrapper;
+    var unsafeUnwrap = scope.unsafeUnwrap;
+    var wrappers = scope.wrappers;
+    var OriginalElement = window.Element;
+    var matchesNames = [ "matches", "mozMatchesSelector", "msMatchesSelector", "webkitMatchesSelector" ].filter(function(name) {
+      return OriginalElement.prototype[name];
+    });
+    var matchesName = matchesNames[0];
+    var originalMatches = OriginalElement.prototype[matchesName];
+    function invalidateRendererBasedOnAttribute(element, name) {
+      var p = element.parentNode;
+      if (!p || !p.shadowRoot) return;
+      var renderer = scope.getRendererForHost(p);
+      if (renderer.dependsOnAttribute(name)) renderer.invalidate();
+    }
+    function enqueAttributeChange(element, name, oldValue) {
+      enqueueMutation(element, "attributes", {
+        name: name,
+        namespace: null,
+        oldValue: oldValue
+      });
+    }
+    var classListTable = new WeakMap();
+    function Element(node) {
+      Node.call(this, node);
+    }
+    Element.prototype = Object.create(Node.prototype);
+    mixin(Element.prototype, {
+      createShadowRoot: function() {
+        var newShadowRoot = new wrappers.ShadowRoot(this);
+        unsafeUnwrap(this).polymerShadowRoot_ = newShadowRoot;
+        var renderer = scope.getRendererForHost(this);
+        renderer.invalidate();
+        return newShadowRoot;
+      },
+      get shadowRoot() {
+        return unsafeUnwrap(this).polymerShadowRoot_ || null;
+      },
+      setAttribute: function(name, value) {
+        var oldValue = unsafeUnwrap(this).getAttribute(name);
+        unsafeUnwrap(this).setAttribute(name, value);
+        enqueAttributeChange(this, name, oldValue);
+        invalidateRendererBasedOnAttribute(this, name);
+      },
+      removeAttribute: function(name) {
+        var oldValue = unsafeUnwrap(this).getAttribute(name);
+        unsafeUnwrap(this).removeAttribute(name);
+        enqueAttributeChange(this, name, oldValue);
+        invalidateRendererBasedOnAttribute(this, name);
+      },
+      get classList() {
+        var list = classListTable.get(this);
+        if (!list) {
+          list = unsafeUnwrap(this).classList;
+          if (!list) return;
+          list.ownerElement_ = this;
+          classListTable.set(this, list);
+        }
+        return list;
+      },
+      get className() {
+        return unsafeUnwrap(this).className;
+      },
+      set className(v) {
+        this.setAttribute("class", v);
+      },
+      get id() {
+        return unsafeUnwrap(this).id;
+      },
+      set id(v) {
+        this.setAttribute("id", v);
+      }
+    });
+    matchesNames.forEach(function(name) {
+      if (name !== "matches") {
+        Element.prototype[name] = function(selector) {
+          return this.matches(selector);
+        };
+      }
+    });
+    if (OriginalElement.prototype.webkitCreateShadowRoot) {
+      Element.prototype.webkitCreateShadowRoot = Element.prototype.createShadowRoot;
+    }
+    mixin(Element.prototype, ChildNodeInterface);
+    mixin(Element.prototype, GetElementsByInterface);
+    mixin(Element.prototype, ParentNodeInterface);
+    mixin(Element.prototype, SelectorsInterface);
+    mixin(Element.prototype, MatchesInterface);
+    registerWrapper(OriginalElement, Element, document.createElementNS(null, "x"));
+    scope.invalidateRendererBasedOnAttribute = invalidateRendererBasedOnAttribute;
+    scope.matchesNames = matchesNames;
+    scope.originalMatches = originalMatches;
+    scope.wrappers.Element = Element;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var Element = scope.wrappers.Element;
+    var defineGetter = scope.defineGetter;
+    var enqueueMutation = scope.enqueueMutation;
+    var mixin = scope.mixin;
+    var nodesWereAdded = scope.nodesWereAdded;
+    var nodesWereRemoved = scope.nodesWereRemoved;
+    var registerWrapper = scope.registerWrapper;
+    var snapshotNodeList = scope.snapshotNodeList;
+    var unsafeUnwrap = scope.unsafeUnwrap;
+    var unwrap = scope.unwrap;
+    var wrap = scope.wrap;
+    var wrappers = scope.wrappers;
+    var escapeAttrRegExp = /[&\u00A0"]/g;
+    var escapeDataRegExp = /[&\u00A0<>]/g;
+    function escapeReplace(c) {
+      switch (c) {
+       case "&":
+        return "&";
+
+       case "<":
+        return "<";
+
+       case ">":
+        return ">";
+
+       case '"':
+        return """;
+
+       case " ":
+        return " ";
+      }
+    }
+    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) {
+      switch (node.nodeType) {
+       case Node.ELEMENT_NODE:
+        var tagName = node.tagName.toLowerCase();
+        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) + "";
+
+       case Node.TEXT_NODE:
+        var data = node.data;
+        if (parentNode && plaintextParents[parentNode.localName]) return data;
+        return escapeData(data);
+
+       case Node.COMMENT_NODE:
+        return "";
+
+       default:
+        console.error(node);
+        throw new Error("not implemented");
+      }
+    }
+    function getInnerHTML(node) {
+      if (node instanceof wrappers.HTMLTemplateElement) node = node.content;
+      var s = "";
+      for (var child = node.firstChild; child; child = child.nextSibling) {
+        s += getOuterHTML(child, node);
+      }
+      return s;
+    }
+    function setInnerHTML(node, value, opt_tagName) {
+      var tagName = opt_tagName || "div";
+      node.textContent = "";
+      var tempElement = unwrap(node.ownerDocument.createElement(tagName));
+      tempElement.innerHTML = value;
+      var firstChild;
+      while (firstChild = tempElement.firstChild) {
+        node.appendChild(wrap(firstChild));
+      }
+    }
+    var oldIe = /MSIE/.test(navigator.userAgent);
+    var OriginalHTMLElement = window.HTMLElement;
+    var OriginalHTMLTemplateElement = window.HTMLTemplateElement;
+    function HTMLElement(node) {
+      Element.call(this, node);
+    }
+    HTMLElement.prototype = Object.create(Element.prototype);
+    mixin(HTMLElement.prototype, {
+      get innerHTML() {
+        return getInnerHTML(this);
+      },
+      set innerHTML(value) {
+        if (oldIe && plaintextParents[this.localName]) {
+          this.textContent = value;
+          return;
+        }
+        var removedNodes = snapshotNodeList(this.childNodes);
+        if (this.invalidateShadowRenderer()) {
+          if (this instanceof wrappers.HTMLTemplateElement) setInnerHTML(this.content, value); else setInnerHTML(this, value, this.tagName);
+        } else if (!OriginalHTMLTemplateElement && this instanceof wrappers.HTMLTemplateElement) {
+          setInnerHTML(this.content, value);
+        } else {
+          unsafeUnwrap(this).innerHTML = value;
+        }
+        var addedNodes = snapshotNodeList(this.childNodes);
+        enqueueMutation(this, "childList", {
+          addedNodes: addedNodes,
+          removedNodes: removedNodes
+        });
+        nodesWereRemoved(removedNodes);
+        nodesWereAdded(addedNodes, this);
+      },
+      get outerHTML() {
+        return getOuterHTML(this, this.parentNode);
+      },
+      set outerHTML(value) {
+        var p = this.parentNode;
+        if (p) {
+          p.invalidateShadowRenderer();
+          var df = frag(p, value);
+          p.replaceChild(df, this);
+        }
+      },
+      insertAdjacentHTML: function(position, text) {
+        var contextElement, refNode;
+        switch (String(position).toLowerCase()) {
+         case "beforebegin":
+          contextElement = this.parentNode;
+          refNode = this;
+          break;
+
+         case "afterend":
+          contextElement = this.parentNode;
+          refNode = this.nextSibling;
+          break;
+
+         case "afterbegin":
+          contextElement = this;
+          refNode = this.firstChild;
+          break;
+
+         case "beforeend":
+          contextElement = this;
+          refNode = null;
+          break;
+
+         default:
+          return;
+        }
+        var df = frag(contextElement, text);
+        contextElement.insertBefore(df, refNode);
+      },
+      get hidden() {
+        return this.hasAttribute("hidden");
+      },
+      set hidden(v) {
+        if (v) {
+          this.setAttribute("hidden", "");
+        } else {
+          this.removeAttribute("hidden");
+        }
+      }
+    });
+    function frag(contextElement, html) {
+      var p = unwrap(contextElement.cloneNode(false));
+      p.innerHTML = html;
+      var df = unwrap(document.createDocumentFragment());
+      var c;
+      while (c = p.firstChild) {
+        df.appendChild(c);
+      }
+      return wrap(df);
+    }
+    function getter(name) {
+      return function() {
+        scope.renderAllPending();
+        return unsafeUnwrap(this)[name];
+      };
+    }
+    function getterRequiresRendering(name) {
+      defineGetter(HTMLElement, name, getter(name));
+    }
+    [ "clientHeight", "clientLeft", "clientTop", "clientWidth", "offsetHeight", "offsetLeft", "offsetTop", "offsetWidth", "scrollHeight", "scrollWidth" ].forEach(getterRequiresRendering);
+    function getterAndSetterRequiresRendering(name) {
+      Object.defineProperty(HTMLElement.prototype, name, {
+        get: getter(name),
+        set: function(v) {
+          scope.renderAllPending();
+          unsafeUnwrap(this)[name] = v;
+        },
+        configurable: true,
+        enumerable: true
+      });
+    }
+    [ "scrollLeft", "scrollTop" ].forEach(getterAndSetterRequiresRendering);
+    function methodRequiresRendering(name) {
+      Object.defineProperty(HTMLElement.prototype, name, {
+        value: function() {
+          scope.renderAllPending();
+          return unsafeUnwrap(this)[name].apply(unsafeUnwrap(this), arguments);
+        },
+        configurable: true,
+        enumerable: true
+      });
+    }
+    [ "getBoundingClientRect", "getClientRects", "scrollIntoView" ].forEach(methodRequiresRendering);
+    registerWrapper(OriginalHTMLElement, HTMLElement, document.createElement("b"));
+    scope.wrappers.HTMLElement = HTMLElement;
+    scope.getInnerHTML = getInnerHTML;
+    scope.setInnerHTML = setInnerHTML;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var HTMLElement = scope.wrappers.HTMLElement;
+    var mixin = scope.mixin;
+    var registerWrapper = scope.registerWrapper;
+    var unsafeUnwrap = scope.unsafeUnwrap;
+    var wrap = scope.wrap;
+    var OriginalHTMLCanvasElement = window.HTMLCanvasElement;
+    function HTMLCanvasElement(node) {
+      HTMLElement.call(this, node);
+    }
+    HTMLCanvasElement.prototype = Object.create(HTMLElement.prototype);
+    mixin(HTMLCanvasElement.prototype, {
+      getContext: function() {
+        var context = unsafeUnwrap(this).getContext.apply(unsafeUnwrap(this), arguments);
+        return context && wrap(context);
+      }
+    });
+    registerWrapper(OriginalHTMLCanvasElement, HTMLCanvasElement, document.createElement("canvas"));
+    scope.wrappers.HTMLCanvasElement = HTMLCanvasElement;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var HTMLElement = scope.wrappers.HTMLElement;
+    var mixin = scope.mixin;
+    var registerWrapper = scope.registerWrapper;
+    var OriginalHTMLContentElement = window.HTMLContentElement;
+    function HTMLContentElement(node) {
+      HTMLElement.call(this, node);
+    }
+    HTMLContentElement.prototype = Object.create(HTMLElement.prototype);
+    mixin(HTMLContentElement.prototype, {
+      constructor: HTMLContentElement,
+      get select() {
+        return this.getAttribute("select");
+      },
+      set select(value) {
+        this.setAttribute("select", value);
+      },
+      setAttribute: function(n, v) {
+        HTMLElement.prototype.setAttribute.call(this, n, v);
+        if (String(n).toLowerCase() === "select") this.invalidateShadowRenderer(true);
+      }
+    });
+    if (OriginalHTMLContentElement) registerWrapper(OriginalHTMLContentElement, HTMLContentElement);
+    scope.wrappers.HTMLContentElement = HTMLContentElement;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var HTMLElement = scope.wrappers.HTMLElement;
+    var mixin = scope.mixin;
+    var registerWrapper = scope.registerWrapper;
+    var wrapHTMLCollection = scope.wrapHTMLCollection;
+    var unwrap = scope.unwrap;
+    var OriginalHTMLFormElement = window.HTMLFormElement;
+    function HTMLFormElement(node) {
+      HTMLElement.call(this, node);
+    }
+    HTMLFormElement.prototype = Object.create(HTMLElement.prototype);
+    mixin(HTMLFormElement.prototype, {
+      get elements() {
+        return wrapHTMLCollection(unwrap(this).elements);
+      }
+    });
+    registerWrapper(OriginalHTMLFormElement, HTMLFormElement, document.createElement("form"));
+    scope.wrappers.HTMLFormElement = HTMLFormElement;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var HTMLElement = scope.wrappers.HTMLElement;
+    var registerWrapper = scope.registerWrapper;
+    var unwrap = scope.unwrap;
+    var rewrap = scope.rewrap;
+    var OriginalHTMLImageElement = window.HTMLImageElement;
+    function HTMLImageElement(node) {
+      HTMLElement.call(this, node);
+    }
+    HTMLImageElement.prototype = Object.create(HTMLElement.prototype);
+    registerWrapper(OriginalHTMLImageElement, HTMLImageElement, document.createElement("img"));
+    function Image(width, height) {
+      if (!(this instanceof Image)) {
+        throw new TypeError("DOM object constructor cannot be called as a function.");
+      }
+      var node = unwrap(document.createElement("img"));
+      HTMLElement.call(this, node);
+      rewrap(node, this);
+      if (width !== undefined) node.width = width;
+      if (height !== undefined) node.height = height;
+    }
+    Image.prototype = HTMLImageElement.prototype;
+    scope.wrappers.HTMLImageElement = HTMLImageElement;
+    scope.wrappers.Image = Image;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var HTMLElement = scope.wrappers.HTMLElement;
+    var mixin = scope.mixin;
+    var NodeList = scope.wrappers.NodeList;
+    var registerWrapper = scope.registerWrapper;
+    var OriginalHTMLShadowElement = window.HTMLShadowElement;
+    function HTMLShadowElement(node) {
+      HTMLElement.call(this, node);
+    }
+    HTMLShadowElement.prototype = Object.create(HTMLElement.prototype);
+    HTMLShadowElement.prototype.constructor = HTMLShadowElement;
+    if (OriginalHTMLShadowElement) registerWrapper(OriginalHTMLShadowElement, HTMLShadowElement);
+    scope.wrappers.HTMLShadowElement = HTMLShadowElement;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var HTMLElement = scope.wrappers.HTMLElement;
+    var mixin = scope.mixin;
+    var registerWrapper = scope.registerWrapper;
+    var unsafeUnwrap = scope.unsafeUnwrap;
+    var unwrap = scope.unwrap;
+    var wrap = scope.wrap;
+    var contentTable = new WeakMap();
+    var templateContentsOwnerTable = new WeakMap();
+    function getTemplateContentsOwner(doc) {
+      if (!doc.defaultView) return doc;
+      var d = templateContentsOwnerTable.get(doc);
+      if (!d) {
+        d = doc.implementation.createHTMLDocument("");
+        while (d.lastChild) {
+          d.removeChild(d.lastChild);
+        }
+        templateContentsOwnerTable.set(doc, d);
+      }
+      return d;
+    }
+    function extractContent(templateElement) {
+      var doc = getTemplateContentsOwner(templateElement.ownerDocument);
+      var df = unwrap(doc.createDocumentFragment());
+      var child;
+      while (child = templateElement.firstChild) {
+        df.appendChild(child);
+      }
+      return df;
+    }
+    var OriginalHTMLTemplateElement = window.HTMLTemplateElement;
+    function HTMLTemplateElement(node) {
+      HTMLElement.call(this, node);
+      if (!OriginalHTMLTemplateElement) {
+        var content = extractContent(node);
+        contentTable.set(this, wrap(content));
+      }
+    }
+    HTMLTemplateElement.prototype = Object.create(HTMLElement.prototype);
+    mixin(HTMLTemplateElement.prototype, {
+      constructor: HTMLTemplateElement,
+      get content() {
+        if (OriginalHTMLTemplateElement) return wrap(unsafeUnwrap(this).content);
+        return contentTable.get(this);
+      }
+    });
+    if (OriginalHTMLTemplateElement) registerWrapper(OriginalHTMLTemplateElement, HTMLTemplateElement);
+    scope.wrappers.HTMLTemplateElement = HTMLTemplateElement;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var HTMLElement = scope.wrappers.HTMLElement;
+    var registerWrapper = scope.registerWrapper;
+    var OriginalHTMLMediaElement = window.HTMLMediaElement;
+    if (!OriginalHTMLMediaElement) return;
+    function HTMLMediaElement(node) {
+      HTMLElement.call(this, node);
+    }
+    HTMLMediaElement.prototype = Object.create(HTMLElement.prototype);
+    registerWrapper(OriginalHTMLMediaElement, HTMLMediaElement, document.createElement("audio"));
+    scope.wrappers.HTMLMediaElement = HTMLMediaElement;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var HTMLMediaElement = scope.wrappers.HTMLMediaElement;
+    var registerWrapper = scope.registerWrapper;
+    var unwrap = scope.unwrap;
+    var rewrap = scope.rewrap;
+    var OriginalHTMLAudioElement = window.HTMLAudioElement;
+    if (!OriginalHTMLAudioElement) return;
+    function HTMLAudioElement(node) {
+      HTMLMediaElement.call(this, node);
+    }
+    HTMLAudioElement.prototype = Object.create(HTMLMediaElement.prototype);
+    registerWrapper(OriginalHTMLAudioElement, HTMLAudioElement, document.createElement("audio"));
+    function Audio(src) {
+      if (!(this instanceof Audio)) {
+        throw new TypeError("DOM object constructor cannot be called as a function.");
+      }
+      var node = unwrap(document.createElement("audio"));
+      HTMLMediaElement.call(this, node);
+      rewrap(node, this);
+      node.setAttribute("preload", "auto");
+      if (src !== undefined) node.setAttribute("src", src);
+    }
+    Audio.prototype = HTMLAudioElement.prototype;
+    scope.wrappers.HTMLAudioElement = HTMLAudioElement;
+    scope.wrappers.Audio = Audio;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var HTMLElement = scope.wrappers.HTMLElement;
+    var mixin = scope.mixin;
+    var registerWrapper = scope.registerWrapper;
+    var rewrap = scope.rewrap;
+    var unwrap = scope.unwrap;
+    var wrap = scope.wrap;
+    var OriginalHTMLOptionElement = window.HTMLOptionElement;
+    function trimText(s) {
+      return s.replace(/\s+/g, " ").trim();
+    }
+    function HTMLOptionElement(node) {
+      HTMLElement.call(this, node);
+    }
+    HTMLOptionElement.prototype = Object.create(HTMLElement.prototype);
+    mixin(HTMLOptionElement.prototype, {
+      get text() {
+        return trimText(this.textContent);
+      },
+      set text(value) {
+        this.textContent = trimText(String(value));
+      },
+      get form() {
+        return wrap(unwrap(this).form);
+      }
+    });
+    registerWrapper(OriginalHTMLOptionElement, HTMLOptionElement, document.createElement("option"));
+    function Option(text, value, defaultSelected, selected) {
+      if (!(this instanceof Option)) {
+        throw new TypeError("DOM object constructor cannot be called as a function.");
+      }
+      var node = unwrap(document.createElement("option"));
+      HTMLElement.call(this, node);
+      rewrap(node, this);
+      if (text !== undefined) node.text = text;
+      if (value !== undefined) node.setAttribute("value", value);
+      if (defaultSelected === true) node.setAttribute("selected", "");
+      node.selected = selected === true;
+    }
+    Option.prototype = HTMLOptionElement.prototype;
+    scope.wrappers.HTMLOptionElement = HTMLOptionElement;
+    scope.wrappers.Option = Option;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var HTMLElement = scope.wrappers.HTMLElement;
+    var mixin = scope.mixin;
+    var registerWrapper = scope.registerWrapper;
+    var unwrap = scope.unwrap;
+    var wrap = scope.wrap;
+    var OriginalHTMLSelectElement = window.HTMLSelectElement;
+    function HTMLSelectElement(node) {
+      HTMLElement.call(this, node);
+    }
+    HTMLSelectElement.prototype = Object.create(HTMLElement.prototype);
+    mixin(HTMLSelectElement.prototype, {
+      add: function(element, before) {
+        if (typeof before === "object") before = unwrap(before);
+        unwrap(this).add(unwrap(element), before);
+      },
+      remove: function(indexOrNode) {
+        if (indexOrNode === undefined) {
+          HTMLElement.prototype.remove.call(this);
+          return;
+        }
+        if (typeof indexOrNode === "object") indexOrNode = unwrap(indexOrNode);
+        unwrap(this).remove(indexOrNode);
+      },
+      get form() {
+        return wrap(unwrap(this).form);
+      }
+    });
+    registerWrapper(OriginalHTMLSelectElement, HTMLSelectElement, document.createElement("select"));
+    scope.wrappers.HTMLSelectElement = HTMLSelectElement;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var HTMLElement = scope.wrappers.HTMLElement;
+    var mixin = scope.mixin;
+    var registerWrapper = scope.registerWrapper;
+    var unwrap = scope.unwrap;
+    var wrap = scope.wrap;
+    var wrapHTMLCollection = scope.wrapHTMLCollection;
+    var OriginalHTMLTableElement = window.HTMLTableElement;
+    function HTMLTableElement(node) {
+      HTMLElement.call(this, node);
+    }
+    HTMLTableElement.prototype = Object.create(HTMLElement.prototype);
+    mixin(HTMLTableElement.prototype, {
+      get caption() {
+        return wrap(unwrap(this).caption);
+      },
+      createCaption: function() {
+        return wrap(unwrap(this).createCaption());
+      },
+      get tHead() {
+        return wrap(unwrap(this).tHead);
+      },
+      createTHead: function() {
+        return wrap(unwrap(this).createTHead());
+      },
+      createTFoot: function() {
+        return wrap(unwrap(this).createTFoot());
+      },
+      get tFoot() {
+        return wrap(unwrap(this).tFoot);
+      },
+      get tBodies() {
+        return wrapHTMLCollection(unwrap(this).tBodies);
+      },
+      createTBody: function() {
+        return wrap(unwrap(this).createTBody());
+      },
+      get rows() {
+        return wrapHTMLCollection(unwrap(this).rows);
+      },
+      insertRow: function(index) {
+        return wrap(unwrap(this).insertRow(index));
+      }
+    });
+    registerWrapper(OriginalHTMLTableElement, HTMLTableElement, document.createElement("table"));
+    scope.wrappers.HTMLTableElement = HTMLTableElement;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var HTMLElement = scope.wrappers.HTMLElement;
+    var mixin = scope.mixin;
+    var registerWrapper = scope.registerWrapper;
+    var wrapHTMLCollection = scope.wrapHTMLCollection;
+    var unwrap = scope.unwrap;
+    var wrap = scope.wrap;
+    var OriginalHTMLTableSectionElement = window.HTMLTableSectionElement;
+    function HTMLTableSectionElement(node) {
+      HTMLElement.call(this, node);
+    }
+    HTMLTableSectionElement.prototype = Object.create(HTMLElement.prototype);
+    mixin(HTMLTableSectionElement.prototype, {
+      constructor: HTMLTableSectionElement,
+      get rows() {
+        return wrapHTMLCollection(unwrap(this).rows);
+      },
+      insertRow: function(index) {
+        return wrap(unwrap(this).insertRow(index));
+      }
+    });
+    registerWrapper(OriginalHTMLTableSectionElement, HTMLTableSectionElement, document.createElement("thead"));
+    scope.wrappers.HTMLTableSectionElement = HTMLTableSectionElement;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var HTMLElement = scope.wrappers.HTMLElement;
+    var mixin = scope.mixin;
+    var registerWrapper = scope.registerWrapper;
+    var wrapHTMLCollection = scope.wrapHTMLCollection;
+    var unwrap = scope.unwrap;
+    var wrap = scope.wrap;
+    var OriginalHTMLTableRowElement = window.HTMLTableRowElement;
+    function HTMLTableRowElement(node) {
+      HTMLElement.call(this, node);
+    }
+    HTMLTableRowElement.prototype = Object.create(HTMLElement.prototype);
+    mixin(HTMLTableRowElement.prototype, {
+      get cells() {
+        return wrapHTMLCollection(unwrap(this).cells);
+      },
+      insertCell: function(index) {
+        return wrap(unwrap(this).insertCell(index));
+      }
+    });
+    registerWrapper(OriginalHTMLTableRowElement, HTMLTableRowElement, document.createElement("tr"));
+    scope.wrappers.HTMLTableRowElement = HTMLTableRowElement;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var HTMLContentElement = scope.wrappers.HTMLContentElement;
+    var HTMLElement = scope.wrappers.HTMLElement;
+    var HTMLShadowElement = scope.wrappers.HTMLShadowElement;
+    var HTMLTemplateElement = scope.wrappers.HTMLTemplateElement;
+    var mixin = scope.mixin;
+    var registerWrapper = scope.registerWrapper;
+    var OriginalHTMLUnknownElement = window.HTMLUnknownElement;
+    function HTMLUnknownElement(node) {
+      switch (node.localName) {
+       case "content":
+        return new HTMLContentElement(node);
+
+       case "shadow":
+        return new HTMLShadowElement(node);
+
+       case "template":
+        return new HTMLTemplateElement(node);
+      }
+      HTMLElement.call(this, node);
+    }
+    HTMLUnknownElement.prototype = Object.create(HTMLElement.prototype);
+    registerWrapper(OriginalHTMLUnknownElement, HTMLUnknownElement);
+    scope.wrappers.HTMLUnknownElement = HTMLUnknownElement;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var Element = scope.wrappers.Element;
+    var HTMLElement = scope.wrappers.HTMLElement;
+    var registerObject = scope.registerObject;
+    var defineWrapGetter = scope.defineWrapGetter;
+    var SVG_NS = "http://www.w3.org/2000/svg";
+    var svgTitleElement = document.createElementNS(SVG_NS, "title");
+    var SVGTitleElement = registerObject(svgTitleElement);
+    var SVGElement = Object.getPrototypeOf(SVGTitleElement.prototype).constructor;
+    if (!("classList" in svgTitleElement)) {
+      var descr = Object.getOwnPropertyDescriptor(Element.prototype, "classList");
+      Object.defineProperty(HTMLElement.prototype, "classList", descr);
+      delete Element.prototype.classList;
+    }
+    defineWrapGetter(SVGElement, "ownerSVGElement");
+    scope.wrappers.SVGElement = SVGElement;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var mixin = scope.mixin;
+    var registerWrapper = scope.registerWrapper;
+    var unwrap = scope.unwrap;
+    var wrap = scope.wrap;
+    var OriginalSVGUseElement = window.SVGUseElement;
+    var SVG_NS = "http://www.w3.org/2000/svg";
+    var gWrapper = wrap(document.createElementNS(SVG_NS, "g"));
+    var useElement = document.createElementNS(SVG_NS, "use");
+    var SVGGElement = gWrapper.constructor;
+    var parentInterfacePrototype = Object.getPrototypeOf(SVGGElement.prototype);
+    var parentInterface = parentInterfacePrototype.constructor;
+    function SVGUseElement(impl) {
+      parentInterface.call(this, impl);
+    }
+    SVGUseElement.prototype = Object.create(parentInterfacePrototype);
+    if ("instanceRoot" in useElement) {
+      mixin(SVGUseElement.prototype, {
+        get instanceRoot() {
+          return wrap(unwrap(this).instanceRoot);
+        },
+        get animatedInstanceRoot() {
+          return wrap(unwrap(this).animatedInstanceRoot);
+        }
+      });
+    }
+    registerWrapper(OriginalSVGUseElement, SVGUseElement, useElement);
+    scope.wrappers.SVGUseElement = SVGUseElement;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var EventTarget = scope.wrappers.EventTarget;
+    var mixin = scope.mixin;
+    var registerWrapper = scope.registerWrapper;
+    var unsafeUnwrap = scope.unsafeUnwrap;
+    var wrap = scope.wrap;
+    var OriginalSVGElementInstance = window.SVGElementInstance;
+    if (!OriginalSVGElementInstance) return;
+    function SVGElementInstance(impl) {
+      EventTarget.call(this, impl);
+    }
+    SVGElementInstance.prototype = Object.create(EventTarget.prototype);
+    mixin(SVGElementInstance.prototype, {
+      get correspondingElement() {
+        return wrap(unsafeUnwrap(this).correspondingElement);
+      },
+      get correspondingUseElement() {
+        return wrap(unsafeUnwrap(this).correspondingUseElement);
+      },
+      get parentNode() {
+        return wrap(unsafeUnwrap(this).parentNode);
+      },
+      get childNodes() {
+        throw new Error("Not implemented");
+      },
+      get firstChild() {
+        return wrap(unsafeUnwrap(this).firstChild);
+      },
+      get lastChild() {
+        return wrap(unsafeUnwrap(this).lastChild);
+      },
+      get previousSibling() {
+        return wrap(unsafeUnwrap(this).previousSibling);
+      },
+      get nextSibling() {
+        return wrap(unsafeUnwrap(this).nextSibling);
+      }
+    });
+    registerWrapper(OriginalSVGElementInstance, SVGElementInstance);
+    scope.wrappers.SVGElementInstance = SVGElementInstance;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var mixin = scope.mixin;
+    var registerWrapper = scope.registerWrapper;
+    var setWrapper = scope.setWrapper;
+    var unsafeUnwrap = scope.unsafeUnwrap;
+    var unwrap = scope.unwrap;
+    var unwrapIfNeeded = scope.unwrapIfNeeded;
+    var wrap = scope.wrap;
+    var OriginalCanvasRenderingContext2D = window.CanvasRenderingContext2D;
+    function CanvasRenderingContext2D(impl) {
+      setWrapper(impl, this);
+    }
+    mixin(CanvasRenderingContext2D.prototype, {
+      get canvas() {
+        return wrap(unsafeUnwrap(this).canvas);
+      },
+      drawImage: function() {
+        arguments[0] = unwrapIfNeeded(arguments[0]);
+        unsafeUnwrap(this).drawImage.apply(unsafeUnwrap(this), arguments);
+      },
+      createPattern: function() {
+        arguments[0] = unwrap(arguments[0]);
+        return unsafeUnwrap(this).createPattern.apply(unsafeUnwrap(this), arguments);
+      }
+    });
+    registerWrapper(OriginalCanvasRenderingContext2D, CanvasRenderingContext2D, document.createElement("canvas").getContext("2d"));
+    scope.wrappers.CanvasRenderingContext2D = CanvasRenderingContext2D;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var mixin = scope.mixin;
+    var registerWrapper = scope.registerWrapper;
+    var setWrapper = scope.setWrapper;
+    var unsafeUnwrap = scope.unsafeUnwrap;
+    var unwrapIfNeeded = scope.unwrapIfNeeded;
+    var wrap = scope.wrap;
+    var OriginalWebGLRenderingContext = window.WebGLRenderingContext;
+    if (!OriginalWebGLRenderingContext) return;
+    function WebGLRenderingContext(impl) {
+      setWrapper(impl, this);
+    }
+    mixin(WebGLRenderingContext.prototype, {
+      get canvas() {
+        return wrap(unsafeUnwrap(this).canvas);
+      },
+      texImage2D: function() {
+        arguments[5] = unwrapIfNeeded(arguments[5]);
+        unsafeUnwrap(this).texImage2D.apply(unsafeUnwrap(this), arguments);
+      },
+      texSubImage2D: function() {
+        arguments[6] = unwrapIfNeeded(arguments[6]);
+        unsafeUnwrap(this).texSubImage2D.apply(unsafeUnwrap(this), arguments);
+      }
+    });
+    var instanceProperties = /WebKit/.test(navigator.userAgent) ? {
+      drawingBufferHeight: null,
+      drawingBufferWidth: null
+    } : {};
+    registerWrapper(OriginalWebGLRenderingContext, WebGLRenderingContext, instanceProperties);
+    scope.wrappers.WebGLRenderingContext = WebGLRenderingContext;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var registerWrapper = scope.registerWrapper;
+    var setWrapper = scope.setWrapper;
+    var unsafeUnwrap = scope.unsafeUnwrap;
+    var unwrap = scope.unwrap;
+    var unwrapIfNeeded = scope.unwrapIfNeeded;
+    var wrap = scope.wrap;
+    var OriginalRange = window.Range;
+    function Range(impl) {
+      setWrapper(impl, this);
+    }
+    Range.prototype = {
+      get startContainer() {
+        return wrap(unsafeUnwrap(this).startContainer);
+      },
+      get endContainer() {
+        return wrap(unsafeUnwrap(this).endContainer);
+      },
+      get commonAncestorContainer() {
+        return wrap(unsafeUnwrap(this).commonAncestorContainer);
+      },
+      setStart: function(refNode, offset) {
+        unsafeUnwrap(this).setStart(unwrapIfNeeded(refNode), offset);
+      },
+      setEnd: function(refNode, offset) {
+        unsafeUnwrap(this).setEnd(unwrapIfNeeded(refNode), offset);
+      },
+      setStartBefore: function(refNode) {
+        unsafeUnwrap(this).setStartBefore(unwrapIfNeeded(refNode));
+      },
+      setStartAfter: function(refNode) {
+        unsafeUnwrap(this).setStartAfter(unwrapIfNeeded(refNode));
+      },
+      setEndBefore: function(refNode) {
+        unsafeUnwrap(this).setEndBefore(unwrapIfNeeded(refNode));
+      },
+      setEndAfter: function(refNode) {
+        unsafeUnwrap(this).setEndAfter(unwrapIfNeeded(refNode));
+      },
+      selectNode: function(refNode) {
+        unsafeUnwrap(this).selectNode(unwrapIfNeeded(refNode));
+      },
+      selectNodeContents: function(refNode) {
+        unsafeUnwrap(this).selectNodeContents(unwrapIfNeeded(refNode));
+      },
+      compareBoundaryPoints: function(how, sourceRange) {
+        return unsafeUnwrap(this).compareBoundaryPoints(how, unwrap(sourceRange));
+      },
+      extractContents: function() {
+        return wrap(unsafeUnwrap(this).extractContents());
+      },
+      cloneContents: function() {
+        return wrap(unsafeUnwrap(this).cloneContents());
+      },
+      insertNode: function(node) {
+        unsafeUnwrap(this).insertNode(unwrapIfNeeded(node));
+      },
+      surroundContents: function(newParent) {
+        unsafeUnwrap(this).surroundContents(unwrapIfNeeded(newParent));
+      },
+      cloneRange: function() {
+        return wrap(unsafeUnwrap(this).cloneRange());
+      },
+      isPointInRange: function(node, offset) {
+        return unsafeUnwrap(this).isPointInRange(unwrapIfNeeded(node), offset);
+      },
+      comparePoint: function(node, offset) {
+        return unsafeUnwrap(this).comparePoint(unwrapIfNeeded(node), offset);
+      },
+      intersectsNode: function(node) {
+        return unsafeUnwrap(this).intersectsNode(unwrapIfNeeded(node));
+      },
+      toString: function() {
+        return unsafeUnwrap(this).toString();
+      }
+    };
+    if (OriginalRange.prototype.createContextualFragment) {
+      Range.prototype.createContextualFragment = function(html) {
+        return wrap(unsafeUnwrap(this).createContextualFragment(html));
+      };
+    }
+    registerWrapper(window.Range, Range, document.createRange());
+    scope.wrappers.Range = Range;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var GetElementsByInterface = scope.GetElementsByInterface;
+    var ParentNodeInterface = scope.ParentNodeInterface;
+    var SelectorsInterface = scope.SelectorsInterface;
+    var mixin = scope.mixin;
+    var registerObject = scope.registerObject;
+    var DocumentFragment = registerObject(document.createDocumentFragment());
+    mixin(DocumentFragment.prototype, ParentNodeInterface);
+    mixin(DocumentFragment.prototype, SelectorsInterface);
+    mixin(DocumentFragment.prototype, GetElementsByInterface);
+    var Comment = registerObject(document.createComment(""));
+    scope.wrappers.Comment = Comment;
+    scope.wrappers.DocumentFragment = DocumentFragment;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var DocumentFragment = scope.wrappers.DocumentFragment;
+    var TreeScope = scope.TreeScope;
+    var elementFromPoint = scope.elementFromPoint;
+    var getInnerHTML = scope.getInnerHTML;
+    var getTreeScope = scope.getTreeScope;
+    var mixin = scope.mixin;
+    var rewrap = scope.rewrap;
+    var setInnerHTML = scope.setInnerHTML;
+    var unsafeUnwrap = scope.unsafeUnwrap;
+    var unwrap = scope.unwrap;
+    var shadowHostTable = new WeakMap();
+    var nextOlderShadowTreeTable = new WeakMap();
+    var spaceCharRe = /[ \t\n\r\f]/;
+    function ShadowRoot(hostWrapper) {
+      var node = unwrap(unsafeUnwrap(hostWrapper).ownerDocument.createDocumentFragment());
+      DocumentFragment.call(this, node);
+      rewrap(node, this);
+      var oldShadowRoot = hostWrapper.shadowRoot;
+      nextOlderShadowTreeTable.set(this, oldShadowRoot);
+      this.treeScope_ = new TreeScope(this, getTreeScope(oldShadowRoot || hostWrapper));
+      shadowHostTable.set(this, hostWrapper);
+    }
+    ShadowRoot.prototype = Object.create(DocumentFragment.prototype);
+    mixin(ShadowRoot.prototype, {
+      constructor: ShadowRoot,
+      get innerHTML() {
+        return getInnerHTML(this);
+      },
+      set innerHTML(value) {
+        setInnerHTML(this, value);
+        this.invalidateShadowRenderer();
+      },
+      get olderShadowRoot() {
+        return nextOlderShadowTreeTable.get(this) || null;
+      },
+      get host() {
+        return shadowHostTable.get(this) || null;
+      },
+      invalidateShadowRenderer: function() {
+        return shadowHostTable.get(this).invalidateShadowRenderer();
+      },
+      elementFromPoint: function(x, y) {
+        return elementFromPoint(this, this.ownerDocument, x, y);
+      },
+      getElementById: function(id) {
+        if (spaceCharRe.test(id)) return null;
+        return this.querySelector('[id="' + id + '"]');
+      }
+    });
+    scope.wrappers.ShadowRoot = ShadowRoot;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var Element = scope.wrappers.Element;
+    var HTMLContentElement = scope.wrappers.HTMLContentElement;
+    var HTMLShadowElement = scope.wrappers.HTMLShadowElement;
+    var Node = scope.wrappers.Node;
+    var ShadowRoot = scope.wrappers.ShadowRoot;
+    var assert = scope.assert;
+    var getTreeScope = scope.getTreeScope;
+    var mixin = scope.mixin;
+    var oneOf = scope.oneOf;
+    var unsafeUnwrap = scope.unsafeUnwrap;
+    var unwrap = scope.unwrap;
+    var wrap = scope.wrap;
+    var ArraySplice = scope.ArraySplice;
+    function updateWrapperUpAndSideways(wrapper) {
+      wrapper.previousSibling_ = wrapper.previousSibling;
+      wrapper.nextSibling_ = wrapper.nextSibling;
+      wrapper.parentNode_ = wrapper.parentNode;
+    }
+    function updateWrapperDown(wrapper) {
+      wrapper.firstChild_ = wrapper.firstChild;
+      wrapper.lastChild_ = wrapper.lastChild;
+    }
+    function updateAllChildNodes(parentNodeWrapper) {
+      assert(parentNodeWrapper instanceof Node);
+      for (var childWrapper = parentNodeWrapper.firstChild; childWrapper; childWrapper = childWrapper.nextSibling) {
+        updateWrapperUpAndSideways(childWrapper);
+      }
+      updateWrapperDown(parentNodeWrapper);
+    }
+    function insertBefore(parentNodeWrapper, newChildWrapper, refChildWrapper) {
+      var parentNode = unwrap(parentNodeWrapper);
+      var newChild = unwrap(newChildWrapper);
+      var refChild = refChildWrapper ? unwrap(refChildWrapper) : null;
+      remove(newChildWrapper);
+      updateWrapperUpAndSideways(newChildWrapper);
+      if (!refChildWrapper) {
+        parentNodeWrapper.lastChild_ = parentNodeWrapper.lastChild;
+        if (parentNodeWrapper.lastChild === parentNodeWrapper.firstChild) parentNodeWrapper.firstChild_ = parentNodeWrapper.firstChild;
+        var lastChildWrapper = wrap(parentNode.lastChild);
+        if (lastChildWrapper) lastChildWrapper.nextSibling_ = lastChildWrapper.nextSibling;
+      } else {
+        if (parentNodeWrapper.firstChild === refChildWrapper) parentNodeWrapper.firstChild_ = refChildWrapper;
+        refChildWrapper.previousSibling_ = refChildWrapper.previousSibling;
+      }
+      scope.originalInsertBefore.call(parentNode, newChild, refChild);
+    }
+    function remove(nodeWrapper) {
+      var node = unwrap(nodeWrapper);
+      var parentNode = node.parentNode;
+      if (!parentNode) return;
+      var parentNodeWrapper = wrap(parentNode);
+      updateWrapperUpAndSideways(nodeWrapper);
+      if (nodeWrapper.previousSibling) nodeWrapper.previousSibling.nextSibling_ = nodeWrapper;
+      if (nodeWrapper.nextSibling) nodeWrapper.nextSibling.previousSibling_ = nodeWrapper;
+      if (parentNodeWrapper.lastChild === nodeWrapper) parentNodeWrapper.lastChild_ = nodeWrapper;
+      if (parentNodeWrapper.firstChild === nodeWrapper) parentNodeWrapper.firstChild_ = nodeWrapper;
+      scope.originalRemoveChild.call(parentNode, node);
+    }
+    var distributedNodesTable = new WeakMap();
+    var destinationInsertionPointsTable = new WeakMap();
+    var rendererForHostTable = new WeakMap();
+    function resetDistributedNodes(insertionPoint) {
+      distributedNodesTable.set(insertionPoint, []);
+    }
+    function getDistributedNodes(insertionPoint) {
+      var rv = distributedNodesTable.get(insertionPoint);
+      if (!rv) distributedNodesTable.set(insertionPoint, rv = []);
+      return rv;
+    }
+    function getChildNodesSnapshot(node) {
+      var result = [], i = 0;
+      for (var child = node.firstChild; child; child = child.nextSibling) {
+        result[i++] = child;
+      }
+      return result;
+    }
+    var request = oneOf(window, [ "requestAnimationFrame", "mozRequestAnimationFrame", "webkitRequestAnimationFrame", "setTimeout" ]);
+    var pendingDirtyRenderers = [];
+    var renderTimer;
+    function renderAllPending() {
+      for (var i = 0; i < pendingDirtyRenderers.length; i++) {
+        var renderer = pendingDirtyRenderers[i];
+        var parentRenderer = renderer.parentRenderer;
+        if (parentRenderer && parentRenderer.dirty) continue;
+        renderer.render();
+      }
+      pendingDirtyRenderers = [];
+    }
+    function handleRequestAnimationFrame() {
+      renderTimer = null;
+      renderAllPending();
+    }
+    function getRendererForHost(host) {
+      var renderer = rendererForHostTable.get(host);
+      if (!renderer) {
+        renderer = new ShadowRenderer(host);
+        rendererForHostTable.set(host, renderer);
+      }
+      return renderer;
+    }
+    function getShadowRootAncestor(node) {
+      var root = getTreeScope(node).root;
+      if (root instanceof ShadowRoot) return root;
+      return null;
+    }
+    function getRendererForShadowRoot(shadowRoot) {
+      return getRendererForHost(shadowRoot.host);
+    }
+    var spliceDiff = new ArraySplice();
+    spliceDiff.equals = function(renderNode, rawNode) {
+      return unwrap(renderNode.node) === rawNode;
+    };
+    function RenderNode(node) {
+      this.skip = false;
+      this.node = node;
+      this.childNodes = [];
+    }
+    RenderNode.prototype = {
+      append: function(node) {
+        var rv = new RenderNode(node);
+        this.childNodes.push(rv);
+        return rv;
+      },
+      sync: function(opt_added) {
+        if (this.skip) return;
+        var nodeWrapper = this.node;
+        var newChildren = this.childNodes;
+        var oldChildren = getChildNodesSnapshot(unwrap(nodeWrapper));
+        var added = opt_added || new WeakMap();
+        var splices = spliceDiff.calculateSplices(newChildren, oldChildren);
+        var newIndex = 0, oldIndex = 0;
+        var lastIndex = 0;
+        for (var i = 0; i < splices.length; i++) {
+          var splice = splices[i];
+          for (;lastIndex < splice.index; lastIndex++) {
+            oldIndex++;
+            newChildren[newIndex++].sync(added);
+          }
+          var removedCount = splice.removed.length;
+          for (var j = 0; j < removedCount; j++) {
+            var wrapper = wrap(oldChildren[oldIndex++]);
+            if (!added.get(wrapper)) remove(wrapper);
+          }
+          var addedCount = splice.addedCount;
+          var refNode = oldChildren[oldIndex] && wrap(oldChildren[oldIndex]);
+          for (var j = 0; j < addedCount; j++) {
+            var newChildRenderNode = newChildren[newIndex++];
+            var newChildWrapper = newChildRenderNode.node;
+            insertBefore(nodeWrapper, newChildWrapper, refNode);
+            added.set(newChildWrapper, true);
+            newChildRenderNode.sync(added);
+          }
+          lastIndex += addedCount;
+        }
+        for (var i = lastIndex; i < newChildren.length; i++) {
+          newChildren[i].sync(added);
+        }
+      }
+    };
+    function ShadowRenderer(host) {
+      this.host = host;
+      this.dirty = false;
+      this.invalidateAttributes();
+      this.associateNode(host);
+    }
+    ShadowRenderer.prototype = {
+      render: function(opt_renderNode) {
+        if (!this.dirty) return;
+        this.invalidateAttributes();
+        var host = this.host;
+        this.distribution(host);
+        var renderNode = opt_renderNode || new RenderNode(host);
+        this.buildRenderTree(renderNode, host);
+        var topMostRenderer = !opt_renderNode;
+        if (topMostRenderer) renderNode.sync();
+        this.dirty = false;
+      },
+      get parentRenderer() {
+        return getTreeScope(this.host).renderer;
+      },
+      invalidate: function() {
+        if (!this.dirty) {
+          this.dirty = true;
+          var parentRenderer = this.parentRenderer;
+          if (parentRenderer) parentRenderer.invalidate();
+          pendingDirtyRenderers.push(this);
+          if (renderTimer) return;
+          renderTimer = window[request](handleRequestAnimationFrame, 0);
+        }
+      },
+      distribution: function(root) {
+        this.resetAllSubtrees(root);
+        this.distributionResolution(root);
+      },
+      resetAll: function(node) {
+        if (isInsertionPoint(node)) resetDistributedNodes(node); else resetDestinationInsertionPoints(node);
+        this.resetAllSubtrees(node);
+      },
+      resetAllSubtrees: function(node) {
+        for (var child = node.firstChild; child; child = child.nextSibling) {
+          this.resetAll(child);
+        }
+        if (node.shadowRoot) this.resetAll(node.shadowRoot);
+        if (node.olderShadowRoot) this.resetAll(node.olderShadowRoot);
+      },
+      distributionResolution: function(node) {
+        if (isShadowHost(node)) {
+          var shadowHost = node;
+          var pool = poolPopulation(shadowHost);
+          var shadowTrees = getShadowTrees(shadowHost);
+          for (var i = 0; i < shadowTrees.length; i++) {
+            this.poolDistribution(shadowTrees[i], pool);
+          }
+          for (var i = shadowTrees.length - 1; i >= 0; i--) {
+            var shadowTree = shadowTrees[i];
+            var shadow = getShadowInsertionPoint(shadowTree);
+            if (shadow) {
+              var olderShadowRoot = shadowTree.olderShadowRoot;
+              if (olderShadowRoot) {
+                pool = poolPopulation(olderShadowRoot);
+              }
+              for (var j = 0; j < pool.length; j++) {
+                destributeNodeInto(pool[j], shadow);
+              }
+            }
+            this.distributionResolution(shadowTree);
+          }
+        }
+        for (var child = node.firstChild; child; child = child.nextSibling) {
+          this.distributionResolution(child);
+        }
+      },
+      poolDistribution: function(node, pool) {
+        if (node instanceof HTMLShadowElement) return;
+        if (node instanceof HTMLContentElement) {
+          var content = node;
+          this.updateDependentAttributes(content.getAttribute("select"));
+          var anyDistributed = false;
+          for (var i = 0; i < pool.length; i++) {
+            var node = pool[i];
+            if (!node) continue;
+            if (matches(node, content)) {
+              destributeNodeInto(node, content);
+              pool[i] = undefined;
+              anyDistributed = true;
+            }
+          }
+          if (!anyDistributed) {
+            for (var child = content.firstChild; child; child = child.nextSibling) {
+              destributeNodeInto(child, content);
+            }
+          }
+          return;
+        }
+        for (var child = node.firstChild; child; child = child.nextSibling) {
+          this.poolDistribution(child, pool);
+        }
+      },
+      buildRenderTree: function(renderNode, node) {
+        var children = this.compose(node);
+        for (var i = 0; i < children.length; i++) {
+          var child = children[i];
+          var childRenderNode = renderNode.append(child);
+          this.buildRenderTree(childRenderNode, child);
+        }
+        if (isShadowHost(node)) {
+          var renderer = getRendererForHost(node);
+          renderer.dirty = false;
+        }
+      },
+      compose: function(node) {
+        var children = [];
+        var p = node.shadowRoot || node;
+        for (var child = p.firstChild; child; child = child.nextSibling) {
+          if (isInsertionPoint(child)) {
+            this.associateNode(p);
+            var distributedNodes = getDistributedNodes(child);
+            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;
+      },
+      invalidateAttributes: function() {
+        this.attributes = Object.create(null);
+      },
+      updateDependentAttributes: function(selector) {
+        if (!selector) return;
+        var attributes = this.attributes;
+        if (/\.\w+/.test(selector)) attributes["class"] = true;
+        if (/#\w+/.test(selector)) attributes["id"] = true;
+        selector.replace(/\[\s*([^\s=\|~\]]+)/g, function(_, name) {
+          attributes[name] = true;
+        });
+      },
+      dependsOnAttribute: function(name) {
+        return this.attributes[name];
+      },
+      associateNode: function(node) {
+        unsafeUnwrap(node).polymerShadowRenderer_ = this;
+      }
+    };
+    function poolPopulation(node) {
+      var pool = [];
+      for (var child = node.firstChild; child; child = child.nextSibling) {
+        if (isInsertionPoint(child)) {
+          pool.push.apply(pool, getDistributedNodes(child));
+        } else {
+          pool.push(child);
+        }
+      }
+      return pool;
+    }
+    function getShadowInsertionPoint(node) {
+      if (node instanceof HTMLShadowElement) return node;
+      if (node instanceof HTMLContentElement) return null;
+      for (var child = node.firstChild; child; child = child.nextSibling) {
+        var res = getShadowInsertionPoint(child);
+        if (res) return res;
+      }
+      return null;
+    }
+    function destributeNodeInto(child, insertionPoint) {
+      getDistributedNodes(insertionPoint).push(child);
+      var points = destinationInsertionPointsTable.get(child);
+      if (!points) destinationInsertionPointsTable.set(child, [ insertionPoint ]); else points.push(insertionPoint);
+    }
+    function getDestinationInsertionPoints(node) {
+      return destinationInsertionPointsTable.get(node);
+    }
+    function resetDestinationInsertionPoints(node) {
+      destinationInsertionPointsTable.set(node, undefined);
+    }
+    var selectorStartCharRe = /^(:not\()?[*.#[a-zA-Z_|]/;
+    function matches(node, contentElement) {
+      var select = contentElement.getAttribute("select");
+      if (!select) return true;
+      select = select.trim();
+      if (!select) return true;
+      if (!(node instanceof Element)) return false;
+      if (!selectorStartCharRe.test(select)) return false;
+      try {
+        return node.matches(select);
+      } catch (ex) {
+        return false;
+      }
+    }
+    function isFinalDestination(insertionPoint, node) {
+      var points = getDestinationInsertionPoints(node);
+      return points && points[points.length - 1] === insertionPoint;
+    }
+    function isInsertionPoint(node) {
+      return node instanceof HTMLContentElement || node instanceof HTMLShadowElement;
+    }
+    function isShadowHost(shadowHost) {
+      return shadowHost.shadowRoot;
+    }
+    function getShadowTrees(host) {
+      var trees = [];
+      for (var tree = host.shadowRoot; tree; tree = tree.olderShadowRoot) {
+        trees.push(tree);
+      }
+      return trees;
+    }
+    function render(host) {
+      new ShadowRenderer(host).render();
+    }
+    Node.prototype.invalidateShadowRenderer = function(force) {
+      var renderer = unsafeUnwrap(this).polymerShadowRenderer_;
+      if (renderer) {
+        renderer.invalidate();
+        return true;
+      }
+      return false;
+    };
+    HTMLContentElement.prototype.getDistributedNodes = HTMLShadowElement.prototype.getDistributedNodes = function() {
+      renderAllPending();
+      return getDistributedNodes(this);
+    };
+    Element.prototype.getDestinationInsertionPoints = function() {
+      renderAllPending();
+      return getDestinationInsertionPoints(this) || [];
+    };
+    HTMLContentElement.prototype.nodeIsInserted_ = HTMLShadowElement.prototype.nodeIsInserted_ = function() {
+      this.invalidateShadowRenderer();
+      var shadowRoot = getShadowRootAncestor(this);
+      var renderer;
+      if (shadowRoot) renderer = getRendererForShadowRoot(shadowRoot);
+      unsafeUnwrap(this).polymerShadowRenderer_ = renderer;
+      if (renderer) renderer.invalidate();
+    };
+    scope.getRendererForHost = getRendererForHost;
+    scope.getShadowTrees = getShadowTrees;
+    scope.renderAllPending = renderAllPending;
+    scope.getDestinationInsertionPoints = getDestinationInsertionPoints;
+    scope.visual = {
+      insertBefore: insertBefore,
+      remove: remove
+    };
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var HTMLElement = scope.wrappers.HTMLElement;
+    var assert = scope.assert;
+    var mixin = scope.mixin;
+    var registerWrapper = scope.registerWrapper;
+    var unwrap = scope.unwrap;
+    var wrap = scope.wrap;
+    var elementsWithFormProperty = [ "HTMLButtonElement", "HTMLFieldSetElement", "HTMLInputElement", "HTMLKeygenElement", "HTMLLabelElement", "HTMLLegendElement", "HTMLObjectElement", "HTMLOutputElement", "HTMLTextAreaElement" ];
+    function createWrapperConstructor(name) {
+      if (!window[name]) return;
+      assert(!scope.wrappers[name]);
+      var GeneratedWrapper = function(node) {
+        HTMLElement.call(this, node);
+      };
+      GeneratedWrapper.prototype = Object.create(HTMLElement.prototype);
+      mixin(GeneratedWrapper.prototype, {
+        get form() {
+          return wrap(unwrap(this).form);
+        }
+      });
+      registerWrapper(window[name], GeneratedWrapper, document.createElement(name.slice(4, -7)));
+      scope.wrappers[name] = GeneratedWrapper;
+    }
+    elementsWithFormProperty.forEach(createWrapperConstructor);
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var registerWrapper = scope.registerWrapper;
+    var setWrapper = scope.setWrapper;
+    var unsafeUnwrap = scope.unsafeUnwrap;
+    var unwrap = scope.unwrap;
+    var unwrapIfNeeded = scope.unwrapIfNeeded;
+    var wrap = scope.wrap;
+    var OriginalSelection = window.Selection;
+    function Selection(impl) {
+      setWrapper(impl, this);
+    }
+    Selection.prototype = {
+      get anchorNode() {
+        return wrap(unsafeUnwrap(this).anchorNode);
+      },
+      get focusNode() {
+        return wrap(unsafeUnwrap(this).focusNode);
+      },
+      addRange: function(range) {
+        unsafeUnwrap(this).addRange(unwrap(range));
+      },
+      collapse: function(node, index) {
+        unsafeUnwrap(this).collapse(unwrapIfNeeded(node), index);
+      },
+      containsNode: function(node, allowPartial) {
+        return unsafeUnwrap(this).containsNode(unwrapIfNeeded(node), allowPartial);
+      },
+      extend: function(node, offset) {
+        unsafeUnwrap(this).extend(unwrapIfNeeded(node), offset);
+      },
+      getRangeAt: function(index) {
+        return wrap(unsafeUnwrap(this).getRangeAt(index));
+      },
+      removeRange: function(range) {
+        unsafeUnwrap(this).removeRange(unwrap(range));
+      },
+      selectAllChildren: function(node) {
+        unsafeUnwrap(this).selectAllChildren(unwrapIfNeeded(node));
+      },
+      toString: function() {
+        return unsafeUnwrap(this).toString();
+      }
+    };
+    registerWrapper(window.Selection, Selection, window.getSelection());
+    scope.wrappers.Selection = Selection;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var GetElementsByInterface = scope.GetElementsByInterface;
+    var Node = scope.wrappers.Node;
+    var ParentNodeInterface = scope.ParentNodeInterface;
+    var Selection = scope.wrappers.Selection;
+    var SelectorsInterface = scope.SelectorsInterface;
+    var ShadowRoot = scope.wrappers.ShadowRoot;
+    var TreeScope = scope.TreeScope;
+    var cloneNode = scope.cloneNode;
+    var defineWrapGetter = scope.defineWrapGetter;
+    var elementFromPoint = scope.elementFromPoint;
+    var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
+    var matchesNames = scope.matchesNames;
+    var mixin = scope.mixin;
+    var registerWrapper = scope.registerWrapper;
+    var renderAllPending = scope.renderAllPending;
+    var rewrap = scope.rewrap;
+    var setWrapper = scope.setWrapper;
+    var unsafeUnwrap = scope.unsafeUnwrap;
+    var unwrap = scope.unwrap;
+    var wrap = scope.wrap;
+    var wrapEventTargetMethods = scope.wrapEventTargetMethods;
+    var wrapNodeList = scope.wrapNodeList;
+    var implementationTable = new WeakMap();
+    function Document(node) {
+      Node.call(this, node);
+      this.treeScope_ = new TreeScope(this, null);
+    }
+    Document.prototype = Object.create(Node.prototype);
+    defineWrapGetter(Document, "documentElement");
+    defineWrapGetter(Document, "body");
+    defineWrapGetter(Document, "head");
+    function wrapMethod(name) {
+      var original = document[name];
+      Document.prototype[name] = function() {
+        return wrap(original.apply(unsafeUnwrap(this), arguments));
+      };
+    }
+    [ "createComment", "createDocumentFragment", "createElement", "createElementNS", "createEvent", "createEventNS", "createRange", "createTextNode", "getElementById" ].forEach(wrapMethod);
+    var originalAdoptNode = document.adoptNode;
+    function adoptNodeNoRemove(node, doc) {
+      originalAdoptNode.call(unsafeUnwrap(doc), unwrap(node));
+      adoptSubtree(node, doc);
+    }
+    function adoptSubtree(node, doc) {
+      if (node.shadowRoot) doc.adoptNode(node.shadowRoot);
+      if (node instanceof ShadowRoot) adoptOlderShadowRoots(node, doc);
+      for (var child = node.firstChild; child; child = child.nextSibling) {
+        adoptSubtree(child, doc);
+      }
+    }
+    function adoptOlderShadowRoots(shadowRoot, doc) {
+      var oldShadowRoot = shadowRoot.olderShadowRoot;
+      if (oldShadowRoot) doc.adoptNode(oldShadowRoot);
+    }
+    var originalGetSelection = document.getSelection;
+    mixin(Document.prototype, {
+      adoptNode: function(node) {
+        if (node.parentNode) node.parentNode.removeChild(node);
+        adoptNodeNoRemove(node, this);
+        return node;
+      },
+      elementFromPoint: function(x, y) {
+        return elementFromPoint(this, this, x, y);
+      },
+      importNode: function(node, deep) {
+        return cloneNode(node, deep, unsafeUnwrap(this));
+      },
+      getSelection: function() {
+        renderAllPending();
+        return new Selection(originalGetSelection.call(unwrap(this)));
+      },
+      getElementsByName: function(name) {
+        return SelectorsInterface.querySelectorAll.call(this, "[name=" + JSON.stringify(String(name)) + "]");
+      }
+    });
+    if (document.registerElement) {
+      var originalRegisterElement = document.registerElement;
+      Document.prototype.registerElement = function(tagName, object) {
+        var prototype, extendsOption;
+        if (object !== undefined) {
+          prototype = object.prototype;
+          extendsOption = object.extends;
+        }
+        if (!prototype) prototype = Object.create(HTMLElement.prototype);
+        if (scope.nativePrototypeTable.get(prototype)) {
+          throw new Error("NotSupportedError");
+        }
+        var proto = Object.getPrototypeOf(prototype);
+        var nativePrototype;
+        var prototypes = [];
+        while (proto) {
+          nativePrototype = scope.nativePrototypeTable.get(proto);
+          if (nativePrototype) break;
+          prototypes.push(proto);
+          proto = Object.getPrototypeOf(proto);
+        }
+        if (!nativePrototype) {
+          throw new Error("NotSupportedError");
+        }
+        var newPrototype = Object.create(nativePrototype);
+        for (var i = prototypes.length - 1; i >= 0; i--) {
+          newPrototype = Object.create(newPrototype);
+        }
+        [ "createdCallback", "attachedCallback", "detachedCallback", "attributeChangedCallback" ].forEach(function(name) {
+          var f = prototype[name];
+          if (!f) return;
+          newPrototype[name] = function() {
+            if (!(wrap(this) instanceof CustomElementConstructor)) {
+              rewrap(this);
+            }
+            f.apply(wrap(this), arguments);
+          };
+        });
+        var p = {
+          prototype: newPrototype
+        };
+        if (extendsOption) p.extends = extendsOption;
+        function CustomElementConstructor(node) {
+          if (!node) {
+            if (extendsOption) {
+              return document.createElement(extendsOption, tagName);
+            } else {
+              return document.createElement(tagName);
+            }
+          }
+          setWrapper(node, this);
+        }
+        CustomElementConstructor.prototype = prototype;
+        CustomElementConstructor.prototype.constructor = CustomElementConstructor;
+        scope.constructorTable.set(newPrototype, CustomElementConstructor);
+        scope.nativePrototypeTable.set(prototype, newPrototype);
+        var nativeConstructor = originalRegisterElement.call(unwrap(this), tagName, p);
+        return CustomElementConstructor;
+      };
+      forwardMethodsToWrapper([ window.HTMLDocument || window.Document ], [ "registerElement" ]);
+    }
+    forwardMethodsToWrapper([ window.HTMLBodyElement, window.HTMLDocument || window.Document, window.HTMLHeadElement, window.HTMLHtmlElement ], [ "appendChild", "compareDocumentPosition", "contains", "getElementsByClassName", "getElementsByTagName", "getElementsByTagNameNS", "insertBefore", "querySelector", "querySelectorAll", "removeChild", "replaceChild" ]);
+    forwardMethodsToWrapper([ window.HTMLBodyElement, window.HTMLHeadElement, window.HTMLHtmlElement ], matchesNames);
+    forwardMethodsToWrapper([ window.HTMLDocument || window.Document ], [ "adoptNode", "importNode", "contains", "createComment", "createDocumentFragment", "createElement", "createElementNS", "createEvent", "createEventNS", "createRange", "createTextNode", "elementFromPoint", "getElementById", "getElementsByName", "getSelection" ]);
+    mixin(Document.prototype, GetElementsByInterface);
+    mixin(Document.prototype, ParentNodeInterface);
+    mixin(Document.prototype, SelectorsInterface);
+    mixin(Document.prototype, {
+      get implementation() {
+        var implementation = implementationTable.get(this);
+        if (implementation) return implementation;
+        implementation = new DOMImplementation(unwrap(this).implementation);
+        implementationTable.set(this, implementation);
+        return implementation;
+      },
+      get defaultView() {
+        return wrap(unwrap(this).defaultView);
+      }
+    });
+    registerWrapper(window.Document, Document, document.implementation.createHTMLDocument(""));
+    if (window.HTMLDocument) registerWrapper(window.HTMLDocument, Document);
+    wrapEventTargetMethods([ window.HTMLBodyElement, window.HTMLDocument || window.Document, window.HTMLHeadElement ]);
+    function DOMImplementation(impl) {
+      setWrapper(impl, this);
+    }
+    function wrapImplMethod(constructor, name) {
+      var original = document.implementation[name];
+      constructor.prototype[name] = function() {
+        return wrap(original.apply(unsafeUnwrap(this), arguments));
+      };
+    }
+    function forwardImplMethod(constructor, name) {
+      var original = document.implementation[name];
+      constructor.prototype[name] = function() {
+        return original.apply(unsafeUnwrap(this), arguments);
+      };
+    }
+    wrapImplMethod(DOMImplementation, "createDocumentType");
+    wrapImplMethod(DOMImplementation, "createDocument");
+    wrapImplMethod(DOMImplementation, "createHTMLDocument");
+    forwardImplMethod(DOMImplementation, "hasFeature");
+    registerWrapper(window.DOMImplementation, DOMImplementation);
+    forwardMethodsToWrapper([ window.DOMImplementation ], [ "createDocumentType", "createDocument", "createHTMLDocument", "hasFeature" ]);
+    scope.adoptNodeNoRemove = adoptNodeNoRemove;
+    scope.wrappers.DOMImplementation = DOMImplementation;
+    scope.wrappers.Document = Document;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var EventTarget = scope.wrappers.EventTarget;
+    var Selection = scope.wrappers.Selection;
+    var mixin = scope.mixin;
+    var registerWrapper = scope.registerWrapper;
+    var renderAllPending = scope.renderAllPending;
+    var unwrap = scope.unwrap;
+    var unwrapIfNeeded = scope.unwrapIfNeeded;
+    var wrap = scope.wrap;
+    var OriginalWindow = window.Window;
+    var originalGetComputedStyle = window.getComputedStyle;
+    var originalGetDefaultComputedStyle = window.getDefaultComputedStyle;
+    var originalGetSelection = window.getSelection;
+    function Window(impl) {
+      EventTarget.call(this, impl);
+    }
+    Window.prototype = Object.create(EventTarget.prototype);
+    OriginalWindow.prototype.getComputedStyle = function(el, pseudo) {
+      return wrap(this || window).getComputedStyle(unwrapIfNeeded(el), pseudo);
+    };
+    if (originalGetDefaultComputedStyle) {
+      OriginalWindow.prototype.getDefaultComputedStyle = function(el, pseudo) {
+        return wrap(this || window).getDefaultComputedStyle(unwrapIfNeeded(el), pseudo);
+      };
+    }
+    OriginalWindow.prototype.getSelection = function() {
+      return wrap(this || window).getSelection();
+    };
+    delete window.getComputedStyle;
+    delete window.getDefaultComputedStyle;
+    delete window.getSelection;
+    [ "addEventListener", "removeEventListener", "dispatchEvent" ].forEach(function(name) {
+      OriginalWindow.prototype[name] = function() {
+        var w = wrap(this || window);
+        return w[name].apply(w, arguments);
+      };
+      delete window[name];
+    });
+    mixin(Window.prototype, {
+      getComputedStyle: function(el, pseudo) {
+        renderAllPending();
+        return originalGetComputedStyle.call(unwrap(this), unwrapIfNeeded(el), pseudo);
+      },
+      getSelection: function() {
+        renderAllPending();
+        return new Selection(originalGetSelection.call(unwrap(this)));
+      },
+      get document() {
+        return wrap(unwrap(this).document);
+      }
+    });
+    if (originalGetDefaultComputedStyle) {
+      Window.prototype.getDefaultComputedStyle = function(el, pseudo) {
+        renderAllPending();
+        return originalGetDefaultComputedStyle.call(unwrap(this), unwrapIfNeeded(el), pseudo);
+      };
+    }
+    registerWrapper(OriginalWindow, Window, window);
+    scope.wrappers.Window = Window;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var unwrap = scope.unwrap;
+    var OriginalDataTransfer = window.DataTransfer || window.Clipboard;
+    var OriginalDataTransferSetDragImage = OriginalDataTransfer.prototype.setDragImage;
+    if (OriginalDataTransferSetDragImage) {
+      OriginalDataTransfer.prototype.setDragImage = function(image, x, y) {
+        OriginalDataTransferSetDragImage.call(this, unwrap(image), x, y);
+      };
+    }
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var registerWrapper = scope.registerWrapper;
+    var setWrapper = scope.setWrapper;
+    var unwrap = scope.unwrap;
+    var OriginalFormData = window.FormData;
+    if (!OriginalFormData) return;
+    function FormData(formElement) {
+      var impl;
+      if (formElement instanceof OriginalFormData) {
+        impl = formElement;
+      } else {
+        impl = new OriginalFormData(formElement && unwrap(formElement));
+      }
+      setWrapper(impl, this);
+    }
+    registerWrapper(OriginalFormData, FormData, new OriginalFormData());
+    scope.wrappers.FormData = FormData;
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var unwrapIfNeeded = scope.unwrapIfNeeded;
+    var originalSend = XMLHttpRequest.prototype.send;
+    XMLHttpRequest.prototype.send = function(obj) {
+      return originalSend.call(this, unwrapIfNeeded(obj));
+    };
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    "use strict";
+    var isWrapperFor = scope.isWrapperFor;
+    var elements = {
+      a: "HTMLAnchorElement",
+      area: "HTMLAreaElement",
+      audio: "HTMLAudioElement",
+      base: "HTMLBaseElement",
+      body: "HTMLBodyElement",
+      br: "HTMLBRElement",
+      button: "HTMLButtonElement",
+      canvas: "HTMLCanvasElement",
+      caption: "HTMLTableCaptionElement",
+      col: "HTMLTableColElement",
+      content: "HTMLContentElement",
+      data: "HTMLDataElement",
+      datalist: "HTMLDataListElement",
+      del: "HTMLModElement",
+      dir: "HTMLDirectoryElement",
+      div: "HTMLDivElement",
+      dl: "HTMLDListElement",
+      embed: "HTMLEmbedElement",
+      fieldset: "HTMLFieldSetElement",
+      font: "HTMLFontElement",
+      form: "HTMLFormElement",
+      frame: "HTMLFrameElement",
+      frameset: "HTMLFrameSetElement",
+      h1: "HTMLHeadingElement",
+      head: "HTMLHeadElement",
+      hr: "HTMLHRElement",
+      html: "HTMLHtmlElement",
+      iframe: "HTMLIFrameElement",
+      img: "HTMLImageElement",
+      input: "HTMLInputElement",
+      keygen: "HTMLKeygenElement",
+      label: "HTMLLabelElement",
+      legend: "HTMLLegendElement",
+      li: "HTMLLIElement",
+      link: "HTMLLinkElement",
+      map: "HTMLMapElement",
+      marquee: "HTMLMarqueeElement",
+      menu: "HTMLMenuElement",
+      menuitem: "HTMLMenuItemElement",
+      meta: "HTMLMetaElement",
+      meter: "HTMLMeterElement",
+      object: "HTMLObjectElement",
+      ol: "HTMLOListElement",
+      optgroup: "HTMLOptGroupElement",
+      option: "HTMLOptionElement",
+      output: "HTMLOutputElement",
+      p: "HTMLParagraphElement",
+      param: "HTMLParamElement",
+      pre: "HTMLPreElement",
+      progress: "HTMLProgressElement",
+      q: "HTMLQuoteElement",
+      script: "HTMLScriptElement",
+      select: "HTMLSelectElement",
+      shadow: "HTMLShadowElement",
+      source: "HTMLSourceElement",
+      span: "HTMLSpanElement",
+      style: "HTMLStyleElement",
+      table: "HTMLTableElement",
+      tbody: "HTMLTableSectionElement",
+      template: "HTMLTemplateElement",
+      textarea: "HTMLTextAreaElement",
+      thead: "HTMLTableSectionElement",
+      time: "HTMLTimeElement",
+      title: "HTMLTitleElement",
+      tr: "HTMLTableRowElement",
+      track: "HTMLTrackElement",
+      ul: "HTMLUListElement",
+      video: "HTMLVideoElement"
+    };
+    function overrideConstructor(tagName) {
+      var nativeConstructorName = elements[tagName];
+      var nativeConstructor = window[nativeConstructorName];
+      if (!nativeConstructor) return;
+      var element = document.createElement(tagName);
+      var wrapperConstructor = element.constructor;
+      window[nativeConstructorName] = wrapperConstructor;
+    }
+    Object.keys(elements).forEach(overrideConstructor);
+    Object.getOwnPropertyNames(scope.wrappers).forEach(function(name) {
+      window[name] = scope.wrappers[name];
+    });
+  })(window.ShadowDOMPolyfill);
+  (function(scope) {
+    var ShadowCSS = {
+      strictStyling: false,
+      registry: {},
+      shimStyling: function(root, name, extendsName) {
+        var scopeStyles = this.prepareRoot(root, name, extendsName);
+        var typeExtension = this.isTypeExtension(extendsName);
+        var scopeSelector = this.makeScopeSelector(name, typeExtension);
+        var cssText = stylesToCssText(scopeStyles, true);
+        cssText = this.scopeCssText(cssText, scopeSelector);
+        if (root) {
+          root.shimmedStyle = cssText;
+        }
+        this.addCssToDocument(cssText, name);
+      },
+      shimStyle: function(style, selector) {
+        return this.shimCssText(style.textContent, selector);
+      },
+      shimCssText: function(cssText, selector) {
+        cssText = this.insertDirectives(cssText);
+        return this.scopeCssText(cssText, selector);
+      },
+      makeScopeSelector: function(name, typeExtension) {
+        if (name) {
+          return typeExtension ? "[is=" + name + "]" : name;
+        }
+        return "";
+      },
+      isTypeExtension: function(extendsName) {
+        return extendsName && extendsName.indexOf("-") < 0;
+      },
+      prepareRoot: function(root, name, extendsName) {
+        var def = this.registerRoot(root, name, extendsName);
+        this.replaceTextInStyles(def.rootStyles, this.insertDirectives);
+        this.removeStyles(root, def.rootStyles);
+        if (this.strictStyling) {
+          this.applyScopeToContent(root, name);
+        }
+        return def.scopeStyles;
+      },
+      removeStyles: function(root, styles) {
+        for (var i = 0, l = styles.length, s; i < l && (s = styles[i]); i++) {
+          s.parentNode.removeChild(s);
+        }
+      },
+      registerRoot: function(root, name, extendsName) {
+        var def = this.registry[name] = {
+          root: root,
+          name: name,
+          extendsName: extendsName
+        };
+        var styles = this.findStyles(root);
+        def.rootStyles = styles;
+        def.scopeStyles = def.rootStyles;
+        var extendee = this.registry[def.extendsName];
+        if (extendee) {
+          def.scopeStyles = extendee.scopeStyles.concat(def.scopeStyles);
+        }
+        return def;
+      },
+      findStyles: function(root) {
+        if (!root) {
+          return [];
+        }
+        var styles = root.querySelectorAll("style");
+        return Array.prototype.filter.call(styles, function(s) {
+          return !s.hasAttribute(NO_SHIM_ATTRIBUTE);
+        });
+      },
+      applyScopeToContent: function(root, name) {
+        if (root) {
+          Array.prototype.forEach.call(root.querySelectorAll("*"), function(node) {
+            node.setAttribute(name, "");
+          });
+          Array.prototype.forEach.call(root.querySelectorAll("template"), function(template) {
+            this.applyScopeToContent(template.content, name);
+          }, this);
+        }
+      },
+      insertDirectives: function(cssText) {
+        cssText = this.insertPolyfillDirectivesInCssText(cssText);
+        return this.insertPolyfillRulesInCssText(cssText);
+      },
+      insertPolyfillDirectivesInCssText: function(cssText) {
+        cssText = cssText.replace(cssCommentNextSelectorRe, function(match, p1) {
+          return p1.slice(0, -2) + "{";
+        });
+        return cssText.replace(cssContentNextSelectorRe, function(match, p1) {
+          return p1 + " {";
+        });
+      },
+      insertPolyfillRulesInCssText: function(cssText) {
+        cssText = cssText.replace(cssCommentRuleRe, function(match, p1) {
+          return p1.slice(0, -1);
+        });
+        return cssText.replace(cssContentRuleRe, function(match, p1, p2, p3) {
+          var rule = match.replace(p1, "").replace(p2, "");
+          return p3 + rule;
+        });
+      },
+      scopeCssText: function(cssText, scopeSelector) {
+        var unscoped = this.extractUnscopedRulesFromCssText(cssText);
+        cssText = this.insertPolyfillHostInCssText(cssText);
+        cssText = this.convertColonHost(cssText);
+        cssText = this.convertColonHostContext(cssText);
+        cssText = this.convertShadowDOMSelectors(cssText);
+        if (scopeSelector) {
+          var self = this, cssText;
+          withCssRules(cssText, function(rules) {
+            cssText = self.scopeRules(rules, scopeSelector);
+          });
+        }
+        cssText = cssText + "\n" + unscoped;
+        return cssText.trim();
+      },
+      extractUnscopedRulesFromCssText: function(cssText) {
+        var r = "", m;
+        while (m = cssCommentUnscopedRuleRe.exec(cssText)) {
+          r += m[1].slice(0, -1) + "\n\n";
+        }
+        while (m = cssContentUnscopedRuleRe.exec(cssText)) {
+          r += m[0].replace(m[2], "").replace(m[1], m[3]) + "\n\n";
+        }
+        return r;
+      },
+      convertColonHost: function(cssText) {
+        return this.convertColonRule(cssText, cssColonHostRe, this.colonHostPartReplacer);
+      },
+      convertColonHostContext: function(cssText) {
+        return this.convertColonRule(cssText, cssColonHostContextRe, this.colonHostContextPartReplacer);
+      },
+      convertColonRule: function(cssText, regExp, partReplacer) {
+        return cssText.replace(regExp, function(m, p1, p2, p3) {
+          p1 = polyfillHostNoCombinator;
+          if (p2) {
+            var parts = p2.split(","), r = [];
+            for (var i = 0, l = parts.length, p; i < l && (p = parts[i]); i++) {
+              p = p.trim();
+              r.push(partReplacer(p1, p, p3));
+            }
+            return r.join(",");
+          } else {
+            return p1 + p3;
+          }
+        });
+      },
+      colonHostContextPartReplacer: function(host, part, suffix) {
+        if (part.match(polyfillHost)) {
+          return this.colonHostPartReplacer(host, part, suffix);
+        } else {
+          return host + part + suffix + ", " + part + " " + host + suffix;
+        }
+      },
+      colonHostPartReplacer: function(host, part, suffix) {
+        return host + part.replace(polyfillHost, "") + suffix;
+      },
+      convertShadowDOMSelectors: function(cssText) {
+        for (var i = 0; i < shadowDOMSelectorsRe.length; i++) {
+          cssText = cssText.replace(shadowDOMSelectorsRe[i], " ");
+        }
+        return cssText;
+      },
+      scopeRules: function(cssRules, scopeSelector) {
+        var cssText = "";
+        if (cssRules) {
+          Array.prototype.forEach.call(cssRules, function(rule) {
+            if (rule.selectorText && (rule.style && rule.style.cssText !== undefined)) {
+              cssText += this.scopeSelector(rule.selectorText, scopeSelector, this.strictStyling) + " {\n	";
+              cssText += this.propertiesFromRule(rule) + "\n}\n\n";
+            } else if (rule.type === CSSRule.MEDIA_RULE) {
+              cssText += "@media " + rule.media.mediaText + " {\n";
+              cssText += this.scopeRules(rule.cssRules, scopeSelector);
+              cssText += "\n}\n\n";
+            } else {
+              try {
+                if (rule.cssText) {
+                  cssText += rule.cssText + "\n\n";
+                }
+              } catch (x) {
+                if (rule.type === CSSRule.KEYFRAMES_RULE && rule.cssRules) {
+                  cssText += this.ieSafeCssTextFromKeyFrameRule(rule);
+                }
+              }
+            }
+          }, this);
+        }
+        return cssText;
+      },
+      ieSafeCssTextFromKeyFrameRule: function(rule) {
+        var cssText = "@keyframes " + rule.name + " {";
+        Array.prototype.forEach.call(rule.cssRules, function(rule) {
+          cssText += " " + rule.keyText + " {" + rule.style.cssText + "}";
+        });
+        cssText += " }";
+        return cssText;
+      },
+      scopeSelector: function(selector, scopeSelector, strict) {
+        var r = [], parts = selector.split(",");
+        parts.forEach(function(p) {
+          p = p.trim();
+          if (this.selectorNeedsScoping(p, scopeSelector)) {
+            p = strict && !p.match(polyfillHostNoCombinator) ? this.applyStrictSelectorScope(p, scopeSelector) : this.applySelectorScope(p, scopeSelector);
+          }
+          r.push(p);
+        }, this);
+        return r.join(", ");
+      },
+      selectorNeedsScoping: function(selector, scopeSelector) {
+        if (Array.isArray(scopeSelector)) {
+          return true;
+        }
+        var re = this.makeScopeMatcher(scopeSelector);
+        return !selector.match(re);
+      },
+      makeScopeMatcher: function(scopeSelector) {
+        scopeSelector = scopeSelector.replace(/\[/g, "\\[").replace(/\]/g, "\\]");
+        return new RegExp("^(" + scopeSelector + ")" + selectorReSuffix, "m");
+      },
+      applySelectorScope: function(selector, selectorScope) {
+        return Array.isArray(selectorScope) ? this.applySelectorScopeList(selector, selectorScope) : this.applySimpleSelectorScope(selector, selectorScope);
+      },
+      applySelectorScopeList: function(selector, scopeSelectorList) {
+        var r = [];
+        for (var i = 0, s; s = scopeSelectorList[i]; i++) {
+          r.push(this.applySimpleSelectorScope(selector, s));
+        }
+        return r.join(", ");
+      },
+      applySimpleSelectorScope: function(selector, scopeSelector) {
+        if (selector.match(polyfillHostRe)) {
+          selector = selector.replace(polyfillHostNoCombinator, scopeSelector);
+          return selector.replace(polyfillHostRe, scopeSelector + " ");
+        } else {
+          return scopeSelector + " " + selector;
+        }
+      },
+      applyStrictSelectorScope: function(selector, scopeSelector) {
+        scopeSelector = scopeSelector.replace(/\[is=([^\]]*)\]/g, "$1");
+        var splits = [ " ", ">", "+", "~" ], scoped = selector, attrName = "[" + scopeSelector + "]";
+        splits.forEach(function(sep) {
+          var parts = scoped.split(sep);
+          scoped = parts.map(function(p) {
+            var t = p.trim().replace(polyfillHostRe, "");
+            if (t && splits.indexOf(t) < 0 && t.indexOf(attrName) < 0) {
+              p = t.replace(/([^:]*)(:*)(.*)/, "$1" + attrName + "$2$3");
+            }
+            return p;
+          }).join(sep);
+        });
+        return scoped;
+      },
+      insertPolyfillHostInCssText: function(selector) {
+        return selector.replace(colonHostContextRe, polyfillHostContext).replace(colonHostRe, polyfillHost);
+      },
+      propertiesFromRule: function(rule) {
+        var cssText = rule.style.cssText;
+        if (rule.style.content && !rule.style.content.match(/['"]+|attr/)) {
+          cssText = cssText.replace(/content:[^;]*;/g, "content: '" + rule.style.content + "';");
+        }
+        var style = rule.style;
+        for (var i in style) {
+          if (style[i] === "initial") {
+            cssText += i + ": initial; ";
+          }
+        }
+        return cssText;
+      },
+      replaceTextInStyles: function(styles, action) {
+        if (styles && action) {
+          if (!(styles instanceof Array)) {
+            styles = [ styles ];
+          }
+          Array.prototype.forEach.call(styles, function(s) {
+            s.textContent = action.call(this, s.textContent);
+          }, this);
+        }
+      },
+      addCssToDocument: function(cssText, name) {
+        if (cssText.match("@import")) {
+          addOwnSheet(cssText, name);
+        } else {
+          addCssToDocument(cssText);
+        }
+      }
+    };
+    var selectorRe = /([^{]*)({[\s\S]*?})/gim, cssCommentRe = /\/\*[^*]*\*+([^/*][^*]*\*+)*\//gim, cssCommentNextSelectorRe = /\/\*\s*@polyfill ([^*]*\*+([^/*][^*]*\*+)*\/)([^{]*?){/gim, cssContentNextSelectorRe = /polyfill-next-selector[^}]*content\:[\s]*?['"](.*?)['"][;\s]*}([^{]*?){/gim, cssCommentRuleRe = /\/\*\s@polyfill-rule([^*]*\*+([^/*][^*]*\*+)*)\//gim, cssContentRuleRe = /(polyfill-rule)[^}]*(content\:[\s]*['"](.*?)['"])[;\s]*[^}]*}/gim, cssCommentUnscopedRuleRe = /\/\*\s@polyfill-unscoped-rule([^*]*\*+([^/*][^*]*\*+)*)\//gim, cssContentUnscopedRuleRe = /(polyfill-unscoped-rule)[^}]*(content\:[\s]*['"](.*?)['"])[;\s]*[^}]*}/gim, cssPseudoRe = /::(x-[^\s{,(]*)/gim, cssPartRe = /::part\(([^)]*)\)/gim, polyfillHost = "-shadowcsshost", polyfillHostContext = "-shadowcsscontext", parenSuffix = ")(?:\\((" + "(?:\\([^)(]*\\)|[^)(]*)+?" + ")\\))?([^,{]*)";
+    var cssColonHostRe = new RegExp("(" + polyfillHost + parenSuffix, "gim"), cssColonHostContextRe = new RegExp("(" + polyfillHostContext + parenSuffix, "gim"), selectorReSuffix = "([>\\s~+[.,{:][\\s\\S]*)?$", colonHostRe = /\:host/gim, colonHostContextRe = /\:host-context/gim, polyfillHostNoCombinator = polyfillHost + "-no-combinator", polyfillHostRe = new RegExp(polyfillHost, "gim"), polyfillHostContextRe = new RegExp(polyfillHostContext, "gim"), shadowDOMSelectorsRe = [ /\^\^/g, /\^/g, /\/shadow\//g, /\/shadow-deep\//g, /::shadow/g, /\/deep\//g, /::content/g ];
+    function stylesToCssText(styles, preserveComments) {
+      var cssText = "";
+      Array.prototype.forEach.call(styles, function(s) {
+        cssText += s.textContent + "\n\n";
+      });
+      if (!preserveComments) {
+        cssText = cssText.replace(cssCommentRe, "");
+      }
+      return cssText;
+    }
+    function cssTextToStyle(cssText) {
+      var style = document.createElement("style");
+      style.textContent = cssText;
+      return style;
+    }
+    function cssToRules(cssText) {
+      var style = cssTextToStyle(cssText);
+      document.head.appendChild(style);
+      var rules = [];
+      if (style.sheet) {
+        try {
+          rules = style.sheet.cssRules;
+        } catch (e) {}
+      } else {
+        console.warn("sheet not found", style);
+      }
+      style.parentNode.removeChild(style);
+      return rules;
+    }
+    var frame = document.createElement("iframe");
+    frame.style.display = "none";
+    function initFrame() {
+      frame.initialized = true;
+      document.body.appendChild(frame);
+      var doc = frame.contentDocument;
+      var base = doc.createElement("base");
+      base.href = document.baseURI;
+      doc.head.appendChild(base);
+    }
+    function inFrame(fn) {
+      if (!frame.initialized) {
+        initFrame();
+      }
+      document.body.appendChild(frame);
+      fn(frame.contentDocument);
+      document.body.removeChild(frame);
+    }
+    var isChrome = navigator.userAgent.match("Chrome");
+    function withCssRules(cssText, callback) {
+      if (!callback) {
+        return;
+      }
+      var rules;
+      if (cssText.match("@import") && isChrome) {
+        var style = cssTextToStyle(cssText);
+        inFrame(function(doc) {
+          doc.head.appendChild(style.impl);
+          rules = Array.prototype.slice.call(style.sheet.cssRules, 0);
+          callback(rules);
+        });
+      } else {
+        rules = cssToRules(cssText);
+        callback(rules);
+      }
+    }
+    function rulesToCss(cssRules) {
+      for (var i = 0, css = []; i < cssRules.length; i++) {
+        css.push(cssRules[i].cssText);
+      }
+      return css.join("\n\n");
+    }
+    function addCssToDocument(cssText) {
+      if (cssText) {
+        getSheet().appendChild(document.createTextNode(cssText));
+      }
+    }
+    function addOwnSheet(cssText, name) {
+      var style = cssTextToStyle(cssText);
+      style.setAttribute(name, "");
+      style.setAttribute(SHIMMED_ATTRIBUTE, "");
+      document.head.appendChild(style);
+    }
+    var SHIM_ATTRIBUTE = "shim-shadowdom";
+    var SHIMMED_ATTRIBUTE = "shim-shadowdom-css";
+    var NO_SHIM_ATTRIBUTE = "no-shim";
+    var sheet;
+    function getSheet() {
+      if (!sheet) {
+        sheet = document.createElement("style");
+        sheet.setAttribute(SHIMMED_ATTRIBUTE, "");
+        sheet[SHIMMED_ATTRIBUTE] = true;
+      }
+      return sheet;
+    }
+    if (window.ShadowDOMPolyfill) {
+      addCssToDocument("style { display: none !important; }\n");
+      var doc = ShadowDOMPolyfill.wrap(document);
+      var head = doc.querySelector("head");
+      head.insertBefore(getSheet(), head.childNodes[0]);
+      document.addEventListener("DOMContentLoaded", function() {
+        var urlResolver = scope.urlResolver;
+        if (window.HTMLImports && !HTMLImports.useNative) {
+          var SHIM_SHEET_SELECTOR = "link[rel=stylesheet]" + "[" + SHIM_ATTRIBUTE + "]";
+          var SHIM_STYLE_SELECTOR = "style[" + SHIM_ATTRIBUTE + "]";
+          HTMLImports.importer.documentPreloadSelectors += "," + SHIM_SHEET_SELECTOR;
+          HTMLImports.importer.importsPreloadSelectors += "," + SHIM_SHEET_SELECTOR;
+          HTMLImports.parser.documentSelectors = [ HTMLImports.parser.documentSelectors, SHIM_SHEET_SELECTOR, SHIM_STYLE_SELECTOR ].join(",");
+          var originalParseGeneric = HTMLImports.parser.parseGeneric;
+          HTMLImports.parser.parseGeneric = function(elt) {
+            if (elt[SHIMMED_ATTRIBUTE]) {
+              return;
+            }
+            var style = elt.__importElement || elt;
+            if (!style.hasAttribute(SHIM_ATTRIBUTE)) {
+              originalParseGeneric.call(this, elt);
+              return;
+            }
+            if (elt.__resource) {
+              style = elt.ownerDocument.createElement("style");
+              style.textContent = elt.__resource;
+            }
+            HTMLImports.path.resolveUrlsInStyle(style);
+            style.textContent = ShadowCSS.shimStyle(style);
+            style.removeAttribute(SHIM_ATTRIBUTE, "");
+            style.setAttribute(SHIMMED_ATTRIBUTE, "");
+            style[SHIMMED_ATTRIBUTE] = true;
+            if (style.parentNode !== head) {
+              if (elt.parentNode === head) {
+                head.replaceChild(style, elt);
+              } else {
+                this.addElementToDocument(style);
+              }
+            }
+            style.__importParsed = true;
+            this.markParsingComplete(elt);
+            this.parseNext();
+          };
+          var hasResource = HTMLImports.parser.hasResource;
+          HTMLImports.parser.hasResource = function(node) {
+            if (node.localName === "link" && node.rel === "stylesheet" && node.hasAttribute(SHIM_ATTRIBUTE)) {
+              return node.__resource;
+            } else {
+              return hasResource.call(this, node);
+            }
+          };
+        }
+      });
+    }
+    scope.ShadowCSS = ShadowCSS;
+  })(window.WebComponents);
+}
+
+(function(scope) {
+  if (window.ShadowDOMPolyfill) {
+    window.wrap = ShadowDOMPolyfill.wrapIfNeeded;
+    window.unwrap = ShadowDOMPolyfill.unwrapIfNeeded;
+  } else {
+    window.wrap = window.unwrap = function(n) {
+      return n;
+    };
+  }
+})(window.WebComponents);
+
+window.HTMLImports = window.HTMLImports || {
+  flags: {}
+};
+
+(function(scope) {
+  var IMPORT_LINK_TYPE = "import";
+  var useNative = Boolean(IMPORT_LINK_TYPE in document.createElement("link"));
+  var hasShadowDOMPolyfill = Boolean(window.ShadowDOMPolyfill);
+  var wrap = function(node) {
+    return hasShadowDOMPolyfill ? ShadowDOMPolyfill.wrapIfNeeded(node) : node;
+  };
+  var rootDocument = wrap(document);
+  var currentScriptDescriptor = {
+    get: function() {
+      var script = HTMLImports.currentScript || document.currentScript || (document.readyState !== "complete" ? document.scripts[document.scripts.length - 1] : null);
+      return wrap(script);
+    },
+    configurable: true
+  };
+  Object.defineProperty(document, "_currentScript", currentScriptDescriptor);
+  Object.defineProperty(rootDocument, "_currentScript", currentScriptDescriptor);
+  var isIE = /Trident|Edge/.test(navigator.userAgent);
+  function whenReady(callback, doc) {
+    doc = doc || rootDocument;
+    whenDocumentReady(function() {
+      watchImportsLoad(callback, doc);
+    }, doc);
+  }
+  var requiredReadyState = isIE ? "complete" : "interactive";
+  var READY_EVENT = "readystatechange";
+  function isDocumentReady(doc) {
+    return doc.readyState === "complete" || doc.readyState === requiredReadyState;
+  }
+  function whenDocumentReady(callback, doc) {
+    if (!isDocumentReady(doc)) {
+      var checkReady = function() {
+        if (doc.readyState === "complete" || doc.readyState === requiredReadyState) {
+          doc.removeEventListener(READY_EVENT, checkReady);
+          whenDocumentReady(callback, doc);
+        }
+      };
+      doc.addEventListener(READY_EVENT, checkReady);
+    } else if (callback) {
+      callback();
+    }
+  }
+  function markTargetLoaded(event) {
+    event.target.__loaded = true;
+  }
+  function watchImportsLoad(callback, doc) {
+    var imports = doc.querySelectorAll("link[rel=import]");
+    var loaded = 0, l = imports.length;
+    function checkDone(d) {
+      if (loaded == l && callback) {
+        callback();
+      }
+    }
+    function loadedImport(e) {
+      markTargetLoaded(e);
+      loaded++;
+      checkDone();
+    }
+    if (l) {
+      for (var i = 0, imp; i < l && (imp = imports[i]); i++) {
+        if (isImportLoaded(imp)) {
+          loadedImport.call(imp, {
+            target: imp
+          });
+        } else {
+          imp.addEventListener("load", loadedImport);
+          imp.addEventListener("error", loadedImport);
+        }
+      }
+    } else {
+      checkDone();
+    }
+  }
+  function isImportLoaded(link) {
+    return useNative ? link.__loaded || link.import && link.import.readyState !== "loading" : link.__importParsed;
+  }
+  if (useNative) {
+    new MutationObserver(function(mxns) {
+      for (var i = 0, l = mxns.length, m; i < l && (m = mxns[i]); i++) {
+        if (m.addedNodes) {
+          handleImports(m.addedNodes);
+        }
+      }
+    }).observe(document.head, {
+      childList: true
+    });
+    function handleImports(nodes) {
+      for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {
+        if (isImport(n)) {
+          handleImport(n);
+        }
+      }
+    }
+    function isImport(element) {
+      return element.localName === "link" && element.rel === "import";
+    }
+    function handleImport(element) {
+      var loaded = element.import;
+      if (loaded) {
+        markTargetLoaded({
+          target: element
+        });
+      } else {
+        element.addEventListener("load", markTargetLoaded);
+        element.addEventListener("error", markTargetLoaded);
+      }
+    }
+    (function() {
+      if (document.readyState === "loading") {
+        var imports = document.querySelectorAll("link[rel=import]");
+        for (var i = 0, l = imports.length, imp; i < l && (imp = imports[i]); i++) {
+          handleImport(imp);
+        }
+      }
+    })();
+  }
+  whenReady(function() {
+    HTMLImports.ready = true;
+    HTMLImports.readyTime = new Date().getTime();
+    var evt = rootDocument.createEvent("CustomEvent");
+    evt.initCustomEvent("HTMLImportsLoaded", true, true, {});
+    rootDocument.dispatchEvent(evt);
+  });
+  scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;
+  scope.useNative = useNative;
+  scope.rootDocument = rootDocument;
+  scope.whenReady = whenReady;
+  scope.isIE = isIE;
+})(HTMLImports);
+
+(function(scope) {
+  var modules = [];
+  var addModule = function(module) {
+    modules.push(module);
+  };
+  var initializeModules = function() {
+    modules.forEach(function(module) {
+      module(scope);
+    });
+  };
+  scope.addModule = addModule;
+  scope.initializeModules = initializeModules;
+})(HTMLImports);
+
+HTMLImports.addModule(function(scope) {
+  var CSS_URL_REGEXP = /(url\()([^)]*)(\))/g;
+  var CSS_IMPORT_REGEXP = /(@import[\s]+(?!url\())([^;]*)(;)/g;
+  var path = {
+    resolveUrlsInStyle: function(style) {
+      var doc = style.ownerDocument;
+      var resolver = doc.createElement("a");
+      style.textContent = this.resolveUrlsInCssText(style.textContent, resolver);
+      return style;
+    },
+    resolveUrlsInCssText: function(cssText, urlObj) {
+      var r = this.replaceUrls(cssText, urlObj, CSS_URL_REGEXP);
+      r = this.replaceUrls(r, urlObj, CSS_IMPORT_REGEXP);
+      return r;
+    },
+    replaceUrls: function(text, urlObj, regexp) {
+      return text.replace(regexp, function(m, pre, url, post) {
+        var urlPath = url.replace(/["']/g, "");
+        urlObj.href = urlPath;
+        urlPath = urlObj.href;
+        return pre + "'" + urlPath + "'" + post;
+      });
+    }
+  };
+  scope.path = path;
+});
+
+HTMLImports.addModule(function(scope) {
+  var xhr = {
+    async: true,
+    ok: function(request) {
+      return request.status >= 200 && request.status < 300 || request.status === 304 || request.status === 0;
+    },
+    load: function(url, next, nextContext) {
+      var request = new XMLHttpRequest();
+      if (scope.flags.debug || scope.flags.bust) {
+        url += "?" + Math.random();
+      }
+      request.open("GET", url, xhr.async);
+      request.addEventListener("readystatechange", function(e) {
+        if (request.readyState === 4) {
+          var locationHeader = request.getResponseHeader("Location");
+          var redirectedUrl = null;
+          if (locationHeader) {
+            var redirectedUrl = locationHeader.substr(0, 1) === "/" ? location.origin + locationHeader : locationHeader;
+          }
+          next.call(nextContext, !xhr.ok(request) && request, request.response || request.responseText, redirectedUrl);
+        }
+      });
+      request.send();
+      return request;
+    },
+    loadDocument: function(url, next, nextContext) {
+      this.load(url, next, nextContext).responseType = "document";
+    }
+  };
+  scope.xhr = xhr;
+});
+
+HTMLImports.addModule(function(scope) {
+  var xhr = scope.xhr;
+  var flags = scope.flags;
+  var Loader = function(onLoad, onComplete) {
+    this.cache = {};
+    this.onload = onLoad;
+    this.oncomplete = onComplete;
+    this.inflight = 0;
+    this.pending = {};
+  };
+  Loader.prototype = {
+    addNodes: function(nodes) {
+      this.inflight += nodes.length;
+      for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {
+        this.require(n);
+      }
+      this.checkDone();
+    },
+    addNode: function(node) {
+      this.inflight++;
+      this.require(node);
+      this.checkDone();
+    },
+    require: function(elt) {
+      var url = elt.src || elt.href;
+      elt.__nodeUrl = url;
+      if (!this.dedupe(url, elt)) {
+        this.fetch(url, elt);
+      }
+    },
+    dedupe: function(url, elt) {
+      if (this.pending[url]) {
+        this.pending[url].push(elt);
+        return true;
+      }
+      var resource;
+      if (this.cache[url]) {
+        this.onload(url, elt, this.cache[url]);
+        this.tail();
+        return true;
+      }
+      this.pending[url] = [ elt ];
+      return false;
+    },
+    fetch: function(url, elt) {
+      flags.load && console.log("fetch", url, elt);
+      if (!url) {
+        setTimeout(function() {
+          this.receive(url, elt, {
+            error: "href must be specified"
+          }, null);
+        }.bind(this), 0);
+      } else if (url.match(/^data:/)) {
+        var pieces = url.split(",");
+        var header = pieces[0];
+        var body = pieces[1];
+        if (header.indexOf(";base64") > -1) {
+          body = atob(body);
+        } else {
+          body = decodeURIComponent(body);
+        }
+        setTimeout(function() {
+          this.receive(url, elt, null, body);
+        }.bind(this), 0);
+      } else {
+        var receiveXhr = function(err, resource, redirectedUrl) {
+          this.receive(url, elt, err, resource, redirectedUrl);
+        }.bind(this);
+        xhr.load(url, receiveXhr);
+      }
+    },
+    receive: function(url, elt, err, resource, redirectedUrl) {
+      this.cache[url] = resource;
+      var $p = this.pending[url];
+      for (var i = 0, l = $p.length, p; i < l && (p = $p[i]); i++) {
+        this.onload(url, p, resource, err, redirectedUrl);
+        this.tail();
+      }
+      this.pending[url] = null;
+    },
+    tail: function() {
+      --this.inflight;
+      this.checkDone();
+    },
+    checkDone: function() {
+      if (!this.inflight) {
+        this.oncomplete();
+      }
+    }
+  };
+  scope.Loader = Loader;
+});
+
+HTMLImports.addModule(function(scope) {
+  var Observer = function(addCallback) {
+    this.addCallback = addCallback;
+    this.mo = new MutationObserver(this.handler.bind(this));
+  };
+  Observer.prototype = {
+    handler: function(mutations) {
+      for (var i = 0, l = mutations.length, m; i < l && (m = mutations[i]); i++) {
+        if (m.type === "childList" && m.addedNodes.length) {
+          this.addedNodes(m.addedNodes);
+        }
+      }
+    },
+    addedNodes: function(nodes) {
+      if (this.addCallback) {
+        this.addCallback(nodes);
+      }
+      for (var i = 0, l = nodes.length, n, loading; i < l && (n = nodes[i]); i++) {
+        if (n.children && n.children.length) {
+          this.addedNodes(n.children);
+        }
+      }
+    },
+    observe: function(root) {
+      this.mo.observe(root, {
+        childList: true,
+        subtree: true
+      });
+    }
+  };
+  scope.Observer = Observer;
+});
+
+HTMLImports.addModule(function(scope) {
+  var path = scope.path;
+  var rootDocument = scope.rootDocument;
+  var flags = scope.flags;
+  var isIE = scope.isIE;
+  var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;
+  var IMPORT_SELECTOR = "link[rel=" + IMPORT_LINK_TYPE + "]";
+  var importParser = {
+    documentSelectors: IMPORT_SELECTOR,
+    importsSelectors: [ IMPORT_SELECTOR, "link[rel=stylesheet]", "style", "script:not([type])", 'script[type="text/javascript"]' ].join(","),
+    map: {
+      link: "parseLink",
+      script: "parseScript",
+      style: "parseStyle"
+    },
+    dynamicElements: [],
+    parseNext: function() {
+      var next = this.nextToParse();
+      if (next) {
+        this.parse(next);
+      }
+    },
+    parse: function(elt) {
+      if (this.isParsed(elt)) {
+        flags.parse && console.log("[%s] is already parsed", elt.localName);
+        return;
+      }
+      var fn = this[this.map[elt.localName]];
+      if (fn) {
+        this.markParsing(elt);
+        fn.call(this, elt);
+      }
+    },
+    parseDynamic: function(elt, quiet) {
+      this.dynamicElements.push(elt);
+      if (!quiet) {
+        this.parseNext();
+      }
+    },
+    markParsing: function(elt) {
+      flags.parse && console.log("parsing", elt);
+      this.parsingElement = elt;
+    },
+    markParsingComplete: function(elt) {
+      elt.__importParsed = true;
+      this.markDynamicParsingComplete(elt);
+      if (elt.__importElement) {
+        elt.__importElement.__importParsed = true;
+        this.markDynamicParsingComplete(elt.__importElement);
+      }
+      this.parsingElement = null;
+      flags.parse && console.log("completed", elt);
+    },
+    markDynamicParsingComplete: function(elt) {
+      var i = this.dynamicElements.indexOf(elt);
+      if (i >= 0) {
+        this.dynamicElements.splice(i, 1);
+      }
+    },
+    parseImport: function(elt) {
+      if (HTMLImports.__importsParsingHook) {
+        HTMLImports.__importsParsingHook(elt);
+      }
+      if (elt.import) {
+        elt.import.__importParsed = true;
+      }
+      this.markParsingComplete(elt);
+      if (elt.__resource && !elt.__error) {
+        elt.dispatchEvent(new CustomEvent("load", {
+          bubbles: false
+        }));
+      } else {
+        elt.dispatchEvent(new CustomEvent("error", {
+          bubbles: false
+        }));
+      }
+      if (elt.__pending) {
+        var fn;
+        while (elt.__pending.length) {
+          fn = elt.__pending.shift();
+          if (fn) {
+            fn({
+              target: elt
+            });
+          }
+        }
+      }
+      this.parseNext();
+    },
+    parseLink: function(linkElt) {
+      if (nodeIsImport(linkElt)) {
+        this.parseImport(linkElt);
+      } else {
+        linkElt.href = linkElt.href;
+        this.parseGeneric(linkElt);
+      }
+    },
+    parseStyle: function(elt) {
+      var src = elt;
+      elt = cloneStyle(elt);
+      elt.__importElement = src;
+      this.parseGeneric(elt);
+    },
+    parseGeneric: function(elt) {
+      this.trackElement(elt);
+      this.addElementToDocument(elt);
+    },
+    rootImportForElement: function(elt) {
+      var n = elt;
+      while (n.ownerDocument.__importLink) {
+        n = n.ownerDocument.__importLink;
+      }
+      return n;
+    },
+    addElementToDocument: function(elt) {
+      var port = this.rootImportForElement(elt.__importElement || elt);
+      port.parentNode.insertBefore(elt, port);
+    },
+    trackElement: function(elt, callback) {
+      var self = this;
+      var done = function(e) {
+        if (callback) {
+          callback(e);
+        }
+        self.markParsingComplete(elt);
+        self.parseNext();
+      };
+      elt.addEventListener("load", done);
+      elt.addEventListener("error", done);
+      if (isIE && elt.localName === "style") {
+        var fakeLoad = false;
+        if (elt.textContent.indexOf("@import") == -1) {
+          fakeLoad = true;
+        } else if (elt.sheet) {
+          fakeLoad = true;
+          var csr = elt.sheet.cssRules;
+          var len = csr ? csr.length : 0;
+          for (var i = 0, r; i < len && (r = csr[i]); i++) {
+            if (r.type === CSSRule.IMPORT_RULE) {
+              fakeLoad = fakeLoad && Boolean(r.styleSheet);
+            }
+          }
+        }
+        if (fakeLoad) {
+          elt.dispatchEvent(new CustomEvent("load", {
+            bubbles: false
+          }));
+        }
+      }
+    },
+    parseScript: function(scriptElt) {
+      var script = document.createElement("script");
+      script.__importElement = scriptElt;
+      script.src = scriptElt.src ? scriptElt.src : generateScriptDataUrl(scriptElt);
+      scope.currentScript = scriptElt;
+      this.trackElement(script, function(e) {
+        script.parentNode.removeChild(script);
+        scope.currentScript = null;
+      });
+      this.addElementToDocument(script);
+    },
+    nextToParse: function() {
+      this._mayParse = [];
+      return !this.parsingElement && (this.nextToParseInDoc(rootDocument) || this.nextToParseDynamic());
+    },
+    nextToParseInDoc: function(doc, link) {
+      if (doc && this._mayParse.indexOf(doc) < 0) {
+        this._mayParse.push(doc);
+        var nodes = doc.querySelectorAll(this.parseSelectorsForNode(doc));
+        for (var i = 0, l = nodes.length, p = 0, n; i < l && (n = nodes[i]); i++) {
+          if (!this.isParsed(n)) {
+            if (this.hasResource(n)) {
+              return nodeIsImport(n) ? this.nextToParseInDoc(n.import, n) : n;
+            } else {
+              return;
+            }
+          }
+        }
+      }
+      return link;
+    },
+    nextToParseDynamic: function() {
+      return this.dynamicElements[0];
+    },
+    parseSelectorsForNode: function(node) {
+      var doc = node.ownerDocument || node;
+      return doc === rootDocument ? this.documentSelectors : this.importsSelectors;
+    },
+    isParsed: function(node) {
+      return node.__importParsed;
+    },
+    needsDynamicParsing: function(elt) {
+      return this.dynamicElements.indexOf(elt) >= 0;
+    },
+    hasResource: function(node) {
+      if (nodeIsImport(node) && node.import === undefined) {
+        return false;
+      }
+      return true;
+    }
+  };
+  function nodeIsImport(elt) {
+    return elt.localName === "link" && elt.rel === IMPORT_LINK_TYPE;
+  }
+  function generateScriptDataUrl(script) {
+    var scriptContent = generateScriptContent(script);
+    return "data:text/javascript;charset=utf-8," + encodeURIComponent(scriptContent);
+  }
+  function generateScriptContent(script) {
+    return script.textContent + generateSourceMapHint(script);
+  }
+  function generateSourceMapHint(script) {
+    var owner = script.ownerDocument;
+    owner.__importedScripts = owner.__importedScripts || 0;
+    var moniker = script.ownerDocument.baseURI;
+    var num = owner.__importedScripts ? "-" + owner.__importedScripts : "";
+    owner.__importedScripts++;
+    return "\n//# sourceURL=" + moniker + num + ".js\n";
+  }
+  function cloneStyle(style) {
+    var clone = style.ownerDocument.createElement("style");
+    clone.textContent = style.textContent;
+    path.resolveUrlsInStyle(clone);
+    return clone;
+  }
+  scope.parser = importParser;
+  scope.IMPORT_SELECTOR = IMPORT_SELECTOR;
+});
+
+HTMLImports.addModule(function(scope) {
+  var flags = scope.flags;
+  var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;
+  var IMPORT_SELECTOR = scope.IMPORT_SELECTOR;
+  var rootDocument = scope.rootDocument;
+  var Loader = scope.Loader;
+  var Observer = scope.Observer;
+  var parser = scope.parser;
+  var importer = {
+    documents: {},
+    documentPreloadSelectors: IMPORT_SELECTOR,
+    importsPreloadSelectors: [ IMPORT_SELECTOR ].join(","),
+    loadNode: function(node) {
+      importLoader.addNode(node);
+    },
+    loadSubtree: function(parent) {
+      var nodes = this.marshalNodes(parent);
+      importLoader.addNodes(nodes);
+    },
+    marshalNodes: function(parent) {
+      return parent.querySelectorAll(this.loadSelectorsForNode(parent));
+    },
+    loadSelectorsForNode: function(node) {
+      var doc = node.ownerDocument || node;
+      return doc === rootDocument ? this.documentPreloadSelectors : this.importsPreloadSelectors;
+    },
+    loaded: function(url, elt, resource, err, redirectedUrl) {
+      flags.load && console.log("loaded", url, elt);
+      elt.__resource = resource;
+      elt.__error = err;
+      if (isImportLink(elt)) {
+        var doc = this.documents[url];
+        if (doc === undefined) {
+          doc = err ? null : makeDocument(resource, redirectedUrl || url);
+          if (doc) {
+            doc.__importLink = elt;
+            this.bootDocument(doc);
+          }
+          this.documents[url] = doc;
+        }
+        elt.import = doc;
+      }
+      parser.parseNext();
+    },
+    bootDocument: function(doc) {
+      this.loadSubtree(doc);
+      this.observer.observe(doc);
+      parser.parseNext();
+    },
+    loadedAll: function() {
+      parser.parseNext();
+    }
+  };
+  var importLoader = new Loader(importer.loaded.bind(importer), importer.loadedAll.bind(importer));
+  importer.observer = new Observer();
+  function isImportLink(elt) {
+    return isLinkRel(elt, IMPORT_LINK_TYPE);
+  }
+  function isLinkRel(elt, rel) {
+    return elt.localName === "link" && elt.getAttribute("rel") === rel;
+  }
+  function hasBaseURIAccessor(doc) {
+    return !!Object.getOwnPropertyDescriptor(doc, "baseURI");
+  }
+  function makeDocument(resource, url) {
+    var doc = document.implementation.createHTMLDocument(IMPORT_LINK_TYPE);
+    doc._URL = url;
+    var base = doc.createElement("base");
+    base.setAttribute("href", url);
+    if (!doc.baseURI && !hasBaseURIAccessor(doc)) {
+      Object.defineProperty(doc, "baseURI", {
+        value: url
+      });
+    }
+    var meta = doc.createElement("meta");
+    meta.setAttribute("charset", "utf-8");
+    doc.head.appendChild(meta);
+    doc.head.appendChild(base);
+    doc.body.innerHTML = resource;
+    if (window.HTMLTemplateElement && HTMLTemplateElement.bootstrap) {
+      HTMLTemplateElement.bootstrap(doc);
+    }
+    return doc;
+  }
+  if (!document.baseURI) {
+    var baseURIDescriptor = {
+      get: function() {
+        var base = document.querySelector("base");
+        return base ? base.href : window.location.href;
+      },
+      configurable: true
+    };
+    Object.defineProperty(document, "baseURI", baseURIDescriptor);
+    Object.defineProperty(rootDocument, "baseURI", baseURIDescriptor);
+  }
+  scope.importer = importer;
+  scope.importLoader = importLoader;
+});
+
+HTMLImports.addModule(function(scope) {
+  var parser = scope.parser;
+  var importer = scope.importer;
+  var dynamic = {
+    added: function(nodes) {
+      var owner, parsed, loading;
+      for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {
+        if (!owner) {
+          owner = n.ownerDocument;
+          parsed = parser.isParsed(owner);
+        }
+        loading = this.shouldLoadNode(n);
+        if (loading) {
+          importer.loadNode(n);
+        }
+        if (this.shouldParseNode(n) && parsed) {
+          parser.parseDynamic(n, loading);
+        }
+      }
+    },
+    shouldLoadNode: function(node) {
+      return node.nodeType === 1 && matches.call(node, importer.loadSelectorsForNode(node));
+    },
+    shouldParseNode: function(node) {
+      return node.nodeType === 1 && matches.call(node, parser.parseSelectorsForNode(node));
+    }
+  };
+  importer.observer.addCallback = dynamic.added.bind(dynamic);
+  var matches = HTMLElement.prototype.matches || HTMLElement.prototype.matchesSelector || HTMLElement.prototype.webkitMatchesSelector || HTMLElement.prototype.mozMatchesSelector || HTMLElement.prototype.msMatchesSelector;
+});
+
+(function(scope) {
+  var initializeModules = scope.initializeModules;
+  var isIE = scope.isIE;
+  if (scope.useNative) {
+    return;
+  }
+  if (isIE && typeof window.CustomEvent !== "function") {
+    window.CustomEvent = function(inType, params) {
+      params = params || {};
+      var e = document.createEvent("CustomEvent");
+      e.initCustomEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable), params.detail);
+      return e;
+    };
+    window.CustomEvent.prototype = window.Event.prototype;
+  }
+  initializeModules();
+  var rootDocument = scope.rootDocument;
+  function bootstrap() {
+    HTMLImports.importer.bootDocument(rootDocument);
+  }
+  if (document.readyState === "complete" || document.readyState === "interactive" && !window.attachEvent) {
+    bootstrap();
+  } else {
+    document.addEventListener("DOMContentLoaded", bootstrap);
+  }
+})(HTMLImports);
+
+window.CustomElements = window.CustomElements || {
+  flags: {}
+};
+
+(function(scope) {
+  var flags = scope.flags;
+  var modules = [];
+  var addModule = function(module) {
+    modules.push(module);
+  };
+  var initializeModules = function() {
+    modules.forEach(function(module) {
+      module(scope);
+    });
+  };
+  scope.addModule = addModule;
+  scope.initializeModules = initializeModules;
+  scope.hasNative = Boolean(document.registerElement);
+  scope.useNative = !flags.register && scope.hasNative && !window.ShadowDOMPolyfill && (!window.HTMLImports || HTMLImports.useNative);
+})(CustomElements);
+
+CustomElements.addModule(function(scope) {
+  var IMPORT_LINK_TYPE = window.HTMLImports ? HTMLImports.IMPORT_LINK_TYPE : "none";
+  function forSubtree(node, cb) {
+    findAllElements(node, function(e) {
+      if (cb(e)) {
+        return true;
+      }
+      forRoots(e, cb);
+    });
+    forRoots(node, cb);
+  }
+  function findAllElements(node, find, data) {
+    var e = node.firstElementChild;
+    if (!e) {
+      e = node.firstChild;
+      while (e && e.nodeType !== Node.ELEMENT_NODE) {
+        e = e.nextSibling;
+      }
+    }
+    while (e) {
+      if (find(e, data) !== true) {
+        findAllElements(e, find, data);
+      }
+      e = e.nextElementSibling;
+    }
+    return null;
+  }
+  function forRoots(node, cb) {
+    var root = node.shadowRoot;
+    while (root) {
+      forSubtree(root, cb);
+      root = root.olderShadowRoot;
+    }
+  }
+  var processingDocuments;
+  function forDocumentTree(doc, cb) {
+    processingDocuments = [];
+    _forDocumentTree(doc, cb);
+    processingDocuments = null;
+  }
+  function _forDocumentTree(doc, cb) {
+    doc = wrap(doc);
+    if (processingDocuments.indexOf(doc) >= 0) {
+      return;
+    }
+    processingDocuments.push(doc);
+    var imports = doc.querySelectorAll("link[rel=" + IMPORT_LINK_TYPE + "]");
+    for (var i = 0, l = imports.length, n; i < l && (n = imports[i]); i++) {
+      if (n.import) {
+        _forDocumentTree(n.import, cb);
+      }
+    }
+    cb(doc);
+  }
+  scope.forDocumentTree = forDocumentTree;
+  scope.forSubtree = forSubtree;
+});
+
+CustomElements.addModule(function(scope) {
+  var flags = scope.flags;
+  var forSubtree = scope.forSubtree;
+  var forDocumentTree = scope.forDocumentTree;
+  function addedNode(node) {
+    return added(node) || addedSubtree(node);
+  }
+  function added(node) {
+    if (scope.upgrade(node)) {
+      return true;
+    }
+    attached(node);
+  }
+  function addedSubtree(node) {
+    forSubtree(node, function(e) {
+      if (added(e)) {
+        return true;
+      }
+    });
+  }
+  function attachedNode(node) {
+    attached(node);
+    if (inDocument(node)) {
+      forSubtree(node, function(e) {
+        attached(e);
+      });
+    }
+  }
+  var hasPolyfillMutations = !window.MutationObserver || window.MutationObserver === window.JsMutationObserver;
+  scope.hasPolyfillMutations = hasPolyfillMutations;
+  var isPendingMutations = false;
+  var pendingMutations = [];
+  function deferMutation(fn) {
+    pendingMutations.push(fn);
+    if (!isPendingMutations) {
+      isPendingMutations = true;
+      setTimeout(takeMutations);
+    }
+  }
+  function takeMutations() {
+    isPendingMutations = false;
+    var $p = pendingMutations;
+    for (var i = 0, l = $p.length, p; i < l && (p = $p[i]); i++) {
+      p();
+    }
+    pendingMutations = [];
+  }
+  function attached(element) {
+    if (hasPolyfillMutations) {
+      deferMutation(function() {
+        _attached(element);
+      });
+    } else {
+      _attached(element);
+    }
+  }
+  function _attached(element) {
+    if (element.__upgraded__ && (element.attachedCallback || element.detachedCallback)) {
+      if (!element.__attached && inDocument(element)) {
+        element.__attached = true;
+        if (element.attachedCallback) {
+          element.attachedCallback();
+        }
+      }
+    }
+  }
+  function detachedNode(node) {
+    detached(node);
+    forSubtree(node, function(e) {
+      detached(e);
+    });
+  }
+  function detached(element) {
+    if (hasPolyfillMutations) {
+      deferMutation(function() {
+        _detached(element);
+      });
+    } else {
+      _detached(element);
+    }
+  }
+  function _detached(element) {
+    if (element.__upgraded__ && (element.attachedCallback || element.detachedCallback)) {
+      if (element.__attached && !inDocument(element)) {
+        element.__attached = false;
+        if (element.detachedCallback) {
+          element.detachedCallback();
+        }
+      }
+    }
+  }
+  function inDocument(element) {
+    var p = element;
+    var doc = wrap(document);
+    while (p) {
+      if (p == doc) {
+        return true;
+      }
+      p = p.parentNode || p.host;
+    }
+  }
+  function watchShadow(node) {
+    if (node.shadowRoot && !node.shadowRoot.__watched) {
+      flags.dom && console.log("watching shadow-root for: ", node.localName);
+      var root = node.shadowRoot;
+      while (root) {
+        observe(root);
+        root = root.olderShadowRoot;
+      }
+    }
+  }
+  function handler(mutations) {
+    if (flags.dom) {
+      var mx = mutations[0];
+      if (mx && mx.type === "childList" && mx.addedNodes) {
+        if (mx.addedNodes) {
+          var d = mx.addedNodes[0];
+          while (d && d !== document && !d.host) {
+            d = d.parentNode;
+          }
+          var u = d && (d.URL || d._URL || d.host && d.host.localName) || "";
+          u = u.split("/?").shift().split("/").pop();
+        }
+      }
+      console.group("mutations (%d) [%s]", mutations.length, u || "");
+    }
+    mutations.forEach(function(mx) {
+      if (mx.type === "childList") {
+        forEach(mx.addedNodes, function(n) {
+          if (!n.localName) {
+            return;
+          }
+          addedNode(n);
+        });
+        forEach(mx.removedNodes, function(n) {
+          if (!n.localName) {
+            return;
+          }
+          detachedNode(n);
+        });
+      }
+    });
+    flags.dom && console.groupEnd();
+  }
+  function takeRecords(node) {
+    node = wrap(node);
+    if (!node) {
+      node = wrap(document);
+    }
+    while (node.parentNode) {
+      node = node.parentNode;
+    }
+    var observer = node.__observer;
+    if (observer) {
+      handler(observer.takeRecords());
+      takeMutations();
+    }
+  }
+  var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);
+  function observe(inRoot) {
+    if (inRoot.__observer) {
+      return;
+    }
+    var observer = new MutationObserver(handler);
+    observer.observe(inRoot, {
+      childList: true,
+      subtree: true
+    });
+    inRoot.__observer = observer;
+  }
+  function upgradeDocument(doc) {
+    doc = wrap(doc);
+    flags.dom && console.group("upgradeDocument: ", doc.baseURI.split("/").pop());
+    addedNode(doc);
+    observe(doc);
+    flags.dom && console.groupEnd();
+  }
+  function upgradeDocumentTree(doc) {
+    forDocumentTree(doc, upgradeDocument);
+  }
+  var originalCreateShadowRoot = Element.prototype.createShadowRoot;
+  if (originalCreateShadowRoot) {
+    Element.prototype.createShadowRoot = function() {
+      var root = originalCreateShadowRoot.call(this);
+      CustomElements.watchShadow(this);
+      return root;
+    };
+  }
+  scope.watchShadow = watchShadow;
+  scope.upgradeDocumentTree = upgradeDocumentTree;
+  scope.upgradeSubtree = addedSubtree;
+  scope.upgradeAll = addedNode;
+  scope.attachedNode = attachedNode;
+  scope.takeRecords = takeRecords;
+});
+
+CustomElements.addModule(function(scope) {
+  var flags = scope.flags;
+  function upgrade(node) {
+    if (!node.__upgraded__ && node.nodeType === Node.ELEMENT_NODE) {
+      var is = node.getAttribute("is");
+      var definition = scope.getRegisteredDefinition(is || node.localName);
+      if (definition) {
+        if (is && definition.tag == node.localName) {
+          return upgradeWithDefinition(node, definition);
+        } else if (!is && !definition.extends) {
+          return upgradeWithDefinition(node, definition);
+        }
+      }
+    }
+  }
+  function upgradeWithDefinition(element, definition) {
+    flags.upgrade && console.group("upgrade:", element.localName);
+    if (definition.is) {
+      element.setAttribute("is", definition.is);
+    }
+    implementPrototype(element, definition);
+    element.__upgraded__ = true;
+    created(element);
+    scope.attachedNode(element);
+    scope.upgradeSubtree(element);
+    flags.upgrade && console.groupEnd();
+    return element;
+  }
+  function implementPrototype(element, definition) {
+    if (Object.__proto__) {
+      element.__proto__ = definition.prototype;
+    } else {
+      customMixin(element, definition.prototype, definition.native);
+      element.__proto__ = definition.prototype;
+    }
+  }
+  function customMixin(inTarget, inSrc, inNative) {
+    var used = {};
+    var p = inSrc;
+    while (p !== inNative && p !== HTMLElement.prototype) {
+      var keys = Object.getOwnPropertyNames(p);
+      for (var i = 0, k; k = keys[i]; i++) {
+        if (!used[k]) {
+          Object.defineProperty(inTarget, k, Object.getOwnPropertyDescriptor(p, k));
+          used[k] = 1;
+        }
+      }
+      p = Object.getPrototypeOf(p);
+    }
+  }
+  function created(element) {
+    if (element.createdCallback) {
+      element.createdCallback();
+    }
+  }
+  scope.upgrade = upgrade;
+  scope.upgradeWithDefinition = upgradeWithDefinition;
+  scope.implementPrototype = implementPrototype;
+});
+
+CustomElements.addModule(function(scope) {
+  var upgradeDocumentTree = scope.upgradeDocumentTree;
+  var upgrade = scope.upgrade;
+  var upgradeWithDefinition = scope.upgradeWithDefinition;
+  var implementPrototype = scope.implementPrototype;
+  var useNative = scope.useNative;
+  function register(name, options) {
+    var definition = options || {};
+    if (!name) {
+      throw new Error("document.registerElement: first argument `name` must not be empty");
+    }
+    if (name.indexOf("-") < 0) {
+      throw new Error("document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '" + String(name) + "'.");
+    }
+    if (isReservedTag(name)) {
+      throw new Error("Failed to execute 'registerElement' on 'Document': Registration failed for type '" + String(name) + "'. The type name is invalid.");
+    }
+    if (getRegisteredDefinition(name)) {
+      throw new Error("DuplicateDefinitionError: a type with name '" + String(name) + "' is already registered");
+    }
+    if (!definition.prototype) {
+      definition.prototype = Object.create(HTMLElement.prototype);
+    }
+    definition.__name = name.toLowerCase();
+    definition.lifecycle = definition.lifecycle || {};
+    definition.ancestry = ancestry(definition.extends);
+    resolveTagName(definition);
+    resolvePrototypeChain(definition);
+    overrideAttributeApi(definition.prototype);
+    registerDefinition(definition.__name, definition);
+    definition.ctor = generateConstructor(definition);
+    definition.ctor.prototype = definition.prototype;
+    definition.prototype.constructor = definition.ctor;
+    if (scope.ready) {
+      upgradeDocumentTree(document);
+    }
+    return definition.ctor;
+  }
+  function overrideAttributeApi(prototype) {
+    if (prototype.setAttribute._polyfilled) {
+      return;
+    }
+    var setAttribute = prototype.setAttribute;
+    prototype.setAttribute = function(name, value) {
+      changeAttribute.call(this, name, value, setAttribute);
+    };
+    var removeAttribute = prototype.removeAttribute;
+    prototype.removeAttribute = function(name) {
+      changeAttribute.call(this, name, null, removeAttribute);
+    };
+    prototype.setAttribute._polyfilled = true;
+  }
+  function changeAttribute(name, value, operation) {
+    name = name.toLowerCase();
+    var oldValue = this.getAttribute(name);
+    operation.apply(this, arguments);
+    var newValue = this.getAttribute(name);
+    if (this.attributeChangedCallback && newValue !== oldValue) {
+      this.attributeChangedCallback(name, oldValue, newValue);
+    }
+  }
+  function isReservedTag(name) {
+    for (var i = 0; i < reservedTagList.length; i++) {
+      if (name === reservedTagList[i]) {
+        return true;
+      }
+    }
+  }
+  var reservedTagList = [ "annotation-xml", "color-profile", "font-face", "font-face-src", "font-face-uri", "font-face-format", "font-face-name", "missing-glyph" ];
+  function ancestry(extnds) {
+    var extendee = getRegisteredDefinition(extnds);
+    if (extendee) {
+      return ancestry(extendee.extends).concat([ extendee ]);
+    }
+    return [];
+  }
+  function resolveTagName(definition) {
+    var baseTag = definition.extends;
+    for (var i = 0, a; a = definition.ancestry[i]; i++) {
+      baseTag = a.is && a.tag;
+    }
+    definition.tag = baseTag || definition.__name;
+    if (baseTag) {
+      definition.is = definition.__name;
+    }
+  }
+  function resolvePrototypeChain(definition) {
+    if (!Object.__proto__) {
+      var nativePrototype = HTMLElement.prototype;
+      if (definition.is) {
+        var inst = document.createElement(definition.tag);
+        var expectedPrototype = Object.getPrototypeOf(inst);
+        if (expectedPrototype === definition.prototype) {
+          nativePrototype = expectedPrototype;
+        }
+      }
+      var proto = definition.prototype, ancestor;
+      while (proto && proto !== nativePrototype) {
+        ancestor = Object.getPrototypeOf(proto);
+        proto.__proto__ = ancestor;
+        proto = ancestor;
+      }
+      definition.native = nativePrototype;
+    }
+  }
+  function instantiate(definition) {
+    return upgradeWithDefinition(domCreateElement(definition.tag), definition);
+  }
+  var registry = {};
+  function getRegisteredDefinition(name) {
+    if (name) {
+      return registry[name.toLowerCase()];
+    }
+  }
+  function registerDefinition(name, definition) {
+    registry[name] = definition;
+  }
+  function generateConstructor(definition) {
+    return function() {
+      return instantiate(definition);
+    };
+  }
+  var HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
+  function createElementNS(namespace, tag, typeExtension) {
+    if (namespace === HTML_NAMESPACE) {
+      return createElement(tag, typeExtension);
+    } else {
+      return domCreateElementNS(namespace, tag);
+    }
+  }
+  function createElement(tag, typeExtension) {
+    var definition = getRegisteredDefinition(typeExtension || tag);
+    if (definition) {
+      if (tag == definition.tag && typeExtension == definition.is) {
+        return new definition.ctor();
+      }
+      if (!typeExtension && !definition.is) {
+        return new definition.ctor();
+      }
+    }
+    var element;
+    if (typeExtension) {
+      element = createElement(tag);
+      element.setAttribute("is", typeExtension);
+      return element;
+    }
+    element = domCreateElement(tag);
+    if (tag.indexOf("-") >= 0) {
+      implementPrototype(element, HTMLElement);
+    }
+    return element;
+  }
+  function cloneNode(deep) {
+    var n = domCloneNode.call(this, deep);
+    upgrade(n);
+    return n;
+  }
+  var domCreateElement = document.createElement.bind(document);
+  var domCreateElementNS = document.createElementNS.bind(document);
+  var domCloneNode = Node.prototype.cloneNode;
+  var isInstance;
+  if (!Object.__proto__ && !useNative) {
+    isInstance = function(obj, ctor) {
+      var p = obj;
+      while (p) {
+        if (p === ctor.prototype) {
+          return true;
+        }
+        p = p.__proto__;
+      }
+      return false;
+    };
+  } else {
+    isInstance = function(obj, base) {
+      return obj instanceof base;
+    };
+  }
+  document.registerElement = register;
+  document.createElement = createElement;
+  document.createElementNS = createElementNS;
+  Node.prototype.cloneNode = cloneNode;
+  scope.registry = registry;
+  scope.instanceof = isInstance;
+  scope.reservedTagList = reservedTagList;
+  scope.getRegisteredDefinition = getRegisteredDefinition;
+  document.register = document.registerElement;
+});
+
+(function(scope) {
+  var useNative = scope.useNative;
+  var initializeModules = scope.initializeModules;
+  var isIE11OrOlder = /Trident/.test(navigator.userAgent);
+  if (useNative) {
+    var nop = function() {};
+    scope.watchShadow = nop;
+    scope.upgrade = nop;
+    scope.upgradeAll = nop;
+    scope.upgradeDocumentTree = nop;
+    scope.upgradeSubtree = nop;
+    scope.takeRecords = nop;
+    scope.instanceof = function(obj, base) {
+      return obj instanceof base;
+    };
+  } else {
+    initializeModules();
+  }
+  var upgradeDocumentTree = scope.upgradeDocumentTree;
+  if (!window.wrap) {
+    if (window.ShadowDOMPolyfill) {
+      window.wrap = ShadowDOMPolyfill.wrapIfNeeded;
+      window.unwrap = ShadowDOMPolyfill.unwrapIfNeeded;
+    } else {
+      window.wrap = window.unwrap = function(node) {
+        return node;
+      };
+    }
+  }
+  function bootstrap() {
+    upgradeDocumentTree(wrap(document));
+    if (window.HTMLImports) {
+      HTMLImports.__importsParsingHook = function(elt) {
+        upgradeDocumentTree(wrap(elt.import));
+      };
+    }
+    CustomElements.ready = true;
+    setTimeout(function() {
+      CustomElements.readyTime = Date.now();
+      if (window.HTMLImports) {
+        CustomElements.elapsed = CustomElements.readyTime - HTMLImports.readyTime;
+      }
+      document.dispatchEvent(new CustomEvent("WebComponentsReady", {
+        bubbles: true
+      }));
+    });
+  }
+  if (isIE11OrOlder && typeof window.CustomEvent !== "function") {
+    window.CustomEvent = function(inType, params) {
+      params = params || {};
+      var e = document.createEvent("CustomEvent");
+      e.initCustomEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable), params.detail);
+      return e;
+    };
+    window.CustomEvent.prototype = window.Event.prototype;
+  }
+  if (document.readyState === "complete" || scope.flags.eager) {
+    bootstrap();
+  } else if (document.readyState === "interactive" && !window.attachEvent && (!window.HTMLImports || window.HTMLImports.ready)) {
+    bootstrap();
+  } else {
+    var loadEvent = window.HTMLImports && !HTMLImports.ready ? "HTMLImportsLoaded" : "DOMContentLoaded";
+    window.addEventListener(loadEvent, bootstrap);
+  }
+})(window.CustomElements);
+
+(function(scope) {
+  if (!Function.prototype.bind) {
+    Function.prototype.bind = function(scope) {
+      var self = this;
+      var args = Array.prototype.slice.call(arguments, 1);
+      return function() {
+        var args2 = args.slice();
+        args2.push.apply(args2, arguments);
+        return self.apply(scope, args2);
+      };
+    };
+  }
+})(window.WebComponents);
+
+(function(scope) {
+  "use strict";
+  if (!window.performance) {
+    var start = Date.now();
+    window.performance = {
+      now: function() {
+        return Date.now() - start;
+      }
+    };
+  }
+  if (!window.requestAnimationFrame) {
+    window.requestAnimationFrame = function() {
+      var nativeRaf = window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame;
+      return nativeRaf ? function(callback) {
+        return nativeRaf(function() {
+          callback(performance.now());
+        });
+      } : function(callback) {
+        return window.setTimeout(callback, 1e3 / 60);
+      };
+    }();
+  }
+  if (!window.cancelAnimationFrame) {
+    window.cancelAnimationFrame = function() {
+      return window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || function(id) {
+        clearTimeout(id);
+      };
+    }();
+  }
+  var elementDeclarations = [];
+  var polymerStub = function(name, dictionary) {
+    if (typeof name !== "string" && arguments.length === 1) {
+      Array.prototype.push.call(arguments, document._currentScript);
+    }
+    elementDeclarations.push(arguments);
+  };
+  window.Polymer = polymerStub;
+  scope.consumeDeclarations = function(callback) {
+    scope.consumeDeclarations = function() {
+      throw "Possible attempt to load Polymer twice";
+    };
+    if (callback) {
+      callback(elementDeclarations);
+    }
+    elementDeclarations = null;
+  };
+  function installPolymerWarning() {
+    if (window.Polymer === polymerStub) {
+      window.Polymer = function() {
+        throw new Error("You tried to use polymer without loading it first. To " + 'load polymer, ');
+      };
+    }
+  }
+  if (HTMLImports.useNative) {
+    installPolymerWarning();
+  } else {
+    addEventListener("DOMContentLoaded", installPolymerWarning);
+  }
+})(window.WebComponents);
+
+(function(scope) {
+  var style = document.createElement("style");
+  style.textContent = "" + "body {" + "transition: opacity ease-in 0.2s;" + " } \n" + "body[unresolved] {" + "opacity: 0; display: block; overflow: hidden; position: relative;" + " } \n";
+  var head = document.querySelector("head");
+  head.insertBefore(style, head.firstChild);
+})(window.WebComponents);
+
+(function(scope) {
+  window.Platform = scope;
+})(window.WebComponents);
\ No newline at end of file
diff --git a/example/bower_components/webcomponentsjs/webcomponents.min.js b/example/bower_components/webcomponentsjs/webcomponents.min.js
new file mode 100644
index 000000000..474305f73
--- /dev/null
+++ b/example/bower_components/webcomponentsjs/webcomponents.min.js
@@ -0,0 +1,14 @@
+/**
+ * @license
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+// @version 0.5.5
+window.WebComponents=window.WebComponents||{},function(e){var t=e.flags||{},n="webcomponents.js",r=document.querySelector('script[src*="'+n+'"]');if(!t.noOpts){if(location.search.slice(1).split("&").forEach(function(e){e=e.split("="),e[0]&&(t[e[0]]=e[1]||!0)}),r)for(var o,i=0;o=r.attributes[i];i++)"src"!==o.name&&(t[o.name]=o.value||!0);if(t.log){var a=t.log.split(",");t.log={},a.forEach(function(e){t.log[e]=!0})}else t.log={}}t.shadow=t.shadow||t.shadowdom||t.polyfill,t.shadow="native"===t.shadow?!1:t.shadow||!HTMLElement.prototype.createShadowRoot,t.register&&(window.CustomElements=window.CustomElements||{flags:{}},window.CustomElements.flags.register=t.register),e.flags=t}(WebComponents),WebComponents.flags.shadow&&("undefined"==typeof WeakMap&&!function(){var e=Object.defineProperty,t=Date.now()%1e9,n=function(){this.name="__st"+(1e9*Math.random()>>>0)+(t++ +"__")};n.prototype={set:function(t,n){var r=t[this.name];return r&&r[0]===t?r[1]=n:e(t,this.name,{value:[t,n],writable:!0}),this},get:function(e){var t;return(t=e[this.name])&&t[0]===e?t[1]:void 0},"delete":function(e){var t=e[this.name];return t&&t[0]===e?(t[0]=t[1]=void 0,!0):!1},has:function(e){var t=e[this.name];return t?t[0]===e:!1}},window.WeakMap=n}(),window.ShadowDOMPolyfill={},function(e){"use strict";function t(){if("undefined"!=typeof chrome&&chrome.app&&chrome.app.runtime)return!1;if(navigator.getDeviceStorage)return!1;try{var e=new Function("return true;");return e()}catch(t){return!1}}function n(e){if(!e)throw new Error("Assertion failed")}function r(e,t){for(var n=W(t),r=0;rl;l++)c[l]=new Array(s),c[l][0]=l;for(var u=0;s>u;u++)c[0][u]=u;for(var l=1;a>l;l++)for(var u=1;s>u;u++)if(this.equals(e[t+u-1],r[o+l-1]))c[l][u]=c[l-1][u-1];else{var d=c[l-1][u]+1,p=c[l][u-1]+1;c[l][u]=p>d?d:p}return c},spliceOperationsFromEditDistances:function(e){for(var t=e.length-1,n=e[0].length-1,s=e[t][n],c=[];t>0||n>0;)if(0!=t)if(0!=n){var l,u=e[t-1][n-1],d=e[t-1][n],p=e[t][n-1];l=p>d?u>d?d:u:u>p?p:u,l==u?(u==s?c.push(r):(c.push(o),s=u),t--,n--):l==d?(c.push(a),t--,s=d):(c.push(i),n--,s=p)}else c.push(a),t--;else c.push(i),n--;return c.reverse(),c},calcSplices:function(e,n,s,c,l,u){var d=0,p=0,f=Math.min(s-n,u-l);if(0==n&&0==l&&(d=this.sharedPrefix(e,c,f)),s==e.length&&u==c.length&&(p=this.sharedSuffix(e,c,f-d)),n+=d,l+=d,s-=p,u-=p,s-n==0&&u-l==0)return[];if(n==s){for(var h=t(n,[],0);u>l;)h.removed.push(c[l++]);return[h]}if(l==u)return[t(n,[],s-n)];for(var m=this.spliceOperationsFromEditDistances(this.calcEditDistances(e,n,s,c,l,u)),h=void 0,w=[],v=n,g=l,b=0;br;r++)if(!this.equals(e[r],t[r]))return r;return n},sharedSuffix:function(e,t,n){for(var r=e.length,o=t.length,i=0;n>i&&this.equals(e[--r],t[--o]);)i++;return i},calculateSplices:function(e,t){return this.calcSplices(e,0,e.length,t,0,t.length)},equals:function(e,t){return e===t}},e.ArraySplice=n}(window.ShadowDOMPolyfill),function(e){"use strict";function t(){a=!1;var e=i.slice(0);i=[];for(var t=0;t0){for(var u=0;u0&&r.length>0;){var i=n.pop(),a=r.pop();if(i!==a)break;o=i}return o}function u(e,t,n){t instanceof G.Window&&(t=t.document);var o,i=k(t),a=k(n),s=r(n,e),o=l(i,a);o||(o=a.root);for(var c=o;c;c=c.parent)for(var u=0;u0;i--)if(!g(t[i],e,o,t,r))return!1;return!0}function w(e,t,n,r){var o=it,i=t[0]||n;return g(i,e,o,t,r)}function v(e,t,n,r){for(var o=at,i=1;i0&&g(n,e,o,t,r)}function g(e,t,n,r,o){var i=z.get(e);if(!i)return!0;var a=o||s(r,e);if(a===e){if(n===ot)return!0;n===at&&(n=it)}else if(n===at&&!t.bubbles)return!0;if("relatedTarget"in t){var c=q(t),l=c.relatedTarget;if(l){if(l instanceof Object&&l.addEventListener){var d=V(l),p=u(t,e,d);if(p===a)return!0}else p=null;J.set(t,p)}}Z.set(t,n);var f=t.type,h=!1;X.set(t,a),$.set(t,e),i.depth++;for(var m=0,w=i.length;w>m;m++){var v=i[m];if(v.removed)h=!0;else if(!(v.type!==f||!v.capture&&n===ot||v.capture&&n===at))try{if("function"==typeof v.handler?v.handler.call(e,t):v.handler.handleEvent(t),et.get(t))return!1}catch(g){I||(I=g)}}if(i.depth--,h&&0===i.depth){var b=i.slice();i.length=0;for(var m=0;mr;r++)t[r]=a(e[r]);return t.length=o,t}function o(e,t){e.prototype[t]=function(){return r(i(this)[t].apply(i(this),arguments))}}var i=e.unsafeUnwrap,a=e.wrap,s={enumerable:!1};n.prototype={item:function(e){return this[e]}},t(n.prototype,"item"),e.wrappers.NodeList=n,e.addWrapNodeListMethod=o,e.wrapNodeList=r}(window.ShadowDOMPolyfill),function(e){"use strict";e.wrapHTMLCollection=e.wrapNodeList,e.wrappers.HTMLCollection=e.wrappers.NodeList}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){L(e instanceof S)}function n(e){var t=new M;return t[0]=e,t.length=1,t}function r(e,t,n){C(t,"childList",{removedNodes:n,previousSibling:e.previousSibling,nextSibling:e.nextSibling})}function o(e,t){C(e,"childList",{removedNodes:t})}function i(e,t,r,o){if(e instanceof DocumentFragment){var i=s(e);B=!0;for(var a=i.length-1;a>=0;a--)e.removeChild(i[a]),i[a].parentNode_=t;B=!1;for(var a=0;ao;o++)r.appendChild(I(t[o]));return r}function w(e){if(void 0!==e.firstChild_)for(var t=e.firstChild_;t;){var n=t;t=t.nextSibling_,n.parentNode_=n.previousSibling_=n.nextSibling_=void 0}e.firstChild_=e.lastChild_=void 0}function v(e){if(e.invalidateShadowRenderer()){for(var t=e.firstChild;t;){L(t.parentNode===e);var n=t.nextSibling,r=I(t),o=r.parentNode;o&&Y.call(o,r),t.previousSibling_=t.nextSibling_=t.parentNode_=null,t=n}e.firstChild_=e.lastChild_=null}else for(var n,i=I(e),a=i.firstChild;a;)n=a.nextSibling,Y.call(i,a),a=n}function g(e){var t=e.parentNode;return t&&t.invalidateShadowRenderer()}function b(e){for(var t,n=0;ns;s++)i=b(t[s]),!o&&(a=v(i).root)&&a instanceof e.wrappers.ShadowRoot||(r[n++]=i);return n}function n(e){return String(e).replace(/\/deep\/|::shadow/g," ")}function r(e){return String(e).replace(/:host\(([^\s]+)\)/g,"$1").replace(/([^\s]):host/g,"$1").replace(":host","*").replace(/\^|\/shadow\/|\/shadow-deep\/|::shadow|\/deep\/|::content/g," ")}function o(e,t){for(var n,r=e.firstElementChild;r;){if(r.matches(t))return r;if(n=o(r,t))return n;r=r.nextElementSibling}return null}function i(e,t){return e.matches(t)}function a(e,t,n){var r=e.localName;return r===t||r===n&&e.namespaceURI===D}function s(){return!0}function c(e,t,n){return e.localName===n}function l(e,t){return e.namespaceURI===t}function u(e,t,n){return e.namespaceURI===t&&e.localName===n}function d(e,t,n,r,o,i){for(var a=e.firstElementChild;a;)r(a,o,i)&&(n[t++]=a),t=d(a,t,n,r,o,i),a=a.nextElementSibling;return t}function p(n,r,o,i,a){var s,c=g(this),l=v(this).root;if(l instanceof e.wrappers.ShadowRoot)return d(this,r,o,n,i,null);if(c instanceof C)s=T.call(c,i);else{if(!(c instanceof N))return d(this,r,o,n,i,null);s=S.call(c,i)}return t(s,r,o,a)}function f(n,r,o,i,a){var s,c=g(this),l=v(this).root;if(l instanceof e.wrappers.ShadowRoot)return d(this,r,o,n,i,a);if(c instanceof C)s=_.call(c,i,a);else{if(!(c instanceof N))return d(this,r,o,n,i,a);s=M.call(c,i,a)}return t(s,r,o,!1)}function h(n,r,o,i,a){var s,c=g(this),l=v(this).root;if(l instanceof e.wrappers.ShadowRoot)return d(this,r,o,n,i,a);if(c instanceof C)s=O.call(c,i,a);else{if(!(c instanceof N))return d(this,r,o,n,i,a);s=L.call(c,i,a)}return t(s,r,o,!1)}var m=e.wrappers.HTMLCollection,w=e.wrappers.NodeList,v=e.getTreeScope,g=e.unsafeUnwrap,b=e.wrap,y=document.querySelector,E=document.documentElement.querySelector,S=document.querySelectorAll,T=document.documentElement.querySelectorAll,M=document.getElementsByTagName,_=document.documentElement.getElementsByTagName,L=document.getElementsByTagNameNS,O=document.documentElement.getElementsByTagNameNS,C=window.Element,N=window.HTMLDocument||window.Document,D="http://www.w3.org/1999/xhtml",j={querySelector:function(t){var r=n(t),i=r!==t;t=r;var a,s=g(this),c=v(this).root;if(c instanceof e.wrappers.ShadowRoot)return o(this,t);if(s instanceof C)a=b(E.call(s,t));else{if(!(s instanceof N))return o(this,t);a=b(y.call(s,t))}return a&&!i&&(c=v(a).root)&&c instanceof e.wrappers.ShadowRoot?o(this,t):a},querySelectorAll:function(e){var t=n(e),r=t!==e;e=t;var o=new w;return o.length=p.call(this,i,0,o,e,r),o
+}},H={matches:function(t){return t=r(t),e.originalMatches.call(g(this),t)}},x={getElementsByTagName:function(e){var t=new m,n="*"===e?s:a;return t.length=f.call(this,n,0,t,e,e.toLowerCase()),t},getElementsByClassName:function(e){return this.querySelectorAll("."+e)},getElementsByTagNameNS:function(e,t){var n=new m,r=null;return r="*"===e?"*"===t?s:c:"*"===t?l:u,n.length=h.call(this,r,0,n,e||null,t),n}};e.GetElementsByInterface=x,e.SelectorsInterface=j,e.MatchesInterface=H}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){for(;e&&e.nodeType!==Node.ELEMENT_NODE;)e=e.nextSibling;return e}function n(e){for(;e&&e.nodeType!==Node.ELEMENT_NODE;)e=e.previousSibling;return e}var r=e.wrappers.NodeList,o={get firstElementChild(){return t(this.firstChild)},get lastElementChild(){return n(this.lastChild)},get childElementCount(){for(var e=0,t=this.firstElementChild;t;t=t.nextElementSibling)e++;return e},get children(){for(var e=new r,t=0,n=this.firstElementChild;n;n=n.nextElementSibling)e[t++]=n;return e.length=t,e},remove:function(){var e=this.parentNode;e&&e.removeChild(this)}},i={get nextElementSibling(){return t(this.nextSibling)},get previousElementSibling(){return n(this.previousSibling)}};e.ChildNodeInterface=i,e.ParentNodeInterface=o}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){r.call(this,e)}var n=e.ChildNodeInterface,r=e.wrappers.Node,o=e.enqueueMutation,i=e.mixin,a=e.registerWrapper,s=e.unsafeUnwrap,c=window.CharacterData;t.prototype=Object.create(r.prototype),i(t.prototype,{get textContent(){return this.data},set textContent(e){this.data=e},get data(){return s(this).data},set data(e){var t=s(this).data;o(this,"characterData",{oldValue:t}),s(this).data=e}}),i(t.prototype,n),a(c,t,document.createTextNode("")),e.wrappers.CharacterData=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){return e>>>0}function n(e){r.call(this,e)}var r=e.wrappers.CharacterData,o=(e.enqueueMutation,e.mixin),i=e.registerWrapper,a=window.Text;n.prototype=Object.create(r.prototype),o(n.prototype,{splitText:function(e){e=t(e);var n=this.data;if(e>n.length)throw new Error("IndexSizeError");var r=n.slice(0,e),o=n.slice(e);this.data=r;var i=this.ownerDocument.createTextNode(o);return this.parentNode&&this.parentNode.insertBefore(i,this.nextSibling),i}}),i(a,n,document.createTextNode("")),e.wrappers.Text=n}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){return i(e).getAttribute("class")}function n(e,t){a(e,"attributes",{name:"class",namespace:null,oldValue:t})}function r(t){e.invalidateRendererBasedOnAttribute(t,"class")}function o(e,o,i){var a=e.ownerElement_;if(null==a)return o.apply(e,i);var s=t(a),c=o.apply(e,i);return t(a)!==s&&(n(a,s),r(a)),c}if(!window.DOMTokenList)return void console.warn("Missing DOMTokenList prototype, please include a compatible classList polyfill such as http://goo.gl/uTcepH.");var i=e.unsafeUnwrap,a=e.enqueueMutation,s=DOMTokenList.prototype.add;DOMTokenList.prototype.add=function(){o(this,s,arguments)};var c=DOMTokenList.prototype.remove;DOMTokenList.prototype.remove=function(){o(this,c,arguments)};var l=DOMTokenList.prototype.toggle;DOMTokenList.prototype.toggle=function(){return o(this,l,arguments)}}(window.ShadowDOMPolyfill),function(e){"use strict";function t(t,n){var r=t.parentNode;if(r&&r.shadowRoot){var o=e.getRendererForHost(r);o.dependsOnAttribute(n)&&o.invalidate()}}function n(e,t,n){u(e,"attributes",{name:t,namespace:null,oldValue:n})}function r(e){a.call(this,e)}var o=e.ChildNodeInterface,i=e.GetElementsByInterface,a=e.wrappers.Node,s=e.ParentNodeInterface,c=e.SelectorsInterface,l=e.MatchesInterface,u=(e.addWrapNodeListMethod,e.enqueueMutation),d=e.mixin,p=(e.oneOf,e.registerWrapper),f=e.unsafeUnwrap,h=e.wrappers,m=window.Element,w=["matches","mozMatchesSelector","msMatchesSelector","webkitMatchesSelector"].filter(function(e){return m.prototype[e]}),v=w[0],g=m.prototype[v],b=new WeakMap;r.prototype=Object.create(a.prototype),d(r.prototype,{createShadowRoot:function(){var t=new h.ShadowRoot(this);f(this).polymerShadowRoot_=t;var n=e.getRendererForHost(this);return n.invalidate(),t},get shadowRoot(){return f(this).polymerShadowRoot_||null},setAttribute:function(e,r){var o=f(this).getAttribute(e);f(this).setAttribute(e,r),n(this,e,o),t(this,e)},removeAttribute:function(e){var r=f(this).getAttribute(e);f(this).removeAttribute(e),n(this,e,r),t(this,e)},get classList(){var e=b.get(this);if(!e){if(e=f(this).classList,!e)return;e.ownerElement_=this,b.set(this,e)}return e},get className(){return f(this).className},set className(e){this.setAttribute("class",e)},get id(){return f(this).id},set id(e){this.setAttribute("id",e)}}),w.forEach(function(e){"matches"!==e&&(r.prototype[e]=function(e){return this.matches(e)})}),m.prototype.webkitCreateShadowRoot&&(r.prototype.webkitCreateShadowRoot=r.prototype.createShadowRoot),d(r.prototype,o),d(r.prototype,i),d(r.prototype,s),d(r.prototype,c),d(r.prototype,l),p(m,r,document.createElementNS(null,"x")),e.invalidateRendererBasedOnAttribute=t,e.matchesNames=w,e.originalMatches=g,e.wrappers.Element=r}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){switch(e){case"&":return"&";case"<":return"<";case">":return">";case'"':return""";case" ":return" "}}function n(e){return e.replace(L,t)}function r(e){return e.replace(O,t)}function o(e){for(var t={},n=0;n";case Node.TEXT_NODE:var u=e.data;return t&&N[t.localName]?u:r(u);case Node.COMMENT_NODE:return"";default:throw console.error(e),new Error("not implemented")}}function a(e){e instanceof _.HTMLTemplateElement&&(e=e.content);for(var t="",n=e.firstChild;n;n=n.nextSibling)t+=i(n,e);return t}function s(e,t,n){var r=n||"div";e.textContent="";var o=T(e.ownerDocument.createElement(r));o.innerHTML=t;for(var i;i=o.firstChild;)e.appendChild(M(i))}function c(e){h.call(this,e)}function l(e,t){var n=T(e.cloneNode(!1));n.innerHTML=t;for(var r,o=T(document.createDocumentFragment());r=n.firstChild;)o.appendChild(r);return M(o)}function u(t){return function(){return e.renderAllPending(),S(this)[t]}}function d(e){m(c,e,u(e))}function p(t){Object.defineProperty(c.prototype,t,{get:u(t),set:function(n){e.renderAllPending(),S(this)[t]=n},configurable:!0,enumerable:!0})}function f(t){Object.defineProperty(c.prototype,t,{value:function(){return e.renderAllPending(),S(this)[t].apply(S(this),arguments)},configurable:!0,enumerable:!0})}var h=e.wrappers.Element,m=e.defineGetter,w=e.enqueueMutation,v=e.mixin,g=e.nodesWereAdded,b=e.nodesWereRemoved,y=e.registerWrapper,E=e.snapshotNodeList,S=e.unsafeUnwrap,T=e.unwrap,M=e.wrap,_=e.wrappers,L=/[&\u00A0"]/g,O=/[&\u00A0<>]/g,C=o(["area","base","br","col","command","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"]),N=o(["style","script","xmp","iframe","noembed","noframes","plaintext","noscript"]),D=/MSIE/.test(navigator.userAgent),j=window.HTMLElement,H=window.HTMLTemplateElement;c.prototype=Object.create(h.prototype),v(c.prototype,{get innerHTML(){return a(this)},set innerHTML(e){if(D&&N[this.localName])return void(this.textContent=e);var t=E(this.childNodes);this.invalidateShadowRenderer()?this instanceof _.HTMLTemplateElement?s(this.content,e):s(this,e,this.tagName):!H&&this instanceof _.HTMLTemplateElement?s(this.content,e):S(this).innerHTML=e;var n=E(this.childNodes);w(this,"childList",{addedNodes:n,removedNodes:t}),b(t),g(n,this)},get outerHTML(){return i(this,this.parentNode)},set outerHTML(e){var t=this.parentNode;if(t){t.invalidateShadowRenderer();var n=l(t,e);t.replaceChild(n,this)}},insertAdjacentHTML:function(e,t){var n,r;switch(String(e).toLowerCase()){case"beforebegin":n=this.parentNode,r=this;break;case"afterend":n=this.parentNode,r=this.nextSibling;break;case"afterbegin":n=this,r=this.firstChild;break;case"beforeend":n=this,r=null;break;default:return}var o=l(n,t);n.insertBefore(o,r)},get hidden(){return this.hasAttribute("hidden")},set hidden(e){e?this.setAttribute("hidden",""):this.removeAttribute("hidden")}}),["clientHeight","clientLeft","clientTop","clientWidth","offsetHeight","offsetLeft","offsetTop","offsetWidth","scrollHeight","scrollWidth"].forEach(d),["scrollLeft","scrollTop"].forEach(p),["getBoundingClientRect","getClientRects","scrollIntoView"].forEach(f),y(j,c,document.createElement("b")),e.wrappers.HTMLElement=c,e.getInnerHTML=a,e.setInnerHTML=s}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.unsafeUnwrap,a=e.wrap,s=window.HTMLCanvasElement;t.prototype=Object.create(n.prototype),r(t.prototype,{getContext:function(){var e=i(this).getContext.apply(i(this),arguments);return e&&a(e)}}),o(s,t,document.createElement("canvas")),e.wrappers.HTMLCanvasElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=window.HTMLContentElement;t.prototype=Object.create(n.prototype),r(t.prototype,{constructor:t,get select(){return this.getAttribute("select")},set select(e){this.setAttribute("select",e)},setAttribute:function(e,t){n.prototype.setAttribute.call(this,e,t),"select"===String(e).toLowerCase()&&this.invalidateShadowRenderer(!0)}}),i&&o(i,t),e.wrappers.HTMLContentElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.wrapHTMLCollection,a=e.unwrap,s=window.HTMLFormElement;t.prototype=Object.create(n.prototype),r(t.prototype,{get elements(){return i(a(this).elements)}}),o(s,t,document.createElement("form")),e.wrappers.HTMLFormElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){r.call(this,e)}function n(e,t){if(!(this instanceof n))throw new TypeError("DOM object constructor cannot be called as a function.");var o=i(document.createElement("img"));r.call(this,o),a(o,this),void 0!==e&&(o.width=e),void 0!==t&&(o.height=t)}var r=e.wrappers.HTMLElement,o=e.registerWrapper,i=e.unwrap,a=e.rewrap,s=window.HTMLImageElement;t.prototype=Object.create(r.prototype),o(s,t,document.createElement("img")),n.prototype=t.prototype,e.wrappers.HTMLImageElement=t,e.wrappers.Image=n}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=(e.mixin,e.wrappers.NodeList,e.registerWrapper),o=window.HTMLShadowElement;t.prototype=Object.create(n.prototype),t.prototype.constructor=t,o&&r(o,t),e.wrappers.HTMLShadowElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){if(!e.defaultView)return e;var t=d.get(e);if(!t){for(t=e.implementation.createHTMLDocument("");t.lastChild;)t.removeChild(t.lastChild);d.set(e,t)}return t}function n(e){for(var n,r=t(e.ownerDocument),o=c(r.createDocumentFragment());n=e.firstChild;)o.appendChild(n);return o}function r(e){if(o.call(this,e),!p){var t=n(e);u.set(this,l(t))}}var o=e.wrappers.HTMLElement,i=e.mixin,a=e.registerWrapper,s=e.unsafeUnwrap,c=e.unwrap,l=e.wrap,u=new WeakMap,d=new WeakMap,p=window.HTMLTemplateElement;r.prototype=Object.create(o.prototype),i(r.prototype,{constructor:r,get content(){return p?l(s(this).content):u.get(this)}}),p&&a(p,r),e.wrappers.HTMLTemplateElement=r}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.registerWrapper,o=window.HTMLMediaElement;o&&(t.prototype=Object.create(n.prototype),r(o,t,document.createElement("audio")),e.wrappers.HTMLMediaElement=t)}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){r.call(this,e)}function n(e){if(!(this instanceof n))throw new TypeError("DOM object constructor cannot be called as a function.");var t=i(document.createElement("audio"));r.call(this,t),a(t,this),t.setAttribute("preload","auto"),void 0!==e&&t.setAttribute("src",e)}var r=e.wrappers.HTMLMediaElement,o=e.registerWrapper,i=e.unwrap,a=e.rewrap,s=window.HTMLAudioElement;s&&(t.prototype=Object.create(r.prototype),o(s,t,document.createElement("audio")),n.prototype=t.prototype,e.wrappers.HTMLAudioElement=t,e.wrappers.Audio=n)}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){return e.replace(/\s+/g," ").trim()}function n(e){o.call(this,e)}function r(e,t,n,i){if(!(this instanceof r))throw new TypeError("DOM object constructor cannot be called as a function.");var a=c(document.createElement("option"));o.call(this,a),s(a,this),void 0!==e&&(a.text=e),void 0!==t&&a.setAttribute("value",t),n===!0&&a.setAttribute("selected",""),a.selected=i===!0}var o=e.wrappers.HTMLElement,i=e.mixin,a=e.registerWrapper,s=e.rewrap,c=e.unwrap,l=e.wrap,u=window.HTMLOptionElement;n.prototype=Object.create(o.prototype),i(n.prototype,{get text(){return t(this.textContent)},set text(e){this.textContent=t(String(e))},get form(){return l(c(this).form)}}),a(u,n,document.createElement("option")),r.prototype=n.prototype,e.wrappers.HTMLOptionElement=n,e.wrappers.Option=r}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.unwrap,a=e.wrap,s=window.HTMLSelectElement;t.prototype=Object.create(n.prototype),r(t.prototype,{add:function(e,t){"object"==typeof t&&(t=i(t)),i(this).add(i(e),t)},remove:function(e){return void 0===e?void n.prototype.remove.call(this):("object"==typeof e&&(e=i(e)),void i(this).remove(e))},get form(){return a(i(this).form)}}),o(s,t,document.createElement("select")),e.wrappers.HTMLSelectElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.unwrap,a=e.wrap,s=e.wrapHTMLCollection,c=window.HTMLTableElement;t.prototype=Object.create(n.prototype),r(t.prototype,{get caption(){return a(i(this).caption)},createCaption:function(){return a(i(this).createCaption())},get tHead(){return a(i(this).tHead)},createTHead:function(){return a(i(this).createTHead())},createTFoot:function(){return a(i(this).createTFoot())},get tFoot(){return a(i(this).tFoot)},get tBodies(){return s(i(this).tBodies)},createTBody:function(){return a(i(this).createTBody())},get rows(){return s(i(this).rows)},insertRow:function(e){return a(i(this).insertRow(e))}}),o(c,t,document.createElement("table")),e.wrappers.HTMLTableElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.wrapHTMLCollection,a=e.unwrap,s=e.wrap,c=window.HTMLTableSectionElement;t.prototype=Object.create(n.prototype),r(t.prototype,{constructor:t,get rows(){return i(a(this).rows)},insertRow:function(e){return s(a(this).insertRow(e))}}),o(c,t,document.createElement("thead")),e.wrappers.HTMLTableSectionElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.wrapHTMLCollection,a=e.unwrap,s=e.wrap,c=window.HTMLTableRowElement;t.prototype=Object.create(n.prototype),r(t.prototype,{get cells(){return i(a(this).cells)},insertCell:function(e){return s(a(this).insertCell(e))}}),o(c,t,document.createElement("tr")),e.wrappers.HTMLTableRowElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){switch(e.localName){case"content":return new n(e);case"shadow":return new o(e);case"template":return new i(e)}r.call(this,e)}var n=e.wrappers.HTMLContentElement,r=e.wrappers.HTMLElement,o=e.wrappers.HTMLShadowElement,i=e.wrappers.HTMLTemplateElement,a=(e.mixin,e.registerWrapper),s=window.HTMLUnknownElement;t.prototype=Object.create(r.prototype),a(s,t),e.wrappers.HTMLUnknownElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";var t=e.wrappers.Element,n=e.wrappers.HTMLElement,r=e.registerObject,o=e.defineWrapGetter,i="http://www.w3.org/2000/svg",a=document.createElementNS(i,"title"),s=r(a),c=Object.getPrototypeOf(s.prototype).constructor;if(!("classList"in a)){var l=Object.getOwnPropertyDescriptor(t.prototype,"classList");Object.defineProperty(n.prototype,"classList",l),delete t.prototype.classList}o(c,"ownerSVGElement"),e.wrappers.SVGElement=c}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){p.call(this,e)}var n=e.mixin,r=e.registerWrapper,o=e.unwrap,i=e.wrap,a=window.SVGUseElement,s="http://www.w3.org/2000/svg",c=i(document.createElementNS(s,"g")),l=document.createElementNS(s,"use"),u=c.constructor,d=Object.getPrototypeOf(u.prototype),p=d.constructor;t.prototype=Object.create(d),"instanceRoot"in l&&n(t.prototype,{get instanceRoot(){return i(o(this).instanceRoot)},get animatedInstanceRoot(){return i(o(this).animatedInstanceRoot)}}),r(a,t,l),e.wrappers.SVGUseElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.EventTarget,r=e.mixin,o=e.registerWrapper,i=e.unsafeUnwrap,a=e.wrap,s=window.SVGElementInstance;s&&(t.prototype=Object.create(n.prototype),r(t.prototype,{get correspondingElement(){return a(i(this).correspondingElement)},get correspondingUseElement(){return a(i(this).correspondingUseElement)},get parentNode(){return a(i(this).parentNode)},get childNodes(){throw new Error("Not implemented")},get firstChild(){return a(i(this).firstChild)},get lastChild(){return a(i(this).lastChild)},get previousSibling(){return a(i(this).previousSibling)},get nextSibling(){return a(i(this).nextSibling)}}),o(s,t),e.wrappers.SVGElementInstance=t)}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){o(e,this)}var n=e.mixin,r=e.registerWrapper,o=e.setWrapper,i=e.unsafeUnwrap,a=e.unwrap,s=e.unwrapIfNeeded,c=e.wrap,l=window.CanvasRenderingContext2D;n(t.prototype,{get canvas(){return c(i(this).canvas)},drawImage:function(){arguments[0]=s(arguments[0]),i(this).drawImage.apply(i(this),arguments)},createPattern:function(){return arguments[0]=a(arguments[0]),i(this).createPattern.apply(i(this),arguments)}}),r(l,t,document.createElement("canvas").getContext("2d")),e.wrappers.CanvasRenderingContext2D=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){o(e,this)}var n=e.mixin,r=e.registerWrapper,o=e.setWrapper,i=e.unsafeUnwrap,a=e.unwrapIfNeeded,s=e.wrap,c=window.WebGLRenderingContext;if(c){n(t.prototype,{get canvas(){return s(i(this).canvas)},texImage2D:function(){arguments[5]=a(arguments[5]),i(this).texImage2D.apply(i(this),arguments)},texSubImage2D:function(){arguments[6]=a(arguments[6]),i(this).texSubImage2D.apply(i(this),arguments)}});var l=/WebKit/.test(navigator.userAgent)?{drawingBufferHeight:null,drawingBufferWidth:null}:{};r(c,t,l),e.wrappers.WebGLRenderingContext=t}}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){r(e,this)}var n=e.registerWrapper,r=e.setWrapper,o=e.unsafeUnwrap,i=e.unwrap,a=e.unwrapIfNeeded,s=e.wrap,c=window.Range;t.prototype={get startContainer(){return s(o(this).startContainer)},get endContainer(){return s(o(this).endContainer)},get commonAncestorContainer(){return s(o(this).commonAncestorContainer)},setStart:function(e,t){o(this).setStart(a(e),t)},setEnd:function(e,t){o(this).setEnd(a(e),t)},setStartBefore:function(e){o(this).setStartBefore(a(e))},setStartAfter:function(e){o(this).setStartAfter(a(e))},setEndBefore:function(e){o(this).setEndBefore(a(e))},setEndAfter:function(e){o(this).setEndAfter(a(e))},selectNode:function(e){o(this).selectNode(a(e))},selectNodeContents:function(e){o(this).selectNodeContents(a(e))},compareBoundaryPoints:function(e,t){return o(this).compareBoundaryPoints(e,i(t))},extractContents:function(){return s(o(this).extractContents())},cloneContents:function(){return s(o(this).cloneContents())},insertNode:function(e){o(this).insertNode(a(e))},surroundContents:function(e){o(this).surroundContents(a(e))},cloneRange:function(){return s(o(this).cloneRange())},isPointInRange:function(e,t){return o(this).isPointInRange(a(e),t)},comparePoint:function(e,t){return o(this).comparePoint(a(e),t)},intersectsNode:function(e){return o(this).intersectsNode(a(e))},toString:function(){return o(this).toString()}},c.prototype.createContextualFragment&&(t.prototype.createContextualFragment=function(e){return s(o(this).createContextualFragment(e))}),n(window.Range,t,document.createRange()),e.wrappers.Range=t}(window.ShadowDOMPolyfill),function(e){"use strict";var t=e.GetElementsByInterface,n=e.ParentNodeInterface,r=e.SelectorsInterface,o=e.mixin,i=e.registerObject,a=i(document.createDocumentFragment());o(a.prototype,n),o(a.prototype,r),o(a.prototype,t);var s=i(document.createComment(""));e.wrappers.Comment=s,e.wrappers.DocumentFragment=a}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){var t=d(u(e).ownerDocument.createDocumentFragment());n.call(this,t),c(t,this);var o=e.shadowRoot;f.set(this,o),this.treeScope_=new r(this,a(o||e)),p.set(this,e)}var n=e.wrappers.DocumentFragment,r=e.TreeScope,o=e.elementFromPoint,i=e.getInnerHTML,a=e.getTreeScope,s=e.mixin,c=e.rewrap,l=e.setInnerHTML,u=e.unsafeUnwrap,d=e.unwrap,p=new WeakMap,f=new WeakMap,h=/[ \t\n\r\f]/;t.prototype=Object.create(n.prototype),s(t.prototype,{constructor:t,get innerHTML(){return i(this)},set innerHTML(e){l(this,e),this.invalidateShadowRenderer()},get olderShadowRoot(){return f.get(this)||null},get host(){return p.get(this)||null},invalidateShadowRenderer:function(){return p.get(this).invalidateShadowRenderer()},elementFromPoint:function(e,t){return o(this,this.ownerDocument,e,t)},getElementById:function(e){return h.test(e)?null:this.querySelector('[id="'+e+'"]')}}),e.wrappers.ShadowRoot=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){e.previousSibling_=e.previousSibling,e.nextSibling_=e.nextSibling,e.parentNode_=e.parentNode}function n(n,o,i){var a=x(n),s=x(o),c=i?x(i):null;if(r(o),t(o),i)n.firstChild===i&&(n.firstChild_=i),i.previousSibling_=i.previousSibling;else{n.lastChild_=n.lastChild,n.lastChild===n.firstChild&&(n.firstChild_=n.firstChild);var l=R(a.lastChild);l&&(l.nextSibling_=l.nextSibling)}e.originalInsertBefore.call(a,s,c)}function r(n){var r=x(n),o=r.parentNode;if(o){var i=R(o);t(n),n.previousSibling&&(n.previousSibling.nextSibling_=n),n.nextSibling&&(n.nextSibling.previousSibling_=n),i.lastChild===n&&(i.lastChild_=n),i.firstChild===n&&(i.firstChild_=n),e.originalRemoveChild.call(o,r)}}function o(e){I.set(e,[])}function i(e){var t=I.get(e);return t||I.set(e,t=[]),t}function a(e){for(var t=[],n=0,r=e.firstChild;r;r=r.nextSibling)t[n++]=r;return t}function s(){for(var e=0;em;m++){var w=R(i[u++]);s.get(w)||r(w)}for(var v=f.addedCount,g=i[u]&&R(i[u]),m=0;v>m;m++){var b=o[l++],y=b.node;n(t,y,g),s.set(y,!0),b.sync(s)}d+=v}for(var p=d;p=0;o--){var i=r[o],a=m(i);if(a){var s=i.olderShadowRoot;s&&(n=h(s));for(var c=0;c=0;u--)l=Object.create(l);["createdCallback","attachedCallback","detachedCallback","attributeChangedCallback"].forEach(function(e){var t=o[e];t&&(l[e]=function(){C(this)instanceof r||M(this),t.apply(C(this),arguments)})});var d={prototype:l};i&&(d["extends"]=i),r.prototype=o,r.prototype.constructor=r,e.constructorTable.set(l,r),e.nativePrototypeTable.set(o,l);x.call(O(this),t,d);return r},b([window.HTMLDocument||window.Document],["registerElement"])}b([window.HTMLBodyElement,window.HTMLDocument||window.Document,window.HTMLHeadElement,window.HTMLHtmlElement],["appendChild","compareDocumentPosition","contains","getElementsByClassName","getElementsByTagName","getElementsByTagNameNS","insertBefore","querySelector","querySelectorAll","removeChild","replaceChild"]),b([window.HTMLBodyElement,window.HTMLHeadElement,window.HTMLHtmlElement],y),b([window.HTMLDocument||window.Document],["adoptNode","importNode","contains","createComment","createDocumentFragment","createElement","createElementNS","createEvent","createEventNS","createRange","createTextNode","elementFromPoint","getElementById","getElementsByName","getSelection"]),E(t.prototype,l),E(t.prototype,d),E(t.prototype,f),E(t.prototype,{get implementation(){var e=D.get(this);
+return e?e:(e=new a(O(this).implementation),D.set(this,e),e)},get defaultView(){return C(O(this).defaultView)}}),S(window.Document,t,document.implementation.createHTMLDocument("")),window.HTMLDocument&&S(window.HTMLDocument,t),N([window.HTMLBodyElement,window.HTMLDocument||window.Document,window.HTMLHeadElement]),s(a,"createDocumentType"),s(a,"createDocument"),s(a,"createHTMLDocument"),c(a,"hasFeature"),S(window.DOMImplementation,a),b([window.DOMImplementation],["createDocumentType","createDocument","createHTMLDocument","hasFeature"]),e.adoptNodeNoRemove=r,e.wrappers.DOMImplementation=a,e.wrappers.Document=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.EventTarget,r=e.wrappers.Selection,o=e.mixin,i=e.registerWrapper,a=e.renderAllPending,s=e.unwrap,c=e.unwrapIfNeeded,l=e.wrap,u=window.Window,d=window.getComputedStyle,p=window.getDefaultComputedStyle,f=window.getSelection;t.prototype=Object.create(n.prototype),u.prototype.getComputedStyle=function(e,t){return l(this||window).getComputedStyle(c(e),t)},p&&(u.prototype.getDefaultComputedStyle=function(e,t){return l(this||window).getDefaultComputedStyle(c(e),t)}),u.prototype.getSelection=function(){return l(this||window).getSelection()},delete window.getComputedStyle,delete window.getDefaultComputedStyle,delete window.getSelection,["addEventListener","removeEventListener","dispatchEvent"].forEach(function(e){u.prototype[e]=function(){var t=l(this||window);return t[e].apply(t,arguments)},delete window[e]}),o(t.prototype,{getComputedStyle:function(e,t){return a(),d.call(s(this),c(e),t)},getSelection:function(){return a(),new r(f.call(s(this)))},get document(){return l(s(this).document)}}),p&&(t.prototype.getDefaultComputedStyle=function(e,t){return a(),p.call(s(this),c(e),t)}),i(u,t,window),e.wrappers.Window=t}(window.ShadowDOMPolyfill),function(e){"use strict";var t=e.unwrap,n=window.DataTransfer||window.Clipboard,r=n.prototype.setDragImage;r&&(n.prototype.setDragImage=function(e,n,o){r.call(this,t(e),n,o)})}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){var t;t=e instanceof i?e:new i(e&&o(e)),r(t,this)}var n=e.registerWrapper,r=e.setWrapper,o=e.unwrap,i=window.FormData;i&&(n(i,t,new i),e.wrappers.FormData=t)}(window.ShadowDOMPolyfill),function(e){"use strict";var t=e.unwrapIfNeeded,n=XMLHttpRequest.prototype.send;XMLHttpRequest.prototype.send=function(e){return n.call(this,t(e))}}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){var t=n[e],r=window[t];if(r){var o=document.createElement(e),i=o.constructor;window[t]=i}}var n=(e.isWrapperFor,{a:"HTMLAnchorElement",area:"HTMLAreaElement",audio:"HTMLAudioElement",base:"HTMLBaseElement",body:"HTMLBodyElement",br:"HTMLBRElement",button:"HTMLButtonElement",canvas:"HTMLCanvasElement",caption:"HTMLTableCaptionElement",col:"HTMLTableColElement",content:"HTMLContentElement",data:"HTMLDataElement",datalist:"HTMLDataListElement",del:"HTMLModElement",dir:"HTMLDirectoryElement",div:"HTMLDivElement",dl:"HTMLDListElement",embed:"HTMLEmbedElement",fieldset:"HTMLFieldSetElement",font:"HTMLFontElement",form:"HTMLFormElement",frame:"HTMLFrameElement",frameset:"HTMLFrameSetElement",h1:"HTMLHeadingElement",head:"HTMLHeadElement",hr:"HTMLHRElement",html:"HTMLHtmlElement",iframe:"HTMLIFrameElement",img:"HTMLImageElement",input:"HTMLInputElement",keygen:"HTMLKeygenElement",label:"HTMLLabelElement",legend:"HTMLLegendElement",li:"HTMLLIElement",link:"HTMLLinkElement",map:"HTMLMapElement",marquee:"HTMLMarqueeElement",menu:"HTMLMenuElement",menuitem:"HTMLMenuItemElement",meta:"HTMLMetaElement",meter:"HTMLMeterElement",object:"HTMLObjectElement",ol:"HTMLOListElement",optgroup:"HTMLOptGroupElement",option:"HTMLOptionElement",output:"HTMLOutputElement",p:"HTMLParagraphElement",param:"HTMLParamElement",pre:"HTMLPreElement",progress:"HTMLProgressElement",q:"HTMLQuoteElement",script:"HTMLScriptElement",select:"HTMLSelectElement",shadow:"HTMLShadowElement",source:"HTMLSourceElement",span:"HTMLSpanElement",style:"HTMLStyleElement",table:"HTMLTableElement",tbody:"HTMLTableSectionElement",template:"HTMLTemplateElement",textarea:"HTMLTextAreaElement",thead:"HTMLTableSectionElement",time:"HTMLTimeElement",title:"HTMLTitleElement",tr:"HTMLTableRowElement",track:"HTMLTrackElement",ul:"HTMLUListElement",video:"HTMLVideoElement"});Object.keys(n).forEach(t),Object.getOwnPropertyNames(e.wrappers).forEach(function(t){window[t]=e.wrappers[t]})}(window.ShadowDOMPolyfill),function(e){function t(e,t){var n="";return Array.prototype.forEach.call(e,function(e){n+=e.textContent+"\n\n"}),t||(n=n.replace(d,"")),n}function n(e){var t=document.createElement("style");return t.textContent=e,t}function r(e){var t=n(e);document.head.appendChild(t);var r=[];if(t.sheet)try{r=t.sheet.cssRules}catch(o){}else console.warn("sheet not found",t);return t.parentNode.removeChild(t),r}function o(){N.initialized=!0,document.body.appendChild(N);var e=N.contentDocument,t=e.createElement("base");t.href=document.baseURI,e.head.appendChild(t)}function i(e){N.initialized||o(),document.body.appendChild(N),e(N.contentDocument),document.body.removeChild(N)}function a(e,t){if(t){var o;if(e.match("@import")&&j){var a=n(e);i(function(e){e.head.appendChild(a.impl),o=Array.prototype.slice.call(a.sheet.cssRules,0),t(o)})}else o=r(e),t(o)}}function s(e){e&&l().appendChild(document.createTextNode(e))}function c(e,t){var r=n(e);r.setAttribute(t,""),r.setAttribute(x,""),document.head.appendChild(r)}function l(){return D||(D=document.createElement("style"),D.setAttribute(x,""),D[x]=!0),D}var u={strictStyling:!1,registry:{},shimStyling:function(e,n,r){var o=this.prepareRoot(e,n,r),i=this.isTypeExtension(r),a=this.makeScopeSelector(n,i),s=t(o,!0);s=this.scopeCssText(s,a),e&&(e.shimmedStyle=s),this.addCssToDocument(s,n)},shimStyle:function(e,t){return this.shimCssText(e.textContent,t)},shimCssText:function(e,t){return e=this.insertDirectives(e),this.scopeCssText(e,t)},makeScopeSelector:function(e,t){return e?t?"[is="+e+"]":e:""},isTypeExtension:function(e){return e&&e.indexOf("-")<0},prepareRoot:function(e,t,n){var r=this.registerRoot(e,t,n);return this.replaceTextInStyles(r.rootStyles,this.insertDirectives),this.removeStyles(e,r.rootStyles),this.strictStyling&&this.applyScopeToContent(e,t),r.scopeStyles},removeStyles:function(e,t){for(var n,r=0,o=t.length;o>r&&(n=t[r]);r++)n.parentNode.removeChild(n)},registerRoot:function(e,t,n){var r=this.registry[t]={root:e,name:t,extendsName:n},o=this.findStyles(e);r.rootStyles=o,r.scopeStyles=r.rootStyles;var i=this.registry[r.extendsName];return i&&(r.scopeStyles=i.scopeStyles.concat(r.scopeStyles)),r},findStyles:function(e){if(!e)return[];var t=e.querySelectorAll("style");return Array.prototype.filter.call(t,function(e){return!e.hasAttribute(R)})},applyScopeToContent:function(e,t){e&&(Array.prototype.forEach.call(e.querySelectorAll("*"),function(e){e.setAttribute(t,"")}),Array.prototype.forEach.call(e.querySelectorAll("template"),function(e){this.applyScopeToContent(e.content,t)},this))},insertDirectives:function(e){return e=this.insertPolyfillDirectivesInCssText(e),this.insertPolyfillRulesInCssText(e)},insertPolyfillDirectivesInCssText:function(e){return e=e.replace(p,function(e,t){return t.slice(0,-2)+"{"}),e.replace(f,function(e,t){return t+" {"})},insertPolyfillRulesInCssText:function(e){return e=e.replace(h,function(e,t){return t.slice(0,-1)}),e.replace(m,function(e,t,n,r){var o=e.replace(t,"").replace(n,"");return r+o})},scopeCssText:function(e,t){var n=this.extractUnscopedRulesFromCssText(e);if(e=this.insertPolyfillHostInCssText(e),e=this.convertColonHost(e),e=this.convertColonHostContext(e),e=this.convertShadowDOMSelectors(e),t){var e,r=this;a(e,function(n){e=r.scopeRules(n,t)})}return e=e+"\n"+n,e.trim()},extractUnscopedRulesFromCssText:function(e){for(var t,n="";t=w.exec(e);)n+=t[1].slice(0,-1)+"\n\n";for(;t=v.exec(e);)n+=t[0].replace(t[2],"").replace(t[1],t[3])+"\n\n";return n},convertColonHost:function(e){return this.convertColonRule(e,E,this.colonHostPartReplacer)},convertColonHostContext:function(e){return this.convertColonRule(e,S,this.colonHostContextPartReplacer)},convertColonRule:function(e,t,n){return e.replace(t,function(e,t,r,o){if(t=L,r){for(var i,a=r.split(","),s=[],c=0,l=a.length;l>c&&(i=a[c]);c++)i=i.trim(),s.push(n(t,i,o));return s.join(",")}return t+o})},colonHostContextPartReplacer:function(e,t,n){return t.match(g)?this.colonHostPartReplacer(e,t,n):e+t+n+", "+t+" "+e+n},colonHostPartReplacer:function(e,t,n){return e+t.replace(g,"")+n},convertShadowDOMSelectors:function(e){for(var t=0;t","+","~"],r=e,o="["+t+"]";return n.forEach(function(e){var t=r.split(e);r=t.map(function(e){var t=e.trim().replace(O,"");return t&&n.indexOf(t)<0&&t.indexOf(o)<0&&(e=t.replace(/([^:]*)(:*)(.*)/,"$1"+o+"$2$3")),e}).join(e)}),r},insertPolyfillHostInCssText:function(e){return e.replace(_,b).replace(M,g)},propertiesFromRule:function(e){var t=e.style.cssText;e.style.content&&!e.style.content.match(/['"]+|attr/)&&(t=t.replace(/content:[^;]*;/g,"content: '"+e.style.content+"';"));var n=e.style;for(var r in n)"initial"===n[r]&&(t+=r+": initial; ");return t},replaceTextInStyles:function(e,t){e&&t&&(e instanceof Array||(e=[e]),Array.prototype.forEach.call(e,function(e){e.textContent=t.call(this,e.textContent)},this))},addCssToDocument:function(e,t){e.match("@import")?c(e,t):s(e)}},d=/\/\*[^*]*\*+([^/*][^*]*\*+)*\//gim,p=/\/\*\s*@polyfill ([^*]*\*+([^/*][^*]*\*+)*\/)([^{]*?){/gim,f=/polyfill-next-selector[^}]*content\:[\s]*?['"](.*?)['"][;\s]*}([^{]*?){/gim,h=/\/\*\s@polyfill-rule([^*]*\*+([^/*][^*]*\*+)*)\//gim,m=/(polyfill-rule)[^}]*(content\:[\s]*['"](.*?)['"])[;\s]*[^}]*}/gim,w=/\/\*\s@polyfill-unscoped-rule([^*]*\*+([^/*][^*]*\*+)*)\//gim,v=/(polyfill-unscoped-rule)[^}]*(content\:[\s]*['"](.*?)['"])[;\s]*[^}]*}/gim,g="-shadowcsshost",b="-shadowcsscontext",y=")(?:\\(((?:\\([^)(]*\\)|[^)(]*)+?)\\))?([^,{]*)",E=new RegExp("("+g+y,"gim"),S=new RegExp("("+b+y,"gim"),T="([>\\s~+[.,{:][\\s\\S]*)?$",M=/\:host/gim,_=/\:host-context/gim,L=g+"-no-combinator",O=new RegExp(g,"gim"),C=(new RegExp(b,"gim"),[/\^\^/g,/\^/g,/\/shadow\//g,/\/shadow-deep\//g,/::shadow/g,/\/deep\//g,/::content/g]),N=document.createElement("iframe");N.style.display="none";var D,j=navigator.userAgent.match("Chrome"),H="shim-shadowdom",x="shim-shadowdom-css",R="no-shim";if(window.ShadowDOMPolyfill){s("style { display: none !important; }\n");var P=ShadowDOMPolyfill.wrap(document),I=P.querySelector("head");I.insertBefore(l(),I.childNodes[0]),document.addEventListener("DOMContentLoaded",function(){e.urlResolver;if(window.HTMLImports&&!HTMLImports.useNative){var t="link[rel=stylesheet]["+H+"]",n="style["+H+"]";HTMLImports.importer.documentPreloadSelectors+=","+t,HTMLImports.importer.importsPreloadSelectors+=","+t,HTMLImports.parser.documentSelectors=[HTMLImports.parser.documentSelectors,t,n].join(",");var r=HTMLImports.parser.parseGeneric;HTMLImports.parser.parseGeneric=function(e){if(!e[x]){var t=e.__importElement||e;if(!t.hasAttribute(H))return void r.call(this,e);e.__resource&&(t=e.ownerDocument.createElement("style"),t.textContent=e.__resource),HTMLImports.path.resolveUrlsInStyle(t),t.textContent=u.shimStyle(t),t.removeAttribute(H,""),t.setAttribute(x,""),t[x]=!0,t.parentNode!==I&&(e.parentNode===I?I.replaceChild(t,e):this.addElementToDocument(t)),t.__importParsed=!0,this.markParsingComplete(e),this.parseNext()}};var o=HTMLImports.parser.hasResource;HTMLImports.parser.hasResource=function(e){return"link"===e.localName&&"stylesheet"===e.rel&&e.hasAttribute(H)?e.__resource:o.call(this,e)}}})}e.ShadowCSS=u}(window.WebComponents)),function(){window.ShadowDOMPolyfill?(window.wrap=ShadowDOMPolyfill.wrapIfNeeded,window.unwrap=ShadowDOMPolyfill.unwrapIfNeeded):window.wrap=window.unwrap=function(e){return e}}(window.WebComponents),window.HTMLImports=window.HTMLImports||{flags:{}},function(e){function t(e,t){t=t||h,r(function(){i(e,t)},t)}function n(e){return"complete"===e.readyState||e.readyState===v}function r(e,t){if(n(t))e&&e();else{var o=function(){("complete"===t.readyState||t.readyState===v)&&(t.removeEventListener(g,o),r(e,t))};t.addEventListener(g,o)}}function o(e){e.target.__loaded=!0}function i(e,t){function n(){s==c&&e&&e()}function r(e){o(e),s++,n()}var i=t.querySelectorAll("link[rel=import]"),s=0,c=i.length;if(c)for(var l,u=0;c>u&&(l=i[u]);u++)a(l)?r.call(l,{target:l}):(l.addEventListener("load",r),l.addEventListener("error",r));else n()}function a(e){return d?e.__loaded||e["import"]&&"loading"!==e["import"].readyState:e.__importParsed}function s(e){for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)c(t)&&l(t)}function c(e){return"link"===e.localName&&"import"===e.rel}function l(e){var t=e["import"];t?o({target:e}):(e.addEventListener("load",o),e.addEventListener("error",o))}var u="import",d=Boolean(u in document.createElement("link")),p=Boolean(window.ShadowDOMPolyfill),f=function(e){return p?ShadowDOMPolyfill.wrapIfNeeded(e):e},h=f(document),m={get:function(){var e=HTMLImports.currentScript||document.currentScript||("complete"!==document.readyState?document.scripts[document.scripts.length-1]:null);return f(e)},configurable:!0};Object.defineProperty(document,"_currentScript",m),Object.defineProperty(h,"_currentScript",m);var w=/Trident|Edge/.test(navigator.userAgent),v=w?"complete":"interactive",g="readystatechange";d&&(new MutationObserver(function(e){for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)t.addedNodes&&s(t.addedNodes)}).observe(document.head,{childList:!0}),function(){if("loading"===document.readyState)for(var e,t=document.querySelectorAll("link[rel=import]"),n=0,r=t.length;r>n&&(e=t[n]);n++)l(e)}()),t(function(){HTMLImports.ready=!0,HTMLImports.readyTime=(new Date).getTime();var e=h.createEvent("CustomEvent");e.initCustomEvent("HTMLImportsLoaded",!0,!0,{}),h.dispatchEvent(e)}),e.IMPORT_LINK_TYPE=u,e.useNative=d,e.rootDocument=h,e.whenReady=t,e.isIE=w}(HTMLImports),function(e){var t=[],n=function(e){t.push(e)},r=function(){t.forEach(function(t){t(e)})};e.addModule=n,e.initializeModules=r}(HTMLImports),HTMLImports.addModule(function(e){var t=/(url\()([^)]*)(\))/g,n=/(@import[\s]+(?!url\())([^;]*)(;)/g,r={resolveUrlsInStyle:function(e){var t=e.ownerDocument,n=t.createElement("a");return e.textContent=this.resolveUrlsInCssText(e.textContent,n),e},resolveUrlsInCssText:function(e,r){var o=this.replaceUrls(e,r,t);return o=this.replaceUrls(o,r,n)},replaceUrls:function(e,t,n){return e.replace(n,function(e,n,r,o){var i=r.replace(/["']/g,"");return t.href=i,i=t.href,n+"'"+i+"'"+o})}};e.path=r}),HTMLImports.addModule(function(e){var t={async:!0,ok:function(e){return e.status>=200&&e.status<300||304===e.status||0===e.status},load:function(n,r,o){var i=new XMLHttpRequest;return(e.flags.debug||e.flags.bust)&&(n+="?"+Math.random()),i.open("GET",n,t.async),i.addEventListener("readystatechange",function(){if(4===i.readyState){var e=i.getResponseHeader("Location"),n=null;if(e)var n="/"===e.substr(0,1)?location.origin+e:e;r.call(o,!t.ok(i)&&i,i.response||i.responseText,n)}}),i.send(),i},loadDocument:function(e,t,n){this.load(e,t,n).responseType="document"}};e.xhr=t}),HTMLImports.addModule(function(e){var t=e.xhr,n=e.flags,r=function(e,t){this.cache={},this.onload=e,this.oncomplete=t,this.inflight=0,this.pending={}};r.prototype={addNodes:function(e){this.inflight+=e.length;for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)this.require(t);this.checkDone()},addNode:function(e){this.inflight++,this.require(e),this.checkDone()},require:function(e){var t=e.src||e.href;e.__nodeUrl=t,this.dedupe(t,e)||this.fetch(t,e)},dedupe:function(e,t){if(this.pending[e])return this.pending[e].push(t),!0;return this.cache[e]?(this.onload(e,t,this.cache[e]),this.tail(),!0):(this.pending[e]=[t],!1)},fetch:function(e,r){if(n.load&&console.log("fetch",e,r),e)if(e.match(/^data:/)){var o=e.split(","),i=o[0],a=o[1];a=i.indexOf(";base64")>-1?atob(a):decodeURIComponent(a),setTimeout(function(){this.receive(e,r,null,a)}.bind(this),0)}else{var s=function(t,n,o){this.receive(e,r,t,n,o)}.bind(this);t.load(e,s)}else setTimeout(function(){this.receive(e,r,{error:"href must be specified"},null)}.bind(this),0)},receive:function(e,t,n,r,o){this.cache[e]=r;for(var i,a=this.pending[e],s=0,c=a.length;c>s&&(i=a[s]);s++)this.onload(e,i,r,n,o),this.tail();this.pending[e]=null},tail:function(){--this.inflight,this.checkDone()},checkDone:function(){this.inflight||this.oncomplete()}},e.Loader=r}),HTMLImports.addModule(function(e){var t=function(e){this.addCallback=e,this.mo=new MutationObserver(this.handler.bind(this))};t.prototype={handler:function(e){for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)"childList"===t.type&&t.addedNodes.length&&this.addedNodes(t.addedNodes)},addedNodes:function(e){this.addCallback&&this.addCallback(e);for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)t.children&&t.children.length&&this.addedNodes(t.children)},observe:function(e){this.mo.observe(e,{childList:!0,subtree:!0})}},e.Observer=t}),HTMLImports.addModule(function(e){function t(e){return"link"===e.localName&&e.rel===u}function n(e){var t=r(e);return"data:text/javascript;charset=utf-8,"+encodeURIComponent(t)}function r(e){return e.textContent+o(e)}function o(e){var t=e.ownerDocument;t.__importedScripts=t.__importedScripts||0;var n=e.ownerDocument.baseURI,r=t.__importedScripts?"-"+t.__importedScripts:"";return t.__importedScripts++,"\n//# sourceURL="+n+r+".js\n"}function i(e){var t=e.ownerDocument.createElement("style");return t.textContent=e.textContent,a.resolveUrlsInStyle(t),t}var a=e.path,s=e.rootDocument,c=e.flags,l=e.isIE,u=e.IMPORT_LINK_TYPE,d="link[rel="+u+"]",p={documentSelectors:d,importsSelectors:[d,"link[rel=stylesheet]","style","script:not([type])",'script[type="text/javascript"]'].join(","),map:{link:"parseLink",script:"parseScript",style:"parseStyle"},dynamicElements:[],parseNext:function(){var e=this.nextToParse();e&&this.parse(e)},parse:function(e){if(this.isParsed(e))return void(c.parse&&console.log("[%s] is already parsed",e.localName));var t=this[this.map[e.localName]];t&&(this.markParsing(e),t.call(this,e))},parseDynamic:function(e,t){this.dynamicElements.push(e),t||this.parseNext()},markParsing:function(e){c.parse&&console.log("parsing",e),this.parsingElement=e},markParsingComplete:function(e){e.__importParsed=!0,this.markDynamicParsingComplete(e),e.__importElement&&(e.__importElement.__importParsed=!0,this.markDynamicParsingComplete(e.__importElement)),this.parsingElement=null,c.parse&&console.log("completed",e)},markDynamicParsingComplete:function(e){var t=this.dynamicElements.indexOf(e);t>=0&&this.dynamicElements.splice(t,1)},parseImport:function(e){if(HTMLImports.__importsParsingHook&&HTMLImports.__importsParsingHook(e),e["import"]&&(e["import"].__importParsed=!0),this.markParsingComplete(e),e.dispatchEvent(e.__resource&&!e.__error?new CustomEvent("load",{bubbles:!1}):new CustomEvent("error",{bubbles:!1})),e.__pending)for(var t;e.__pending.length;)t=e.__pending.shift(),t&&t({target:e});this.parseNext()},parseLink:function(e){t(e)?this.parseImport(e):(e.href=e.href,this.parseGeneric(e))},parseStyle:function(e){var t=e;e=i(e),e.__importElement=t,this.parseGeneric(e)},parseGeneric:function(e){this.trackElement(e),this.addElementToDocument(e)},rootImportForElement:function(e){for(var t=e;t.ownerDocument.__importLink;)t=t.ownerDocument.__importLink;return t},addElementToDocument:function(e){var t=this.rootImportForElement(e.__importElement||e);t.parentNode.insertBefore(e,t)},trackElement:function(e,t){var n=this,r=function(r){t&&t(r),n.markParsingComplete(e),n.parseNext()};if(e.addEventListener("load",r),e.addEventListener("error",r),l&&"style"===e.localName){var o=!1;if(-1==e.textContent.indexOf("@import"))o=!0;else if(e.sheet){o=!0;for(var i,a=e.sheet.cssRules,s=a?a.length:0,c=0;s>c&&(i=a[c]);c++)i.type===CSSRule.IMPORT_RULE&&(o=o&&Boolean(i.styleSheet))}o&&e.dispatchEvent(new CustomEvent("load",{bubbles:!1}))}},parseScript:function(t){var r=document.createElement("script");r.__importElement=t,r.src=t.src?t.src:n(t),e.currentScript=t,this.trackElement(r,function(){r.parentNode.removeChild(r),e.currentScript=null}),this.addElementToDocument(r)},nextToParse:function(){return this._mayParse=[],!this.parsingElement&&(this.nextToParseInDoc(s)||this.nextToParseDynamic())},nextToParseInDoc:function(e,n){if(e&&this._mayParse.indexOf(e)<0){this._mayParse.push(e);for(var r,o=e.querySelectorAll(this.parseSelectorsForNode(e)),i=0,a=o.length;a>i&&(r=o[i]);i++)if(!this.isParsed(r))return this.hasResource(r)?t(r)?this.nextToParseInDoc(r["import"],r):r:void 0}return n},nextToParseDynamic:function(){return this.dynamicElements[0]},parseSelectorsForNode:function(e){var t=e.ownerDocument||e;return t===s?this.documentSelectors:this.importsSelectors},isParsed:function(e){return e.__importParsed},needsDynamicParsing:function(e){return this.dynamicElements.indexOf(e)>=0},hasResource:function(e){return t(e)&&void 0===e["import"]?!1:!0}};e.parser=p,e.IMPORT_SELECTOR=d}),HTMLImports.addModule(function(e){function t(e){return n(e,a)}function n(e,t){return"link"===e.localName&&e.getAttribute("rel")===t}function r(e){return!!Object.getOwnPropertyDescriptor(e,"baseURI")}function o(e,t){var n=document.implementation.createHTMLDocument(a);n._URL=t;var o=n.createElement("base");o.setAttribute("href",t),n.baseURI||r(n)||Object.defineProperty(n,"baseURI",{value:t});var i=n.createElement("meta");return i.setAttribute("charset","utf-8"),n.head.appendChild(i),n.head.appendChild(o),n.body.innerHTML=e,window.HTMLTemplateElement&&HTMLTemplateElement.bootstrap&&HTMLTemplateElement.bootstrap(n),n}var i=e.flags,a=e.IMPORT_LINK_TYPE,s=e.IMPORT_SELECTOR,c=e.rootDocument,l=e.Loader,u=e.Observer,d=e.parser,p={documents:{},documentPreloadSelectors:s,importsPreloadSelectors:[s].join(","),loadNode:function(e){f.addNode(e)},loadSubtree:function(e){var t=this.marshalNodes(e);f.addNodes(t)},marshalNodes:function(e){return e.querySelectorAll(this.loadSelectorsForNode(e))},loadSelectorsForNode:function(e){var t=e.ownerDocument||e;return t===c?this.documentPreloadSelectors:this.importsPreloadSelectors},loaded:function(e,n,r,a,s){if(i.load&&console.log("loaded",e,n),n.__resource=r,n.__error=a,t(n)){var c=this.documents[e];void 0===c&&(c=a?null:o(r,s||e),c&&(c.__importLink=n,this.bootDocument(c)),this.documents[e]=c),n["import"]=c}d.parseNext()},bootDocument:function(e){this.loadSubtree(e),this.observer.observe(e),d.parseNext()},loadedAll:function(){d.parseNext()}},f=new l(p.loaded.bind(p),p.loadedAll.bind(p));if(p.observer=new u,!document.baseURI){var h={get:function(){var e=document.querySelector("base");return e?e.href:window.location.href},configurable:!0};Object.defineProperty(document,"baseURI",h),Object.defineProperty(c,"baseURI",h)}e.importer=p,e.importLoader=f}),HTMLImports.addModule(function(e){var t=e.parser,n=e.importer,r={added:function(e){for(var r,o,i,a,s=0,c=e.length;c>s&&(a=e[s]);s++)r||(r=a.ownerDocument,o=t.isParsed(r)),i=this.shouldLoadNode(a),i&&n.loadNode(a),this.shouldParseNode(a)&&o&&t.parseDynamic(a,i)},shouldLoadNode:function(e){return 1===e.nodeType&&o.call(e,n.loadSelectorsForNode(e))},shouldParseNode:function(e){return 1===e.nodeType&&o.call(e,t.parseSelectorsForNode(e))}};n.observer.addCallback=r.added.bind(r);var o=HTMLElement.prototype.matches||HTMLElement.prototype.matchesSelector||HTMLElement.prototype.webkitMatchesSelector||HTMLElement.prototype.mozMatchesSelector||HTMLElement.prototype.msMatchesSelector}),function(e){function t(){HTMLImports.importer.bootDocument(o)}var n=e.initializeModules,r=e.isIE;if(!e.useNative){r&&"function"!=typeof window.CustomEvent&&(window.CustomEvent=function(e,t){t=t||{};var n=document.createEvent("CustomEvent");return n.initCustomEvent(e,Boolean(t.bubbles),Boolean(t.cancelable),t.detail),n},window.CustomEvent.prototype=window.Event.prototype),n();var o=e.rootDocument;"complete"===document.readyState||"interactive"===document.readyState&&!window.attachEvent?t():document.addEventListener("DOMContentLoaded",t)}}(HTMLImports),window.CustomElements=window.CustomElements||{flags:{}},function(e){var t=e.flags,n=[],r=function(e){n.push(e)},o=function(){n.forEach(function(t){t(e)})};e.addModule=r,e.initializeModules=o,e.hasNative=Boolean(document.registerElement),e.useNative=!t.register&&e.hasNative&&!window.ShadowDOMPolyfill&&(!window.HTMLImports||HTMLImports.useNative)}(CustomElements),CustomElements.addModule(function(e){function t(e,t){n(e,function(e){return t(e)?!0:void r(e,t)}),r(e,t)}function n(e,t,r){var o=e.firstElementChild;if(!o)for(o=e.firstChild;o&&o.nodeType!==Node.ELEMENT_NODE;)o=o.nextSibling;for(;o;)t(o,r)!==!0&&n(o,t,r),o=o.nextElementSibling;return null}function r(e,n){for(var r=e.shadowRoot;r;)t(r,n),r=r.olderShadowRoot}function o(e,t){a=[],i(e,t),a=null}function i(e,t){if(e=wrap(e),!(a.indexOf(e)>=0)){a.push(e);for(var n,r=e.querySelectorAll("link[rel="+s+"]"),o=0,c=r.length;c>o&&(n=r[o]);o++)n["import"]&&i(n["import"],t);t(e)}}var a,s=window.HTMLImports?HTMLImports.IMPORT_LINK_TYPE:"none";e.forDocumentTree=o,e.forSubtree=t}),CustomElements.addModule(function(e){function t(e){return n(e)||r(e)}function n(t){return e.upgrade(t)?!0:void s(t)}function r(e){y(e,function(e){return n(e)?!0:void 0})}function o(e){s(e),p(e)&&y(e,function(e){s(e)})}function i(e){M.push(e),T||(T=!0,setTimeout(a))}function a(){T=!1;for(var e,t=M,n=0,r=t.length;r>n&&(e=t[n]);n++)e();M=[]}function s(e){S?i(function(){c(e)}):c(e)}function c(e){e.__upgraded__&&(e.attachedCallback||e.detachedCallback)&&!e.__attached&&p(e)&&(e.__attached=!0,e.attachedCallback&&e.attachedCallback())}function l(e){u(e),y(e,function(e){u(e)})}function u(e){S?i(function(){d(e)}):d(e)}function d(e){e.__upgraded__&&(e.attachedCallback||e.detachedCallback)&&e.__attached&&!p(e)&&(e.__attached=!1,e.detachedCallback&&e.detachedCallback())}function p(e){for(var t=e,n=wrap(document);t;){if(t==n)return!0;t=t.parentNode||t.host}}function f(e){if(e.shadowRoot&&!e.shadowRoot.__watched){b.dom&&console.log("watching shadow-root for: ",e.localName);for(var t=e.shadowRoot;t;)w(t),t=t.olderShadowRoot}}function h(e){if(b.dom){var n=e[0];if(n&&"childList"===n.type&&n.addedNodes&&n.addedNodes){for(var r=n.addedNodes[0];r&&r!==document&&!r.host;)r=r.parentNode;var o=r&&(r.URL||r._URL||r.host&&r.host.localName)||"";o=o.split("/?").shift().split("/").pop()}console.group("mutations (%d) [%s]",e.length,o||"")}e.forEach(function(e){"childList"===e.type&&(_(e.addedNodes,function(e){e.localName&&t(e)}),_(e.removedNodes,function(e){e.localName&&l(e)}))}),b.dom&&console.groupEnd()}function m(e){for(e=wrap(e),e||(e=wrap(document));e.parentNode;)e=e.parentNode;var t=e.__observer;t&&(h(t.takeRecords()),a())}function w(e){if(!e.__observer){var t=new MutationObserver(h);t.observe(e,{childList:!0,subtree:!0}),e.__observer=t}}function v(e){e=wrap(e),b.dom&&console.group("upgradeDocument: ",e.baseURI.split("/").pop()),t(e),w(e),b.dom&&console.groupEnd()}function g(e){E(e,v)}var b=e.flags,y=e.forSubtree,E=e.forDocumentTree,S=!window.MutationObserver||window.MutationObserver===window.JsMutationObserver;e.hasPolyfillMutations=S;var T=!1,M=[],_=Array.prototype.forEach.call.bind(Array.prototype.forEach),L=Element.prototype.createShadowRoot;L&&(Element.prototype.createShadowRoot=function(){var e=L.call(this);return CustomElements.watchShadow(this),e}),e.watchShadow=f,e.upgradeDocumentTree=g,e.upgradeSubtree=r,e.upgradeAll=t,e.attachedNode=o,e.takeRecords=m}),CustomElements.addModule(function(e){function t(t){if(!t.__upgraded__&&t.nodeType===Node.ELEMENT_NODE){var r=t.getAttribute("is"),o=e.getRegisteredDefinition(r||t.localName);if(o){if(r&&o.tag==t.localName)return n(t,o);if(!r&&!o["extends"])return n(t,o)}}}function n(t,n){return a.upgrade&&console.group("upgrade:",t.localName),n.is&&t.setAttribute("is",n.is),r(t,n),t.__upgraded__=!0,i(t),e.attachedNode(t),e.upgradeSubtree(t),a.upgrade&&console.groupEnd(),t}function r(e,t){Object.__proto__?e.__proto__=t.prototype:(o(e,t.prototype,t["native"]),e.__proto__=t.prototype)}function o(e,t,n){for(var r={},o=t;o!==n&&o!==HTMLElement.prototype;){for(var i,a=Object.getOwnPropertyNames(o),s=0;i=a[s];s++)r[i]||(Object.defineProperty(e,i,Object.getOwnPropertyDescriptor(o,i)),r[i]=1);o=Object.getPrototypeOf(o)}}function i(e){e.createdCallback&&e.createdCallback()}var a=e.flags;e.upgrade=t,e.upgradeWithDefinition=n,e.implementPrototype=r}),CustomElements.addModule(function(e){function t(t,r){var c=r||{};if(!t)throw new Error("document.registerElement: first argument `name` must not be empty");if(t.indexOf("-")<0)throw new Error("document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '"+String(t)+"'.");if(o(t))throw new Error("Failed to execute 'registerElement' on 'Document': Registration failed for type '"+String(t)+"'. The type name is invalid.");if(l(t))throw new Error("DuplicateDefinitionError: a type with name '"+String(t)+"' is already registered");return c.prototype||(c.prototype=Object.create(HTMLElement.prototype)),c.__name=t.toLowerCase(),c.lifecycle=c.lifecycle||{},c.ancestry=i(c["extends"]),a(c),s(c),n(c.prototype),u(c.__name,c),c.ctor=d(c),c.ctor.prototype=c.prototype,c.prototype.constructor=c.ctor,e.ready&&w(document),c.ctor}function n(e){if(!e.setAttribute._polyfilled){var t=e.setAttribute;e.setAttribute=function(e,n){r.call(this,e,n,t)};var n=e.removeAttribute;e.removeAttribute=function(e){r.call(this,e,null,n)},e.setAttribute._polyfilled=!0}}function r(e,t,n){e=e.toLowerCase();var r=this.getAttribute(e);n.apply(this,arguments);var o=this.getAttribute(e);this.attributeChangedCallback&&o!==r&&this.attributeChangedCallback(e,r,o)}function o(e){for(var t=0;t=0&&b(r,HTMLElement),r)}function h(e){var t=L.call(this,e);return v(t),t}var m,w=e.upgradeDocumentTree,v=e.upgrade,g=e.upgradeWithDefinition,b=e.implementPrototype,y=e.useNative,E=["annotation-xml","color-profile","font-face","font-face-src","font-face-uri","font-face-format","font-face-name","missing-glyph"],S={},T="http://www.w3.org/1999/xhtml",M=document.createElement.bind(document),_=document.createElementNS.bind(document),L=Node.prototype.cloneNode;m=Object.__proto__||y?function(e,t){return e instanceof t}:function(e,t){for(var n=e;n;){if(n===t.prototype)return!0;n=n.__proto__}return!1},document.registerElement=t,document.createElement=f,document.createElementNS=p,Node.prototype.cloneNode=h,e.registry=S,e["instanceof"]=m,e.reservedTagList=E,e.getRegisteredDefinition=l,document.register=document.registerElement}),function(e){function t(){a(wrap(document)),window.HTMLImports&&(HTMLImports.__importsParsingHook=function(e){a(wrap(e["import"]))}),CustomElements.ready=!0,setTimeout(function(){CustomElements.readyTime=Date.now(),window.HTMLImports&&(CustomElements.elapsed=CustomElements.readyTime-HTMLImports.readyTime),document.dispatchEvent(new CustomEvent("WebComponentsReady",{bubbles:!0}))})}var n=e.useNative,r=e.initializeModules,o=/Trident/.test(navigator.userAgent);if(n){var i=function(){};e.watchShadow=i,e.upgrade=i,e.upgradeAll=i,e.upgradeDocumentTree=i,e.upgradeSubtree=i,e.takeRecords=i,e["instanceof"]=function(e,t){return e instanceof t}}else r();var a=e.upgradeDocumentTree;if(window.wrap||(window.ShadowDOMPolyfill?(window.wrap=ShadowDOMPolyfill.wrapIfNeeded,window.unwrap=ShadowDOMPolyfill.unwrapIfNeeded):window.wrap=window.unwrap=function(e){return e}),o&&"function"!=typeof window.CustomEvent&&(window.CustomEvent=function(e,t){t=t||{};var n=document.createEvent("CustomEvent");return n.initCustomEvent(e,Boolean(t.bubbles),Boolean(t.cancelable),t.detail),n},window.CustomEvent.prototype=window.Event.prototype),"complete"===document.readyState||e.flags.eager)t();else if("interactive"!==document.readyState||window.attachEvent||window.HTMLImports&&!window.HTMLImports.ready){var s=window.HTMLImports&&!HTMLImports.ready?"HTMLImportsLoaded":"DOMContentLoaded";window.addEventListener(s,t)}else t()}(window.CustomElements),function(){Function.prototype.bind||(Function.prototype.bind=function(e){var t=this,n=Array.prototype.slice.call(arguments,1);return function(){var r=n.slice();return r.push.apply(r,arguments),t.apply(e,r)}})}(window.WebComponents),function(e){"use strict";function t(){window.Polymer===o&&(window.Polymer=function(){throw new Error('You tried to use polymer without loading it first. To load polymer, ')})}if(!window.performance){var n=Date.now();window.performance={now:function(){return Date.now()-n}}}window.requestAnimationFrame||(window.requestAnimationFrame=function(){var e=window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame;return e?function(t){return e(function(){t(performance.now())})}:function(e){return window.setTimeout(e,1e3/60)}}()),window.cancelAnimationFrame||(window.cancelAnimationFrame=function(){return window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||function(e){clearTimeout(e)}}());var r=[],o=function(e){"string"!=typeof e&&1===arguments.length&&Array.prototype.push.call(arguments,document._currentScript),r.push(arguments)};window.Polymer=o,e.consumeDeclarations=function(t){e.consumeDeclarations=function(){throw"Possible attempt to load Polymer twice"},t&&t(r),r=null},HTMLImports.useNative?t():addEventListener("DOMContentLoaded",t)}(window.WebComponents),function(){var e=document.createElement("style");e.textContent="body {transition: opacity ease-in 0.2s; } \nbody[unresolved] {opacity: 0; display: block; overflow: hidden; position: relative; } \n";var t=document.querySelector("head");t.insertBefore(e,t.firstChild)}(window.WebComponents),function(e){window.Platform=e}(window.WebComponents);
\ No newline at end of file
diff --git a/example/config.json b/example/config.json
deleted file mode 100644
index c14e920a7..000000000
--- a/example/config.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "excludes": {
-    "imports": ["polymer.html$"]
-  }
-}
diff --git a/example/empty.css b/example/empty.css
deleted file mode 100644
index f296c848f..000000000
--- a/example/empty.css
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * @license
- * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
- * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
- * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
- * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
- * Code distributed by Google as part of the polymer project is also
- * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
- */
-
diff --git a/example/foo.html b/example/foo.html
new file mode 100644
index 000000000..275ce59c7
--- /dev/null
+++ b/example/foo.html
@@ -0,0 +1 @@
+
diff --git a/example/import-test.css b/example/import-test.css
deleted file mode 100644
index 4fcaf8872..000000000
--- a/example/import-test.css
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * @license
- * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
- * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
- * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
- * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
- * Code distributed by Google as part of the polymer project is also
- * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
- */
-
-:host([type="platform"]) { background-color: red; }
-:host([type="core"]) { background-color: red; }
-:host([type="elements"]) { background-color: red; }
-polyfill-next-selector { content: ':host header'; }
-polyfill-next-selector { content: 'I WIN'; }
diff --git a/example/import-test.html b/example/import-test.html
deleted file mode 100644
index 605a9956f..000000000
--- a/example/import-test.html
+++ /dev/null
@@ -1,58 +0,0 @@
-
-
-
-
-  
-  
-  
-
diff --git a/example/index.html b/example/index.html
index b551d2c83..9d31ffe11 100644
--- a/example/index.html
+++ b/example/index.html
@@ -1,33 +1,22 @@
 
-
-
+
 
-  
-  Vulcanizer Test
-  
-  
-  
-  
+  
+  
+  
+  
 
 
-  Hello Import!
-  
-  
-  
-  
-  
-  
-  
+  
+    
+  
   
+  
 
 
diff --git a/example/sub-import/sub-import.html b/example/sub-import/sub-import.html
deleted file mode 100644
index 2297ecc66..000000000
--- a/example/sub-import/sub-import.html
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-  
-  
-
diff --git a/example/sub/import.html b/example/sub/import.html
new file mode 100644
index 000000000..69205e8d5
--- /dev/null
+++ b/example/sub/import.html
@@ -0,0 +1,13 @@
+
+  
+
+
diff --git a/package.json b/package.json
index c611400ac..dd97f40e0 100644
--- a/package.json
+++ b/package.json
@@ -7,9 +7,10 @@
     "vulcanize": "bin/vulcanize"
   },
   "dependencies": {
+    "hydrolysis": "git+ssh://git@github.com/PolymerLabs/hydrolysis.git#vulcanize-demo",
     "nopt": "^3.0.1",
-    "uglify-js": "^2.4.15",
-    "whacko": "0.17.3"
+    "parse5-utils": "git://github.com/PolymerLabs/parse5-utils#query",
+    "parse5": "^1.4.1"
   },
   "devDependencies": {
     "jshint": "^2.5.6",

From 962b0a9f38c90664a276080e41ae5437cec827b5 Mon Sep 17 00:00:00 2001
From: Daniel Freedman 
Date: Wed, 11 Mar 2015 17:11:36 -0700
Subject: [PATCH 0222/1006] use master branch of parse5-utils

---
 bin/demo     | 18 ++++++++++++++----
 package.json |  4 ++--
 2 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/bin/demo b/bin/demo
index 77cba90da..abae9bb49 100755
--- a/bin/demo
+++ b/bin/demo
@@ -17,16 +17,16 @@ function isUniqueImport(importNode) {
 var headFinder = p5u.predicates.hasTagName('head');
 var bodyFinder = p5u.predicates.hasTagName('body');
 var attrs = ['action', 'href', 'src', 'style', 'assetpath'];
-var attrMatcher = p5u.predicates.OR(attrs.map(function(attr) {
+var attrMatcher = p5u.predicates.OR.apply(null, attrs.map(function(attr) {
   return p5u.predicates.hasAttr(attr);
 }));
-var elementMatcher = p5u.predicates.AND([
+var elementMatcher = p5u.predicates.AND(
   p5u.predicates.hasTagName('dom-module'),
   p5u.predicates.hasAttr('id'),
   p5u.predicates.NOT(
     p5u.predicates.hasAttr('assetpath')
   )
-]);
+);
 function reparent(newParent) {
   return function(node) {
     node.parentNode = newParent;
@@ -48,6 +48,16 @@ function relativeTo(from, to) {
   return to;
 }
 
+function remove(node) {
+  var parent = node.parentNode;
+  if (parent) {
+    var idx = parent.childNodes.indexOf(node);
+    if (idx > -1) {
+      parent.childNodes.slice(idx, 1);
+    }
+  }
+}
+
 function flatten(tree) {
   var doc = tree.html.ast;
   var imports = tree.imports;
@@ -59,7 +69,7 @@ function flatten(tree) {
     for (var i = 0, im; i < imports.length; i++) {
       im = imports[i];
       if (!isUniqueImport(im)) {
-        p5u.remove(importNodes[i]);
+        remove(importNodes[i]);
         continue;
       }
       importDoc = flatten(im);
diff --git a/package.json b/package.json
index dd97f40e0..7e8a7cca4 100644
--- a/package.json
+++ b/package.json
@@ -7,9 +7,9 @@
     "vulcanize": "bin/vulcanize"
   },
   "dependencies": {
-    "hydrolysis": "git+ssh://git@github.com/PolymerLabs/hydrolysis.git#vulcanize-demo",
+    "hydrolysis": "git+ssh://git@github.com/PolymerLabs/hydrolysis.git#master",
     "nopt": "^3.0.1",
-    "parse5-utils": "git://github.com/PolymerLabs/parse5-utils#query",
+    "parse5-utils": "git://github.com/PolymerLabs/parse5-utils#master",
     "parse5": "^1.4.1"
   },
   "devDependencies": {

From 2884cf27d5072a8a6c548cd4f0eeb80208c8e562 Mon Sep 17 00:00:00 2001
From: Daniel Freedman 
Date: Thu, 12 Mar 2015 11:20:35 -0700
Subject: [PATCH 0223/1006] fix demo import removal

---
 bin/demo                                      |    2 +-
 example/bower_components/polymer/.bower.json  |    7 +-
 example/bower_components/polymer/PRIMER.md    |   20 +-
 .../polymer/src/expr/style-auditor.html       |  122 +
 .../polymer/src/expr/x-styling.html           |   18 +-
 .../src/features/standard/styling.html        |   86 +-
 example/build.html                            | 5232 +++++++++++++++++
 example/sub/cat.jpg                           |  Bin 0 -> 20757 bytes
 example/sub/import.html                       |    6 +-
 9 files changed, 5433 insertions(+), 60 deletions(-)
 create mode 100644 example/bower_components/polymer/src/expr/style-auditor.html
 create mode 100644 example/build.html
 create mode 100644 example/sub/cat.jpg

diff --git a/bin/demo b/bin/demo
index abae9bb49..b7b02cc21 100755
--- a/bin/demo
+++ b/bin/demo
@@ -53,7 +53,7 @@ function remove(node) {
   if (parent) {
     var idx = parent.childNodes.indexOf(node);
     if (idx > -1) {
-      parent.childNodes.slice(idx, 1);
+      parent.childNodes.splice(idx, 1);
     }
   }
 }
diff --git a/example/bower_components/polymer/.bower.json b/example/bower_components/polymer/.bower.json
index f82219d89..b8897a65b 100644
--- a/example/bower_components/polymer/.bower.json
+++ b/example/bower_components/polymer/.bower.json
@@ -21,14 +21,13 @@
   },
   "private": true,
   "homepage": "https://github.com/Polymer/polymer",
-  "_release": "860ce4cc9a",
+  "_release": "83b809def6",
   "_resolution": {
     "type": "branch",
     "branch": "0.8-preview",
-    "commit": "860ce4cc9aebe8bc69018ae3a0dacd20258a11bc"
+    "commit": "83b809def627c84dc66b5136ea8dcddaa110a661"
   },
   "_source": "git://github.com/Polymer/polymer.git",
   "_target": "0.8-preview",
-  "_originalSource": "Polymer/polymer",
-  "_direct": true
+  "_originalSource": "Polymer/polymer"
 }
\ No newline at end of file
diff --git a/example/bower_components/polymer/PRIMER.md b/example/bower_components/polymer/PRIMER.md
index 31b20c89f..364b2217d 100644
--- a/example/bower_components/polymer/PRIMER.md
+++ b/example/bower_components/polymer/PRIMER.md
@@ -408,7 +408,7 @@ Example:
 
 ## DOM API
 
-Polymer provides custom API for manipulating dom such that local DOM and light DOM trees are properly maintained.
+Polymer provides custom API for manipulating DOM such that local DOM and light DOM trees are properly maintained.
 
 **
Note: All DOM manipulation must use this API, as opposed to DOM API directly on nodes.
** @@ -425,7 +425,9 @@ The following methods are provided: * `Polymer.dom(node).getDestinationInsertionPoints()` * `Polymer.dom.flush()` - The insert, append, and remove operations are trasnacted lazily in certain cases for performance. In order to interrogate the dom (e.g. `offsetHeight`, `getComputedStyle`, etc.) immediately after one of these operations, call `Polymer.dom.flush()` first. -Calling `append`/`insertBefore` where parent is a custom Polymer element adds the node to the light DOM of the element. In order to insert/append into the shadow root of a custom element, use `this.root` as the parent. +Calling `append`/`insertBefore` where `parent` is a custom Polymer element adds the node to the light DOM of the element. In order to insert/append into the shadow root of a custom element, use `this.root` as the parent. + +`Polymer.dom` properties and methods that return a list of nodes return an `Array`, not a `NodeList` like the standard DOM equivalent. Example: @@ -440,7 +442,7 @@ Polymer.dom(this.root).insertBefore(toLocal, beforeNode); var allSpans = Polymer.dom(this).querySelectorAll('span'); ``` -For manipulating dom in elements that themselves do not have local dom, the above api's support an extra argument which is the container `node` in which the operation should be performed. +You can use `Polymer.dom` on any node, whether or not it has a local DOM tree: Example: @@ -1199,15 +1201,21 @@ Polymer 0.8 uses "[Shadow DOM styling rules](http://www.html5rocks.com/en/tutori }); - ``` -Note: Remote stylesheets (``) are not currently supported for providing scoped styles. This may be added in future versions. See below for workarounds. +Loading remote stylesheets is also supported. The syntax is slightly different from how stylesheets are typically loaded. This is typically convenient for developers who like to separate styles or use style pre-processing tools. + +```html + + + + +``` ### Sharing stylesheets -Styles can be shared between elements by defining ``'s containing styles to be shared, and referencing shared styles to be included in a given element by listing the `dom-module` id in an array of `styleModules`. +In addition to using remote stylesheets as described above, styles can be shared between elements by defining ``'s containing styles to be shared, and referencing shared styles to be included in a given element by listing the `dom-module` id in an array of `styleModules`. Example: diff --git a/example/bower_components/polymer/src/expr/style-auditor.html b/example/bower_components/polymer/src/expr/style-auditor.html new file mode 100644 index 000000000..d12f49164 --- /dev/null +++ b/example/bower_components/polymer/src/expr/style-auditor.html @@ -0,0 +1,122 @@ + diff --git a/example/bower_components/polymer/src/expr/x-styling.html b/example/bower_components/polymer/src/expr/x-styling.html index 8ec72e092..47c797c2e 100644 --- a/example/bower_components/polymer/src/expr/x-styling.html +++ b/example/bower_components/polymer/src/expr/x-styling.html @@ -21,7 +21,14 @@ // compute style properties top-down so that values can be inherited // easily from host. _beforeConfigure: function() { - this._updateOwnStyles(); + if (this.enableStyleCustomProperties) { + this._updateOwnStyles(); + } + }, + + _updateOwnStyles: function() { + this._styleProperties = this._computeStyleProperties(); + this.applyStyleProperties(this._styleProperties); }, _computeStyleProperties: function() { @@ -36,6 +43,10 @@ // TODO(sorvell): experimental feature, global defaults! var props = {}, styles = [Polymer.StyleDefaults.defaultSheet]; if (this.host) { + // enable finding styles in hosts without `enableStyleCustomProperties` + if (!this.host._styleProperties) { + this.host._styleProperties = this.host._computeStyleProperties(); + } props = Object.create(this.host._styleProperties); styles = this.host._styles; } @@ -225,11 +236,6 @@ for (var i=0, l= c$.length, c; (i diff --git a/example/build.html b/example/build.html new file mode 100644 index 000000000..51c62f3cb --- /dev/null +++ b/example/build.html @@ -0,0 +1,5232 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/sub/cat.jpg b/example/sub/cat.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d173ff5a77bba68192f7e44ef5bb91362066f537 GIT binary patch literal 20757 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 J`{%z#{|QREAZ`Ev literal 0 HcmV?d00001 diff --git a/example/sub/import.html b/example/sub/import.html index 69205e8d5..04169a0ad 100644 --- a/example/sub/import.html +++ b/example/sub/import.html @@ -1,9 +1,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/example/sub/foo.html b/example/sub/foo.html new file mode 100644 index 000000000..4f59d8769 --- /dev/null +++ b/example/sub/foo.html @@ -0,0 +1 @@ +
Yay!
diff --git a/example/sub/import.html b/example/sub/import.html index 04169a0ad..e64e7fff6 100644 --- a/example/sub/import.html +++ b/example/sub/import.html @@ -2,6 +2,7 @@ From eb88c070bee06aa7c26d801db08fbcf30379387e Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Fri, 13 Mar 2015 11:19:40 -0700 Subject: [PATCH 0225/1006] parse5-utils -> dom5 --- bin/demo | 38 +++++++++++++++++++------------------- package.json | 2 +- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/bin/demo b/bin/demo index b7b02cc21..9f1ac5003 100755 --- a/bin/demo +++ b/bin/demo @@ -6,7 +6,7 @@ var path = require('path'); var url = require('url'); var hyd = require('hydrolysis'); -var p5u = require('parse5-utils/parse5-utils.js'); +var dom5 = require('dom5'); var loader = new hyd.loader(); loader.addResolver(new hyd.fsResolver({})); @@ -14,17 +14,17 @@ function isUniqueImport(importNode) { return Boolean(importNode.url); } -var headFinder = p5u.predicates.hasTagName('head'); -var bodyFinder = p5u.predicates.hasTagName('body'); +var headFinder = dom5.predicates.hasTagName('head'); +var bodyFinder = dom5.predicates.hasTagName('body'); var attrs = ['action', 'href', 'src', 'style', 'assetpath']; -var attrMatcher = p5u.predicates.OR.apply(null, attrs.map(function(attr) { - return p5u.predicates.hasAttr(attr); +var attrMatcher = dom5.predicates.OR.apply(null, attrs.map(function(attr) { + return dom5.predicates.hasAttr(attr); })); -var elementMatcher = p5u.predicates.AND( - p5u.predicates.hasTagName('dom-module'), - p5u.predicates.hasAttr('id'), - p5u.predicates.NOT( - p5u.predicates.hasAttr('assetpath') +var elementMatcher = dom5.predicates.AND( + dom5.predicates.hasTagName('dom-module'), + dom5.predicates.hasAttr('id'), + dom5.predicates.NOT( + dom5.predicates.hasAttr('assetpath') ) ); function reparent(newParent) { @@ -61,8 +61,8 @@ function remove(node) { function flatten(tree) { var doc = tree.html.ast; var imports = tree.imports; - var head = p5u.query(doc, headFinder); - var body = p5u.query(doc, bodyFinder); + var head = dom5.query(doc, headFinder); + var body = dom5.query(doc, bodyFinder); var importNodes = tree.html.import; var importDoc, importHead, importBody, importHeadChildren, importBodyChildren; if (imports) { @@ -73,26 +73,26 @@ function flatten(tree) { continue; } importDoc = flatten(im); - importHead = p5u.query(importDoc, headFinder); - importBody = p5u.query(importDoc, bodyFinder); + importHead = dom5.query(importDoc, headFinder); + importBody = dom5.query(importDoc, bodyFinder); // rewrite urls - p5u.queryAll(importDoc, attrMatcher).forEach(function(node) { + dom5.queryAll(importDoc, attrMatcher).forEach(function(node) { attrs.forEach(function(attr) { - var attrValue = p5u.getAttribute(node, attr); + var attrValue = dom5.getAttribute(node, attr); if (attrValue) { var absUrl = url.resolve(im.url, attrValue); var relUrl = relativeTo(tree.url, absUrl); if (attr === 'assetpath') { relUrl += '/'; } - p5u.setAttribute(node, attr, relUrl); + dom5.setAttribute(node, attr, relUrl); } }); }); - p5u.queryAll(importDoc, elementMatcher).forEach(function(el) { + dom5.queryAll(importDoc, elementMatcher).forEach(function(el) { var rel = relativeTo(tree.url, im.url); rel = path.dirname(rel) + '/'; - p5u.setAttribute(el, 'assetpath', rel); + dom5.setAttribute(el, 'assetpath', rel); }); // merge head and body tags for imports into main document importHeadChildren = importHead.childNodes; diff --git a/package.json b/package.json index 7e8a7cca4..b215c9747 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "dependencies": { "hydrolysis": "git+ssh://git@github.com/PolymerLabs/hydrolysis.git#master", "nopt": "^3.0.1", - "parse5-utils": "git://github.com/PolymerLabs/parse5-utils#master", + "dom5": "git://github.com/PolymerLabs/dom5.git#master", "parse5": "^1.4.1" }, "devDependencies": { From 483e7805edf8c6a9aa0052a67141828f58a3c9ea Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Mon, 16 Mar 2015 14:35:35 -0700 Subject: [PATCH 0226/1006] Fewer allocations for head merging Delete changelogs.sh --- bin/demo | 2 +- util/changelogs.sh | 23 ----------------------- 2 files changed, 1 insertion(+), 24 deletions(-) delete mode 100755 util/changelogs.sh diff --git a/bin/demo b/bin/demo index 9f1ac5003..dd522b780 100755 --- a/bin/demo +++ b/bin/demo @@ -101,7 +101,7 @@ function flatten(tree) { importBodyChildren.forEach(reparent(body)); // replace import node with importHeadChildren var idx = head.childNodes.indexOf(importNodes[i]); - head.childNodes = [].concat(head.childNodes.slice(0, idx), importHeadChildren, head.childNodes.slice(idx + 1)); + head.childNodes = head.childNodes.slice(0, idx).concat(importHeadChildren, head.childNodes.slice(idx + 1)); // prepend import body to document body body.childNodes = importBodyChildren.concat(body.childNodes); } diff --git a/util/changelogs.sh b/util/changelogs.sh deleted file mode 100755 index 987678aab..000000000 --- a/util/changelogs.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -# -# @license -# Copyright (c) 2014 The Polymer Project Authors. All rights reserved. -# This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt -# The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt -# The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt -# Code distributed by Google as part of the polymer project is also -# subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt -# - -# tags sorted semver style -TAGS=($(git tag -l | sort -k1,1r -k2,2r -k3,3r -t.)) - -TO=(${TAGS[@]}) - -FROM=(${TAGS[@]:1}) -FROM+=(`git rev-list --max-parents=0 HEAD`) - -for i in ${!FROM[@]}; do - echo "### ${TO[$i]}" - git log ${FROM[$i]}..${TO[$i]} --pretty="- %s" -done From 0524adc16985e050b87c6487b3acce74563d51df Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Mon, 16 Mar 2015 14:37:59 -0700 Subject: [PATCH 0227/1006] Test iojs and node 0.12 Turn off tests for hydro-demo branch for now --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.travis.yml b/.travis.yml index 6e5919de3..319c5e786 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,8 @@ language: node_js node_js: - "0.10" + - "0.12" + - "iojs" +branches: + except: + - hydro-demo From a2838314c3de4c43acb1981b55c82b24e4ed68b6 Mon Sep 17 00:00:00 2001 From: Trevor Dixon Date: Mon, 16 Mar 2015 22:50:04 -0700 Subject: [PATCH 0228/1006] Don't strip white space; rather collapse to a single space. --- lib/vulcan.js | 14 +++++++++----- test/test.js | 10 +++++++++- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/lib/vulcan.js b/lib/vulcan.js index 3d322c292..128861ede 100644 --- a/lib/vulcan.js +++ b/lib/vulcan.js @@ -175,7 +175,7 @@ function findScriptLocation($) { return pos; } -function isCommentOrEmptyTextNode(node) { +function isComment(node) { var d = node.data; if (node.type === 'comment') { var keep = (/@license/.test(d)); @@ -183,9 +183,6 @@ function isCommentOrEmptyTextNode(node) { comments.set(d); } return !keep; - } else if (node.type === 'text') { - // return true if the node is only whitespace - return !((/\S/).test(d)); } } @@ -228,9 +225,16 @@ function removeCommentsAndWhitespace($) { var content, c; if (!node) { return; - } else if (isCommentOrEmptyTextNode(node)) { + } else if (isComment(node)) { $(node).remove(); return true; + } else if (node.type == 'text') { + var parent = node.parent; + // collapse whitespace unless it's inside a pre or textarea tag + if (['pre', 'textarea'].indexOf(parent.name) === -1) { + // define whitespace characters explicitly; \s is too aggressive + node.data = node.data.replace(/[ \r\n\t]+/g, ' '); + } } else if (node.type == 'script') { // only run uglify on inline javascript scripts if (!node.attribs.src && (!node.attribs.type || node.attribs.type == "text/javascript")) { diff --git a/test/test.js b/test/test.js index b29311d4b..c9027fec8 100644 --- a/test/test.js +++ b/test/test.js @@ -575,9 +575,17 @@ suite('Vulcan', function() { }); }); + test('whitespace', function(done) { + process({inputSrc: '
\n
\n hi  \n
\n
', output: outputPath, strip: true}, function(outputs) { + var vulcanized = outputs[outputPath]; + assert.equal(vulcanized, '
hi  
'); + done(); + }); + }); + suite('css', function() { - test('precsision', function(done) { + test('precision', function(done) { process({inputSrc: '', output: outputPath, strip: true}, function(outputs) { var vulcanized = outputs[outputPath]; assert(vulcanized); From f1b3e6b2f025ef47ca16551c1baedb3492be0115 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Tue, 17 Mar 2015 16:55:34 -0700 Subject: [PATCH 0229/1006] Break out matchers into lib/matchers.js Rewrite urls in style elements --- bin/demo | 68 ++++++--------------- lib/constants.js | 16 +---- lib/matchers.js | 68 +++++++++++++++++++++ lib/pathresolver.js | 142 +++++++++++++++++++------------------------- lib/utils.js | 61 ------------------- 5 files changed, 147 insertions(+), 208 deletions(-) create mode 100644 lib/matchers.js delete mode 100644 lib/utils.js diff --git a/bin/demo b/bin/demo index dd522b780..9b055f03a 100755 --- a/bin/demo +++ b/bin/demo @@ -1,4 +1,13 @@ #!/usr/bin/env node +/** + * @license + * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. + * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt + * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt + * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt + * Code distributed by Google as part of the polymer project is also + * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt + */ // jshint node: true 'use strict'; @@ -7,6 +16,10 @@ var path = require('path'); var url = require('url'); var hyd = require('hydrolysis'); var dom5 = require('dom5'); +var constants = require('../lib/constants.js'); +var matchers = require('../lib/matchers.js'); +var pathResolver = require('../lib/pathresolver.js'); + var loader = new hyd.loader(); loader.addResolver(new hyd.fsResolver({})); @@ -14,40 +27,12 @@ function isUniqueImport(importNode) { return Boolean(importNode.url); } -var headFinder = dom5.predicates.hasTagName('head'); -var bodyFinder = dom5.predicates.hasTagName('body'); -var attrs = ['action', 'href', 'src', 'style', 'assetpath']; -var attrMatcher = dom5.predicates.OR.apply(null, attrs.map(function(attr) { - return dom5.predicates.hasAttr(attr); -})); -var elementMatcher = dom5.predicates.AND( - dom5.predicates.hasTagName('dom-module'), - dom5.predicates.hasAttr('id'), - dom5.predicates.NOT( - dom5.predicates.hasAttr('assetpath') - ) -); function reparent(newParent) { return function(node) { node.parentNode = newParent; }; } -// make two absolute urls relative to each other -function relativeTo(from, to) { - var parsedFrom = url.parse(from); - var parsedTo = url.parse(to); - if (parsedFrom.protocol === parsedTo.protocol && parsedFrom.host === parsedTo.host) { - var pathname = path.relative(path.dirname(parsedFrom.pathname), parsedTo.pathname); - return url.format({ - pathname: pathname, - search: parsedTo.search, - hash: parsedTo.hash - }); - } - return to; -} - function remove(node) { var parent = node.parentNode; if (parent) { @@ -61,8 +46,8 @@ function remove(node) { function flatten(tree) { var doc = tree.html.ast; var imports = tree.imports; - var head = dom5.query(doc, headFinder); - var body = dom5.query(doc, bodyFinder); + var head = dom5.query(doc, matchers.head); + var body = dom5.query(doc, matchers.body); var importNodes = tree.html.import; var importDoc, importHead, importBody, importHeadChildren, importBodyChildren; if (imports) { @@ -73,27 +58,10 @@ function flatten(tree) { continue; } importDoc = flatten(im); - importHead = dom5.query(importDoc, headFinder); - importBody = dom5.query(importDoc, bodyFinder); + importHead = dom5.query(importDoc, matchers.head); + importBody = dom5.query(importDoc, matchers.body); // rewrite urls - dom5.queryAll(importDoc, attrMatcher).forEach(function(node) { - attrs.forEach(function(attr) { - var attrValue = dom5.getAttribute(node, attr); - if (attrValue) { - var absUrl = url.resolve(im.url, attrValue); - var relUrl = relativeTo(tree.url, absUrl); - if (attr === 'assetpath') { - relUrl += '/'; - } - dom5.setAttribute(node, attr, relUrl); - } - }); - }); - dom5.queryAll(importDoc, elementMatcher).forEach(function(el) { - var rel = relativeTo(tree.url, im.url); - rel = path.dirname(rel) + '/'; - dom5.setAttribute(el, 'assetpath', rel); - }); + pathResolver.resolvePaths(importDoc, im.url, tree.url); // merge head and body tags for imports into main document importHeadChildren = importHead.childNodes; importBodyChildren = importBody.childNodes; diff --git a/lib/constants.js b/lib/constants.js index f7cdeaa55..06608a41d 100644 --- a/lib/constants.js +++ b/lib/constants.js @@ -8,24 +8,10 @@ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt */ -var JS = 'script:not([type]), script[type="text/javascript"]'; -var URL_ATTR = ['href', 'src', 'action', 'style']; +var URL_ATTR = ['href', 'src', 'action', 'style', 'assetpath']; module.exports = { - EOL: require('os').EOL, - ELEMENTS: 'dom-module:not([assetpath])', - ELEMENTS_NOSCRIPT: 'polymer-element[noscript]', - ABS_URL: /(^\/)|(^#)|(^[\w-\d]*:)/, - REMOTE_ABS_URL: /(^http[s]?:)|(^\/\/)/, - IMPORTS: 'link[rel="import"][href]', URL: /url\([^)]*\)/g, URL_ATTR: URL_ATTR, - URL_ATTR_SEL: '[' + URL_ATTR.join('],[') + ']', URL_TEMPLATE: '{{.*}}|\\[\\[.*\\]\\]', - JS: JS, - JS_SRC: JS.split(',').map(function(s){ return s + '[src]'; }).join(','), - JS_INLINE: JS.split(',').map(function(s) { return s + ':not([src])'; }).join(','), - CSS: 'style:not([type]), style[type="text/css"]', - // Output match is [ 'Polymer(', NAME_OF_ELEMENT OR undefined, ',', { or ) ] - POLYMER_INVOCATION: /Polymer\(([^,{]+)?(,\s*)?({|\))/ }; diff --git a/lib/matchers.js b/lib/matchers.js new file mode 100644 index 000000000..317322bfe --- /dev/null +++ b/lib/matchers.js @@ -0,0 +1,68 @@ +/** + * @license + * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. + * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt + * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt + * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt + * Code distributed by Google as part of the polymer project is also + * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt + */ + +// jshint node: true +'use strict'; + +var constants = require('./constants.js'); +var p = require('dom5').predicates; + +var urlAttrMatchers = constants.URL_ATTR.map(function(attr) { + return p.hasAttr(attr); +}); + +var urlAttrs = p.OR.apply(null, urlAttrMatchers); + +var jsMatcher = p.AND( + p.hasTagName('script'), + p.OR( + p.NOT( + p.hasAttr('type') + ), + p.hasAttrValue('type', 'text/javascript') + ) +); + +var styleMatcher = p.AND( + p.hasTagName('style'), + p.OR( + p.NOT( + p.hasAttr('type') + ), + p.hasAttrValue('type', 'text/css') + ) +); + +module.exports = { + head: p.hasTagName('head'), + body: p.hasTagName('body'), + domModule: p.AND( + p.hasTagName('dom-module'), + p.hasAttr('id'), + p.NOT( + p.hasAttr('assetpath') + ) + ), + urlAttrs: urlAttrs, + JS: jsMatcher, + CSS: styleMatcher, + JS_SRC: p.AND(p.hasAttr('src'), jsMatcher), + JS_INLINE: p.AND(p.NOT(p.hasAttr('src')), jsMatcher), + commentOrEmptyText: function(node) { + if (node.nodeName === '#text') { + return !/\S/.test(node.value); + } + if (node.nodeName === '#comment') { + return true; + } + return false; + } + +}; diff --git a/lib/pathresolver.js b/lib/pathresolver.js index a7d140bcf..41c0317c5 100644 --- a/lib/pathresolver.js +++ b/lib/pathresolver.js @@ -9,104 +9,82 @@ */ // jshint node:true +'use strict'; + var path = require('path'); var url = require('url'); +var dom5 = require('dom5'); +var matchers = require('./matchers.js'); var constants = require('./constants.js'); -var utils = require('./utils.js'); - -var setTextContent = utils.setTextContent; -var getTextContent = utils.getTextContent; -var searchAll = utils.searchAll; -function resolvePaths($, input, output, abspath) { - // honor tag - var baseEl = $('base'); - var baseUrl = ""; - - if (baseEl.length) { - var baseHref = baseEl.attr('href'); - if (baseHref) { - baseUrl = baseHref + '/'; - } - baseEl.remove(); - } - - var assetPath; - if (abspath) { - assetPath = rebasePath(input, abspath); - } else { - assetPath = path.relative(output, input); - } - - // make sure assetpath is a folder, but not root! - if (assetPath) { - assetPath = utils.unixPath(assetPath) + '/'; - } - - if (baseUrl) { - // assetPath is backwards; the URL resolution is assetPath + baseUrl + input - assetPath = url.resolve(assetPath, baseUrl); - } - - // resolve attributes - searchAll($, constants.URL_ATTR_SEL).each(function() { - var el = $(this); - constants.URL_ATTR.forEach(function(a) { - var val = el.attr(a); - if (val) { - if (val.search(constants.URL_TEMPLATE) < 0) { - if (a === 'style') { - el.attr(a, rewriteURL(input, output, val, abspath, baseUrl)); - } else { - el.attr(a, rewriteRelPath(input, output, val, abspath, baseUrl)); +function resolvePaths(importDoc, importUrl, mainDocUrl) { + // rewrite URLs in element attributes + var nodes = dom5.queryAll(importDoc, matchers.urlAttrs); + var attrValue; + for (var i = 0, node; i < nodes.length; i++) { + node = nodes[i]; + for (var j = 0, attr; j < constants.URL_ATTR.length; j++) { + attr = constants.URL_ATTR[j]; + attrValue = dom5.getAttribute(node, attr); + if (attrValue && attrValue.search(constants.URL_TEMPLATE) < 0) { + var relUrl; + if (attr !== 'style') { + relUrl = rewriteRelPath(importUrl, mainDocUrl, attrValue); + if (attr === 'assetpath') { + relUrl += '/'; } + } else { + relUrl = rewriteURL(importUrl, mainDocUrl, attrValue); } + dom5.setAttribute(node, attr, relUrl); } - }); - }); - searchAll($, constants.CSS).each(function() { - var el = $(this); - var text = getTextContent(el); - if (baseUrl) { - // baseHref should be added to input path - input = url.resolve(input + '/', baseHref); } - text = rewriteURL(input, output, text, abspath); - setTextContent(el, text); - }); - searchAll($, constants.ELEMENTS).each(function() { - $(this).attr('assetpath', assetPath); - }); -} - -function rebasePath(absolutePath, baselinePath) { - var absBase = new RegExp('^' + utils.escapeForRegExp(baselinePath)); - return absolutePath.replace(absBase, ''); -} - -function rewriteRelPath(inputPath, outputPath, rel, abspath, baseUrl) { - if (constants.ABS_URL.test(rel)) { - return rel; } - - if (baseUrl) { - rel = url.resolve(baseUrl, rel); + // rewrite URLs in stylesheets + var styleNodes = dom5.queryAll(importDoc, matchers.CSS); + for (i = 0, node; i < styleNodes.length; i++) { + node = styleNodes[i]; + var styleText = ''; + if (!node.childNodes.length) { + return; + } else if (node.childNodes.length === 1) { + styleText = node.childNodes[0].value; + } else { + styleText = node.childNodes.map(function(tn) { return tn.value; }).join('\n'); + node.childNodes.length = 1; + } + styleText = rewriteURL(importUrl, mainDocUrl, styleText); + node.childNodes[0].value = styleText; } - - var abs = path.resolve(inputPath, rel); - - if (abspath) { - return utils.unixPath(rebasePath(abs, abspath)); + // add assetpath to dom-modules in importDoc + var domModules = dom5.queryAll(importDoc, matchers.domModule); + for (i = 0, node; i < domModules.length; i++) { + node = domModules[i]; + var assetPathUrl = rewriteRelPath(importUrl, mainDocUrl, ''); + assetPathUrl = path.dirname(assetPathUrl) + '/'; + dom5.setAttribute(node, 'assetpath', assetPathUrl); } +} - var relPath = path.relative(outputPath, abs); - return utils.unixPath(relPath); +function rewriteRelPath(importUrl, mainDocUrl, relUrl) { + var absUrl = url.resolve(importUrl, relUrl); + var parsedFrom = url.parse(mainDocUrl); + var parsedTo = url.parse(absUrl); + if (parsedFrom.protocol === parsedTo.protocol && parsedFrom.host === parsedTo.host) { + var pathname = path.relative(path.dirname(parsedFrom.pathname), parsedTo.pathname); + return url.format({ + pathname: pathname, + search: parsedTo.search, + hash: parsedTo.hash + }); + } + return relUrl; } -function rewriteURL(inputPath, outputPath, cssText, abspath, baseUrl) { +function rewriteURL(importUrl, mainDocUrl, cssText) { return cssText.replace(constants.URL, function(match) { var path = match.replace(/["']/g, "").slice(4, -1); - path = rewriteRelPath(inputPath, outputPath, path, abspath, baseUrl); + path = rewriteRelPath(importUrl, mainDocUrl, path); return 'url("' + path + '")'; }); } diff --git a/lib/utils.js b/lib/utils.js deleted file mode 100644 index d0024233f..000000000 --- a/lib/utils.js +++ /dev/null @@ -1,61 +0,0 @@ -/** - * @license - * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. - * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt - * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt - * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt - * Code distributed by Google as part of the polymer project is also - * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt - */ -var path = require('path'); - -function concatTemplates($, context, query, matches) { - $('template, ' + query, context).each(function() { - if (this.name === 'template') { - concatTemplates($, this.children[0], query, matches); - } else { - matches.push(this); - } - }); -} - -module.exports = { - // directly update the textnode child of '); - // clone attributes - styleEl.attr(el.attr()); - // don't set href or rel on the ', - '
', - '', - '
', - '' - ].join('\n'); + var ast = parse(html); + pathresolver.resolvePaths(ast, inputPath, outputPath); + var actual = serialize(ast); + assert.equal(actual, expected, 'relative'); + }); + + test.skip('Resolve Paths with ', function() { var htmlBase = [ '', '', @@ -213,7 +219,7 @@ suite('Path Resolver', function() { '', '', '
', - '' + '' ].join('\n'); var expectedBase = [ @@ -225,30 +231,13 @@ suite('Path Resolver', function() { '', '', '', - '' + '' ].join('\n'); - var actual; - var whacko = require('whacko'); - var $ = whacko.load(html); - - pathresolver.resolvePaths($, inputPath, outputPath); - - actual = $.html(); - assert.equal(actual, expected, 'relative'); - - $ = whacko.load(html); - - pathresolver.resolvePaths($, inputPath, outputPath, '/foo'); - - actual = $.html(); - assert.equal(actual, expected2, 'absolute'); - - $ = whacko.load(htmlBase); - - pathresolver.resolvePaths($, inputPath, outputPath); + var ast = parse(htmlBase); + pathresolver.resolvePaths(ast, inputPath, outputPath); - actual = $.html(); + var actual = serialize(ast); assert.equal(actual, expectedBase, 'base'); }); @@ -260,364 +249,98 @@ suite('Path Resolver', function() { '' ].join('\n'); - var actual; - var whacko = require('whacko'); - var $ = whacko.load(base); + var ast = parse(base); + pathresolver.resolvePaths(ast, inputPath, outputPath); - pathresolver.resolvePaths($, inputPath, outputPath); - - actual = $.html(); + var actual = serialize(ast); assert.equal(actual, base, 'templated urls'); }); }); -suite('Utils', function() { - var constants = require('../lib/constants.js'); - var utils = require('../lib/utils.js'); - - test('getTextContent', function() { - var whacko = require('whacko'); - var divEl = whacko('
some text!
'); - assert.equal(utils.getTextContent(divEl), 'some text!', 'a textnode child'); - var blankEl = whacko('
'); - assert.equal(utils.getTextContent(blankEl), '', 'no textnode children'); - }); - - test('setTextContent', function() { - var whacko = require('whacko'); - var divEl = whacko('
'); - utils.setTextContent(divEl, 'some text!'); - assert.equal(utils.getTextContent(divEl), 'some text!', 'create text node'); - utils.setTextContent(divEl, 'some text 2!'); - assert.equal(utils.getTextContent(divEl), 'some text 2!', 'override text node'); - }); - - test('unixPath', function() { - var pp = ['foo', 'bar', 'baz']; - var p = pp.join('/'); - var actual = utils.unixPath(p); - assert.equal(actual, p, 'started unix'); - var p2 = pp.join('\\'); - actual = utils.unixPath(p2, '\\'); - assert.equal(actual, p, 'windows path'); - }); - - test('escapeForRegExp', function() { - var actual = utils.escapeForRegExp('foo-bar'); - assert.equal(actual, 'foo\\-bar', 'element name'); - actual = utils.escapeForRegExp('foo/bar/baz'); - assert.equal(actual, 'foo\\/bar\\/baz', 'absolute path'); - }); - - test('searchAll', function() { - var searchAll = utils.searchAll; - var whacko = require('whacko'); - var $ = whacko.load('baz'); - var out = searchAll($, 'span'); - - assert.equal(out.length, 4, 'found all spans, nested in templates'); - }); - -}); - -suite('Optparser', function() { - var path = require('path'); - var optParser = require('../lib/optparser.js'); - var constants = require('../lib/constants.js'); - var ABS_URL = constants.ABS_URL; - var REMOTE_ABS_URL = constants.REMOTE_ABS_URL; - - function optParserTest(fn, opts, skipFail) { - if (typeof opts === 'undefined') { - opts = {input: path.resolve('index.html')}; - } - optParser.processOptions(opts, function(err, options) { - if (!skipFail) { - assert.equal(err, null); - } - fn(err, options); - }); - } - - test('Error on no input', function(done) { - optParserTest(function(err, options) { - assert.equal(err, 'No input file or source string given!'); - done(); - }, null, true); - }); - - test('Defaults', function(done) { - optParserTest(function(err, options) { - assert.equal(options.input, path.resolve('index.html')); - assert.equal(options.output, path.resolve('vulcanized.html')); - assert.equal(options.outputDir, path.dirname(path.resolve('vulcanized.html'))); - assert(!options.csp); - assert(!options.abspath); - assert.deepEqual(options.excludes, {imports:[ABS_URL], scripts:[ABS_URL], styles:[ABS_URL]}); - done(); - }); - }); - - test('CSP', function(done) { - optParserTest(function(err, options) { - assert.equal(options.csp, path.resolve('vulcanized.js')); - done(); - }, {input: 'index.html', csp: true}); - }); - - test('output', function(done) { - optParserTest(function(err, options) { - assert.equal(options.output, path.resolve('build.html')); - assert.equal(options.csp, path.resolve('build.js')); - done(); - }, {input: path.resolve('index.html'), output: path.resolve('build.html'), csp: true}); - }); - - test('abspath', function(done) { - optParserTest(function(err, options) { - assert.equal(options.abspath, path.resolve('../')); - assert.deepEqual(options.excludes, {imports:[REMOTE_ABS_URL], scripts:[REMOTE_ABS_URL], styles:[REMOTE_ABS_URL]}); - done(); - }, {input: path.resolve('index.html'), abspath: path.resolve('../')}); - }); - - test('excludes', function(done) { - var excludes = { - imports: [ - '.*' - ] - }; - var expected = [/.*/, ABS_URL]; - - optParserTest(function(err, options) { - assert.deepEqual(options.excludes.imports, expected); - done(); - }, {input: path.resolve('index.html'), excludes: excludes}); - - }); - - test('config file', function(done) { - optParserTest(function(err, options) { - assert.equal(options.input, path.resolve('index.html')); - assert.equal(options.output, path.resolve('build.html')); - assert.equal(options.csp, path.resolve('build.js')); - assert(!options.abspath); - assert.deepEqual(options.excludes, {imports:[/.*/, ABS_URL], scripts:[ABS_URL], styles:[ABS_URL]}); -done(); - }, {config: path.resolve('test/config.json'), input: path.resolve('index.html'), output: path.resolve('build.html'), csp: true}); - }); - - test('report broken config file', function(done) { - optParserTest(function(err, options) { - assert.equal(err, 'Malformed config JSON!'); - done(); - }, {config: path.resolve('test/broken_config.json')}, true); - }); - -}); - -suite('Vulcan', function() { - var vulcan = require('../lib/vulcan.js'); - var outputPath = path.resolve('test/html/actual.html'); - var inputPath = path.resolve('test/html/default.html'); - - var searchAll = require('../lib/utils.js').searchAll; - - test('set options', function(done) { - var options = { - input: 'index.html' - }; - vulcan.setOptions(options, done); - }); - - function process(options, fn) { - var outputs = Object.create(null); - options.outputHandler = function(name, data, eop) { - if (!data) { - throw new Error("Writing empty data"); - } - outputs[name] = data; - }; - vulcan.setOptions(options, function(err) { - assert(!err); - vulcan.processDocument(); - Object.keys(outputs).forEach(function(o) { - assert.equal(typeof outputs[o], 'string', 'all buffers are closed'); - }); - fn(outputs); - }); - } - - test('defaults', function(done) { - var getTextContent = require('../lib/utils.js').getTextContent; - - process({input: inputPath, output: outputPath}, function(outputs) { - assert.equal(Object.keys(outputs).length, 1); - var vulcanized = outputs[outputPath]; - assert(vulcanized); - var $ = require('whacko').load(vulcanized); - assert.equal(searchAll($, 'body > div[hidden]').length, 1, 'only one div[hidden]'); - assert.equal(searchAll($, 'head > link[rel="import"]:not([href^="http://"])').length, 0, 'all relative imports removed'); - assert.equal(searchAll($, 'dom-module').length, 1, 'imports were deduplicated'); - assert.equal($('link', $('dom-module > template').get(0).children[0]).length, 0, 'external styles removed'); - assert.equal($('style', $('dom-module > template').get(0).children[0]).length, 1, 'styles inlined'); - assert.equal($('svg > *', $('dom-module > template').get(0).children[0]).length, 6, 'svg children propery nested'); - assert.equal(searchAll($, 'dom-module').attr('assetpath'), 'imports/', 'assetpath set'); - done(); - }); - }); - - test('CSP', function(done) { - - process({input: inputPath, output: outputPath, csp: true}, function(outputs) { - assert.equal(Object.keys(outputs).length, 2); - var vulcanized = outputs[outputPath]; - var vulcanizedJS = outputs[path.resolve(outputPath, '../actual.js')]; - assert(vulcanized); - assert(vulcanizedJS); - var $ = require('whacko').load(vulcanized); - assert(searchAll($, 'body > script[src="actual.js"]'), 'vulcanized script in body'); - assert.equal(searchAll($, 'body script:not([src])').length, 0, 'inline scripts removed'); - assert.equal(vulcanizedJS.trim(), 'Polymer({\n is: \'my-element\'\n });', 'csp element script'); - done(); - }); - }); - - test('exclude', function(done) { - - var i = 3; - function reallyDone() { - if (--i === 0) { - done(); - } - } - - process({input: inputPath, output: outputPath, excludes: {imports: ['simple-import']}}, function(outputs) { - var vulcanized = outputs[outputPath]; - assert(vulcanized); - var $ = require('whacko').load(vulcanized); - assert.equal(searchAll($, 'head > link[href="imports/simple-import.html"]').length, 0, 'import excluded'); - assert.equal(searchAll($, 'head > link[rel="stylesheet"][href="imports/simple-style.css"]').length, 0, 'import content excluded'); - assert.equal(searchAll($, 'head > link[href="http://example.com/foo/bar.html"]').length, 1, 'external import is not excluded'); - reallyDone(); - }); - - process({input: inputPath, output: outputPath, excludes: {styles: ['simple-style']}}, function(outputs) { - var vulcanized = outputs[outputPath]; - assert(vulcanized); - var $ = require('whacko').load(vulcanized); - assert.equal(searchAll($, 'link[href="imports/simple-style.css"]').length, 1, 'style excluded'); - reallyDone(); - }); - - process({input: inputPath, output: outputPath, excludes: {imports: ['simple-import']}, 'strip-excludes': false}, function(outputs) { - var vulcanized = outputs[outputPath]; - assert(vulcanized); - var $ = require('whacko').load(vulcanized); - assert.equal(searchAll($, 'link[href="imports/simple-import.html"]').length, 1, 'excluded import not stripped'); - reallyDone(); - }); - }); - - suite('Strip', function() { - - test('script', function(done) { - var options = {input: 'test/html/broken-js.html', strip: true}; - vulcan.setOptions(options, function(err) { - assert.ifError(err); - assert.throws(vulcan.processDocument, function(err) { - assert.equal(err.message, 'Compress JS Error'); - assert.equal(err.content.trim(), 'var a = ('); - assert.ok(err.detail); - return true; - }, 'throws useful error'); - done(); - }); - }); - - suite('css', function() { - - test('precsision', function(done) { - process({inputSrc: '', output: outputPath, strip: true}, function(outputs) { - var vulcanized = outputs[outputPath]; - assert(vulcanized); - assert(vulcanized.indexOf('.0000000001px') > -1, 'precision is correct'); - done(); - }); - }); - - test('polyfill-next-selector', function(done) { - process({inputSrc: '', output: outputPath, strip: true}, function(outputs) { - var vulcanized = outputs[outputPath]; - assert(vulcanized); - assert(vulcanized.indexOf(''; - process({inputSrc: input, output: outputPath, strip: true}, function(outputs) { - var vulcanized = outputs[outputPath]; - assert(vulcanized); - assert(vulcanized.indexOf('{{ foo }}') > -1, 'braces kept'); - assert(vulcanized.indexOf(input.replace(/[\r\n]/g, '')) > -1, 'newlines removed at least'); - done(); - }); - }); - }); - - test('comment removal', function(done) { - var options = {input: 'test/html/comments.html', output: outputPath, strip: true}; - process(options, function(outputs) { - var vulcanized = outputs[outputPath]; - assert(vulcanized); - assert(vulcanized.indexOf('@license') > -1, 'license comment at top kept'); - assert.equal(vulcanized.indexOf('comment 1'), -1, 'comment in body removed'); - assert.equal(vulcanized.indexOf('comment 2'), -1, 'comment in template removed'); - assert.equal(vulcanized.indexOf('comment 3'), -1, 'comment in style in template removed'); - assert.equal(vulcanized.indexOf('comment 4'), -1, 'comment in polymer-element removed'); - assert.equal(vulcanized.indexOf('comment 5'), -1, 'comment in script removed'); - done(); - }); - }); - - test('License deduplicated', function(done) { - var options = {inputSrc: '', output: outputPath, strip: true}; - process(options, function(outputs) { - var vulcanized = outputs[outputPath]; - assert(vulcanized); - assert.equal(vulcanized.indexOf('foo'), vulcanized.lastIndexOf('foo')); - done(); - }); - }); - - test('keep fallback declarations', function(done) { - var options = {inputSrc: '', output: outputPath, strip: true}; - process(options, function(outputs) { - var vulcanized = outputs[outputPath]; - assert(vulcanized); - assert(vulcanized.indexOf('display: flex') > -1, 'keep flex'); - assert(vulcanized.indexOf('display: -webkit-flex') > -1, 'keep -webkit-flex'); - done(); - }); - }); - - }); - - test('Handle tag', function(done) { - var options = {input: 'test/html/base.html', output: outputPath}; - process(options, function(outputs) { - var vulcanized = outputs[outputPath]; - assert(vulcanized); - var $ = require('whacko').load(vulcanized); - var spanHref = $('span').attr('href'); - assert.equal('imports/hello', spanHref, ' accounted for'); - var divHref = $('a').attr('href'); - assert.equal('imports/sub-base/sub-base.html', divHref); - done(); - }); - }); +suite.skip('Vulcan', function() { + var vulcan = require('../lib/vulcan.js'); + var outputPath = path.resolve('test/html/actual.html'); + var inputPath = path.resolve('test/html/default.html'); + + var loader; + + var hyd = require('hydrolysis'); + + setup(function() { + loader = new hyd.Loader(); + loader.addResolver(new hyd.FSResolver({})); + }); + + function process(input, cb) { + } + + test('defaults', function(done) { + + process({input: inputPath, output: outputPath}, function(outputs) { + assert.equal(Object.keys(outputs).length, 1); + var vulcanized = outputs[outputPath]; + assert(vulcanized); + var $ = require('whacko').load(vulcanized); + assert.equal(searchAll($, 'body > div[hidden]').length, 1, 'only one div[hidden]'); + assert.equal(searchAll($, 'head > link[rel="import"]:not([href^="http://"])').length, 0, 'all relative imports removed'); + assert.equal(searchAll($, 'dom-module').length, 1, 'imports were deduplicated'); + assert.equal($('link', $('dom-module > template').get(0).children[0]).length, 0, 'external styles removed'); + assert.equal($('style', $('dom-module > template').get(0).children[0]).length, 1, 'styles inlined'); + assert.equal($('svg > *', $('dom-module > template').get(0).children[0]).length, 6, 'svg children propery nested'); + assert.equal(searchAll($, 'dom-module').attr('assetpath'), 'imports/', 'assetpath set'); + done(); + }); + }); + + test.skip('exclude', function(done) { + + var i = 3; + function reallyDone() { + if (--i === 0) { + done(); + } + } + + process({input: inputPath, output: outputPath, excludes: {imports: ['simple-import']}}, function(outputs) { + var vulcanized = outputs[outputPath]; + assert(vulcanized); + var $ = require('whacko').load(vulcanized); + assert.equal(searchAll($, 'head > link[href="imports/simple-import.html"]').length, 0, 'import excluded'); + assert.equal(searchAll($, 'head > link[rel="stylesheet"][href="imports/simple-style.css"]').length, 0, 'import content excluded'); + assert.equal(searchAll($, 'head > link[href="http://example.com/foo/bar.html"]').length, 1, 'external import is not excluded'); + reallyDone(); + }); + + process({input: inputPath, output: outputPath, excludes: {styles: ['simple-style']}}, function(outputs) { + var vulcanized = outputs[outputPath]; + assert(vulcanized); + var $ = require('whacko').load(vulcanized); + assert.equal(searchAll($, 'link[href="imports/simple-style.css"]').length, 1, 'style excluded'); + reallyDone(); + }); + + process({input: inputPath, output: outputPath, excludes: {imports: ['simple-import']}, 'strip-excludes': false}, function(outputs) { + var vulcanized = outputs[outputPath]; + assert(vulcanized); + var $ = require('whacko').load(vulcanized); + assert.equal(searchAll($, 'link[href="imports/simple-import.html"]').length, 1, 'excluded import not stripped'); + reallyDone(); + }); + }); + + test.skip('Handle tag', function(done) { + var options = {input: 'test/html/base.html', output: outputPath}; + process(options, function(outputs) { + var vulcanized = outputs[outputPath]; + assert(vulcanized); + var $ = require('whacko').load(vulcanized); + var spanHref = $('span').attr('href'); + assert.equal('imports/hello', spanHref, ' accounted for'); + var divHref = $('a').attr('href'); + assert.equal('imports/sub-base/sub-base.html', divHref); + done(); + }); + }); }); From 672de5470828f2ac6d6c900d283f70047d810984 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Wed, 25 Mar 2015 17:34:57 -0700 Subject: [PATCH 0240/1006] re-enable travis --- .travis.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index d672ef15c..6064ca092 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,5 @@ language: node_js node_js: - "0.10" -branches: - except: - - hydro-demo + - "0.12" + - "iojs" From 97408217841d27f7f10653918ecfa00d932133c6 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Thu, 26 Mar 2015 10:58:28 -0700 Subject: [PATCH 0241/1006] add some up to date docs --- README.md | 241 ++++++-------------------------------------------- bin/vulcanize | 28 +++++- 2 files changed, 50 insertions(+), 219 deletions(-) diff --git a/README.md b/README.md index 95a584337..6b072c2e2 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ # Vulcanize -### Concatenate a set of Web Components into one file +### Reduce an HTML file and its dependent HTML Imports into one file >Named for the [Vulcanization](http://en.wikipedia.org/wiki/Vulcanization) process that turns polymers into more durable materials. @@ -12,237 +12,48 @@ materials. `vulcanize` is available on npm. For maximium utility, `vulcanize` should be installed globally. - sudo npm install -g vulcanize + npm install -g vulcanize This will install `vulcanize` to `/usr/local/bin/vulcanize`. ## Usage +The command - vulcanize index.html + vulcanize target.html -At the simplest, `vulcanize` only requires an html file as an argument. The optimized output file will be named -`vulcanized.html`. +will inline the HTML Imports of `target.html` and print the resulting HTML to +standard output. -If you want to control the output name, use the `-o` flag +The command - vulcanize -o build.html index.html + vulcanize target.html > build.html -Most URLs will be automatically adjusted by the vulcanizer. +will inline the HTML Imports of `target.html` and print the result to +`build.html`. +## Using vulcanize programmatically -## Options +Vulcanize as a library has only one exported function. -- `--output`, `-o` - - Output file name (defaults to vulcanized.html) -- `--verbose`, `-v` - - More verbose logging -- `--help`, `-v`, `-?` - - Print this message -- `--config` - - Read a given config file -- `--strip`, `-s` - - Remove comments and empty text nodes -- `--csp` - - Extract inline scripts to a separate file (uses ``.js) -- `--inline` - - The opposite of CSP mode, inline all assets (script and css) into the document -- `--inline --csp` - - Bundle all javascript (inline and external) into ``.js -- `--abspath`, `-p` - - Specify site root. Resolve paths to absolute paths based on site root -- `--no-strip-excludes` - - Keep imports excluded from inlining -- `--version`, ` -V` - - print version information +`vulcanize.process` takes a `target` path to `target.html`, a `output directory` +path for rebasing urls in the main document, a hydrolysis loader (more on that +later), and a callback. -## Additional options when used as Node module - -In addition to the above options, `vulcan` when used as Node module has additional options for string-based rather than file-based document processing. These are: - -- `inputSrc` - - The document to process, represented as String, String Buffer, or any Object with a `toString` function that yields valid HTML souce. Imports are resolved relative to the directory in which the node process was started. -- `outputHandler` - - An output handler function to call rather than writing the processing result to file. The handler must be of the form `function(filename, data)`, which is called with the following arguments: - - `filename` - - The file that vulcanize would create if it were running in file I/O mode. - - `data` - - The HTML source that vulcanize writes to file if no outputhandler is used. - -An example of using these options is shown below: - -``` -var vulcan = require("./lib/vulcan"); - -var head = ""; -var body = "test"; -var input = "" + head + body + ""; - -var outputHandler = function(filename, data) { - console.log(data); -}; - -vulcan.setOptions({inputSrc: input, outputHandler: outputHandler}, function(err) { - if(err) { - console.error(err); - process.exit(1); - } - vulcan.processDocument(); -}); - -``` - -## Config -> JSON file for additional options - -- Excludes: Remove the selected urls completely from the vulcanized bundle: - - Use the `--no-strip-excludes` command line flag, or set `"strip-excludes": false` - in the config to keep excluded urls in the output bundle. - -### Example Config -```json -{ - "excludes": { - "imports": [ - "regex-to-exclude" - ] - } -} -``` - -### Keep excludes config -```json -{ - "excludes": { - "imports": [ - "regex-to-exclude" - ] - }, - "strip-excludes": false -} -``` - -## Example Usage - -Say we have three html files: `index.html`, `x-app.html`, and `x-dep.html`. - -index.html: - -```html - - - -``` - -x-app.html: - -```html - - - - - -``` - -x-dep.html: - -```html - - - - -``` - -Running vulcan on `index.html`, and specifying `build.html` as the output: - - vulcanize -o build.html index.html - -Will result in `build.html` that appears as so: - -```html - - - -``` - -## Content Security Policy -[Content Security Policy](http://en.wikipedia.org/wiki/Content_Security_Policy), or CSP, is a Javascript security model -that aims to prevent XSS and other attacks. In so doing, it prohibits the use of inline scripts. - -To help automate the use of Polymer element registration with CSP, the `--csp` flag to vulcan will remove all scripts -from the HTML Imports and place their contents into an output javascript file. - -Using the previous example, the output from `vulcanize --csp -o build.html index.html` will be - -build.html: -```html - - - - -``` - -build.js: +Example: ```js +var vulcan = require('vulcanize'); +var hydrolysis = require('hydrolysis'); - Polymer('x-dep'); - ; -Polymer('x-app') -``` - -The JS files can become a bit messy without reformatting, and semi-colons are inserted between script contents as a -precaution. - -## Stripping whitespace +var loader = new hydrolysis.Loader(); +loader.addResolver(new hydrolysis.FSResolver({})); -Vulcanize includes a set of size reducing heuristics to remove unnecessary whitespace and comments in HTML, JS, and CSS. -This can be activated by using the `--strip` option. - -Using the previous example, the output from `vulcanize --csp -o build.html --strip index.html` will be - -build.html: -```html - - - - +vulcan.process(target, process.cwd(), loader, function(err, inlinedHtml) { +}); ``` -```js -Polymer("x-dep");Polymer("x-app"); -``` +`vulcanize` depends on `hydrolysis` to crawl the tree of HTML Imports, and +`vulcanize.process` depends on being given a `hydrolysis` loader to resolve +files. +**Note: fill this in later** [![Analytics](https://ga-beacon.appspot.com/UA-39334307-2/Polymer/vulcanize/README)](https://github.com/igrigorik/ga-beacon) diff --git a/bin/vulcanize b/bin/vulcanize index a1767a736..cb13d537f 100755 --- a/bin/vulcanize +++ b/bin/vulcanize @@ -15,16 +15,36 @@ var hyd = require('hydrolysis'); var vulcan = require('../lib/vulcan'); -var loader = new hyd.Loader(); -loader.addResolver(new hyd.FSResolver({})); - var target = process.argv[2]; +var help = [ + 'vulcanize: Reduce an HTML file and its dependent HTML Imports into one file', + '', + 'Usage:', + ' vulcanize ', + 'Examples:', + ' The command', + '', + ' vulcanize target.html', + '', + ' will inline the HTML Imports of `target.html` and print the resulting HTML to standard output.', + '', + ' The command', + '', + ' vulcanize target.html > build.html', + '', + ' will inline the HTML Imports of `target.html` and print the result to build.html.' +].join('\n'); + if (!target) { - console.error('no target!'); + console.error(help); process.exit(1); } +var loader = new hyd.Loader(); +loader.addResolver(new hyd.FSResolver({})); + + vulcan.process(target, process.cwd(), loader, function(err, content) { if (err) { console.log(err); From 3ae884e60729cc9cfe4617687b12407973f6e6a1 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Fri, 27 Mar 2015 15:43:26 -0700 Subject: [PATCH 0242/1006] Use the "hidden div" method from last codebase Casper - CSP splitter after vulcanize --- bin/casper | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++ lib/vulcan.js | 10 ++++++-- 2 files changed, 76 insertions(+), 2 deletions(-) create mode 100755 bin/casper diff --git a/bin/casper b/bin/casper new file mode 100755 index 000000000..a61a1f66a --- /dev/null +++ b/bin/casper @@ -0,0 +1,68 @@ +#!/usr/bin/env node +/** + * @license + * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. + * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt + * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt + * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt + * Code distributed by Google as part of the polymer project is also + * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt + */ + +// jshint node: true +'use strict'; + +var path = require('path'); +var fs = require('fs'); + +var parse5 = require('parse5'); +var parser = new parse5.Parser(); +var serializer = new parse5.Serializer(); + +var dom5 = require('dom5'); +var pred = dom5.predicates; + +var inlineScriptFinder = pred.AND( + pred.hasTagName('script'), + pred.OR( + pred.NOT( + pred.hasAttr('type') + ), + pred.hasAttrValue('type', 'application/javascript'), + pred.hasAttrValue('type', 'text/javascript') + ), + pred.NOT( + pred.hasAttr('src') + ) +); + +var target = process.argv[2]; +var outhtml = path.resolve(process.argv[3]); +var outscript = path.resolve(process.argv[4]); + +var html = fs.readFileSync(target, 'utf-8'); + +var doc = parser.parse(html); +var head = dom5.query(doc, pred.hasTagName('head')); +var body = dom5.query(doc, pred.hasTagName('body')); +var scripts = dom5.queryAll(doc, inlineScriptFinder); + +function remove(node) { + var parent = node.parentNode; + var idx = parent.childNodes.indexOf(node); + parent.childNodes.splice(idx, 1); +} + +var contents = []; +scripts.forEach(function(sn) { + remove(sn); + contents.push(sn.childNodes[0].value); +}); + +var newScript = dom5.constructors.element('script'); +dom5.setAttribute(newScript, 'src', path.relative(path.dirname(outhtml), outscript)); +dom5.parentNode = body; +body.childNodes.push(newScript); + +fs.writeFileSync(outhtml, serializer.serialize(doc), 'utf-8'); +fs.writeFileSync(outscript, contents.join(';'), 'utf-8'); diff --git a/lib/vulcan.js b/lib/vulcan.js index 4b87c3915..f04027fd7 100644 --- a/lib/vulcan.js +++ b/lib/vulcan.js @@ -60,13 +60,19 @@ function flatten(tree) { // merge head and body tags for imports into main document importHeadChildren = importHead.childNodes; importBodyChildren = importBody.childNodes; + var hideDiv = dom5.constructors.element('div'); + dom5.setAttribute(hideDiv, 'hidden', ''); + hideDiv.childNodes = importBodyChildren; importHeadChildren.forEach(reparent(head)); - importBodyChildren.forEach(reparent(body)); + importBodyChildren.forEach(reparent(hideDiv)); + hideDiv.childNodes = importBodyChildren; // replace import node with importHeadChildren var idx = head.childNodes.indexOf(importNodes[i]); head.childNodes = head.childNodes.slice(0, idx).concat(importHeadChildren, head.childNodes.slice(idx + 1)); // prepend import body to document body - body.childNodes = importBodyChildren.concat(body.childNodes); + if (importBodyChildren.length) { + body.childNodes.unshift(hideDiv); + } } } return doc; From 370edb3a8e6ac3666571ac6561e0e84c75a346b9 Mon Sep 17 00:00:00 2001 From: Jeremy Klein Date: Mon, 30 Mar 2015 17:59:04 -0700 Subject: [PATCH 0243/1006] Add charset meta tag if needed --- lib/constants.js | 1 + lib/vulcan.js | 4 ++++ test/html/default.html | 1 - test/test.js | 3 ++- 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/constants.js b/lib/constants.js index da7fbf95b..9fff354d3 100644 --- a/lib/constants.js +++ b/lib/constants.js @@ -12,6 +12,7 @@ var JS = 'script:not([type]), script[type="text/javascript"], script[type="appli var URL_ATTR = ['href', 'src', 'action', 'style']; module.exports = { + CHARSET_META: '', EOL: require('os').EOL, ELEMENTS: 'polymer-element:not([assetpath])', ELEMENTS_NOSCRIPT: 'polymer-element[noscript]', diff --git a/lib/vulcan.js b/lib/vulcan.js index 128861ede..6bab83bd4 100644 --- a/lib/vulcan.js +++ b/lib/vulcan.js @@ -344,6 +344,10 @@ function handleMainDocument() { removeCommentsAndWhitespace($); } + var charsetMeta = searchAll($, 'meta[charset]'); + if (charsetMeta.length === 0) { + $('head').append(constants.CHARSET_META); + } writeFileSync(options.output, $.html(), true); } diff --git a/test/html/default.html b/test/html/default.html index 68f1516d5..188d68801 100644 --- a/test/html/default.html +++ b/test/html/default.html @@ -10,7 +10,6 @@ --> - diff --git a/test/test.js b/test/test.js index c9027fec8..1d7e72d2d 100644 --- a/test/test.js +++ b/test/test.js @@ -496,6 +496,7 @@ suite('Vulcan', function() { var $ = require('whacko').load(vulcanized); assert.equal(searchAll($, 'body > div[hidden]').length, 1, 'only one div[hidden]'); assert.equal(searchAll($, 'head > link[rel="import"]:not([href^="http://"])').length, 0, 'all relative imports removed'); + assert.equal(searchAll($, 'head > meta[charset="UTF-8"]').length, 1, 'charset meta tag added.'); assert.equal(searchAll($, 'polymer-element').length, 1, 'imports were deduplicated'); assert.equal(searchAll($, 'polymer-element').attr('noscript'), null, 'noscript removed'); assert.equal(getTextContent(searchAll($, 'polymer-element > script')), 'Polymer(\'my-element\');', 'polymer script included'); @@ -578,7 +579,7 @@ suite('Vulcan', function() { test('whitespace', function(done) { process({inputSrc: '
\n
\n hi  \n
\n
', output: outputPath, strip: true}, function(outputs) { var vulcanized = outputs[outputPath]; - assert.equal(vulcanized, '
hi  
'); + assert.equal(vulcanized, '
hi  
'); done(); }); }); From e55b35e6273cd9c8fc0d3bd55cd5d417f30196fa Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Tue, 31 Mar 2015 10:36:11 -0700 Subject: [PATCH 0244/1006] Make sure import bodies are ordered correctly Use new Analyzer api, remove path rewriting in main doc (too confusing) --- bin/casper | 21 ++++------------- bin/vulcanize | 6 ++--- lib/vulcan.js | 65 +++++++++++++++++++++------------------------------ 3 files changed, 35 insertions(+), 57 deletions(-) diff --git a/bin/casper b/bin/casper index a61a1f66a..9cdcb479d 100755 --- a/bin/casper +++ b/bin/casper @@ -15,10 +15,6 @@ var path = require('path'); var fs = require('fs'); -var parse5 = require('parse5'); -var parser = new parse5.Parser(); -var serializer = new parse5.Serializer(); - var dom5 = require('dom5'); var pred = dom5.predicates; @@ -42,27 +38,20 @@ var outscript = path.resolve(process.argv[4]); var html = fs.readFileSync(target, 'utf-8'); -var doc = parser.parse(html); +var doc = dom5.parse(html); var head = dom5.query(doc, pred.hasTagName('head')); var body = dom5.query(doc, pred.hasTagName('body')); var scripts = dom5.queryAll(doc, inlineScriptFinder); -function remove(node) { - var parent = node.parentNode; - var idx = parent.childNodes.indexOf(node); - parent.childNodes.splice(idx, 1); -} - var contents = []; scripts.forEach(function(sn) { - remove(sn); - contents.push(sn.childNodes[0].value); + dom5.remove(sn); + contents.push(dom5.getTextContent(sn)); }); var newScript = dom5.constructors.element('script'); dom5.setAttribute(newScript, 'src', path.relative(path.dirname(outhtml), outscript)); -dom5.parentNode = body; -body.childNodes.push(newScript); +dom5.append(body, newScript); -fs.writeFileSync(outhtml, serializer.serialize(doc), 'utf-8'); +fs.writeFileSync(outhtml, dom5.serialize(doc), 'utf-8'); fs.writeFileSync(outscript, contents.join(';'), 'utf-8'); diff --git a/bin/vulcanize b/bin/vulcanize index cb13d537f..c52841fb7 100755 --- a/bin/vulcanize +++ b/bin/vulcanize @@ -45,10 +45,10 @@ var loader = new hyd.Loader(); loader.addResolver(new hyd.FSResolver({})); -vulcan.process(target, process.cwd(), loader, function(err, content) { +vulcan.process(target, loader, function(err, content) { if (err) { - console.log(err); - console.log(err.stack); + console.error(err); + console.error(err.stack); process.exit(1); } console.log(content); diff --git a/lib/vulcan.js b/lib/vulcan.js index f04027fd7..210552a4e 100644 --- a/lib/vulcan.js +++ b/lib/vulcan.js @@ -11,7 +11,6 @@ // jshint node: true 'use strict'; -var path = require('path'); var hyd = require('hydrolysis'); var dom5 = require('dom5'); var constants = require('./constants'); @@ -28,68 +27,58 @@ function reparent(newParent) { }; } -function remove(node) { - var parent = node.parentNode; - if (parent) { - var idx = parent.childNodes.indexOf(node); - if (idx > -1) { - parent.childNodes.splice(idx, 1); - } - } -} - -function flatten(tree) { +function flatten(tree, bodyContents) { var doc = tree.html.ast; var imports = tree.imports; var head = dom5.query(doc, matchers.head); var body = dom5.query(doc, matchers.body); var importNodes = tree.html.import; - var importDoc, importHead, importBody, importHeadChildren, importBodyChildren; if (imports) { for (var i = 0, im; i < imports.length; i++) { im = imports[i]; if (!isUniqueImport(im)) { - remove(importNodes[i]); + dom5.remove(importNodes[i]); continue; } - importDoc = flatten(im); + var importDoc = flatten(im, bodyContents); // rewrite urls pathResolver.resolvePaths(importDoc, im.href, tree.href); - importHead = dom5.query(importDoc, matchers.head); - importBody = dom5.query(importDoc, matchers.body); + var importHead = dom5.query(importDoc, matchers.head); + var importBody = dom5.query(importDoc, matchers.body); // merge head and body tags for imports into main document - importHeadChildren = importHead.childNodes; - importBodyChildren = importBody.childNodes; - var hideDiv = dom5.constructors.element('div'); - dom5.setAttribute(hideDiv, 'hidden', ''); - hideDiv.childNodes = importBodyChildren; + var importHeadChildren = importHead.childNodes; + var importBodyChildren = importBody.childNodes; importHeadChildren.forEach(reparent(head)); - importBodyChildren.forEach(reparent(hideDiv)); - hideDiv.childNodes = importBodyChildren; - // replace import node with importHeadChildren + // replace link in head with head elements from import var idx = head.childNodes.indexOf(importNodes[i]); head.childNodes = head.childNodes.slice(0, idx).concat(importHeadChildren, head.childNodes.slice(idx + 1)); - // prepend import body to document body + // defer body children to be inlined in-order if (importBodyChildren.length) { - body.childNodes.unshift(hideDiv); + bodyContents.push(importBodyChildren); } } } return doc; } -function process(target, outDir, loader, cb) { - var resolvedTarget = path.resolve(target); - var m = new hyd.Monomers(true, loader); - m.metadataTree(target).then(function(tree) { - var flatDoc = flatten(tree); - var dir = path.dirname(path.resolve(target)); - // rewrite to be local to current working directory - if (dir !== outDir) { - pathResolver.resolvePaths(flatDoc, target, path.resolve(outDir, 'foo.html')); +function process(target, loader, cb) { + var analyzer = new hyd.Analyzer(true, loader); + analyzer.metadataTree(target).then(function(tree) { + var bodyContents = []; + var flatDoc = flatten(tree, bodyContents); + var body = dom5.query(flatDoc, matchers.body); + var reduced = bodyContents.reduce(function(a, b) { + return a.concat(b); + }); + if (reduced.length) { + var hiddenDiv = dom5.constructors.element('div'); + dom5.setAttribute(hiddenDiv, 'hidden', ''); + dom5.setAttribute(hiddenDiv, 'by-vulcanize', ''); + reduced.forEach(reparent(hiddenDiv)); + hiddenDiv.childNodes = reduced; + dom5.insertBefore(body, body.childNodes[0], hiddenDiv); } - var serializer = new (require('parse5').Serializer)(); - var out = serializer.serialize(flatDoc); + var out = dom5.serialize(flatDoc); cb(null, out); }).catch(cb); } From 2b9a9ed01f31ecddb68894e56582f924c2394507 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Tue, 31 Mar 2015 13:59:02 -0700 Subject: [PATCH 0245/1006] handle base tags in main document --- bin/irving | 54 +++++++++++++++++++++++++++++++++++++++++++++ lib/matchers.js | 12 +++++----- lib/pathresolver.js | 14 +++--------- lib/vulcan.js | 22 +++++++++++++++++- 4 files changed, 83 insertions(+), 19 deletions(-) create mode 100755 bin/irving diff --git a/bin/irving b/bin/irving new file mode 100755 index 000000000..7dea9d6fe --- /dev/null +++ b/bin/irving @@ -0,0 +1,54 @@ +#!/usr/bin/env node +/** + * @license + * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. + * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt + * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt + * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt + * Code distributed by Google as part of the polymer project is also + * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt + */ + +// jshint node: true +'use strict'; + +var fs = require('fs'); +var dom5 = require('dom5'); +var pred = dom5.predicates; + +var headMatcher = pred.hasTagName('head'); +var bodyMatcher = pred.hasTagName('body'); + +var docText; + +process.stdin.setEncoding('utf-8'); +process.stdin.on('readable', function() { + var chunk = process.stdin.read(); + if (chunk !== null) { + docText += chunk; + } +}); + +process.stdin.on('end', function() { + var doc = dom5.parse(docText); + + var head = dom5.query(doc, headMatcher); + var body = dom5.query(doc, bodyMatcher); + var html = head.parentNode; + + dom5.remove(head); + dom5.remove(body); + + var reparent = function(node) { + node.parentNode = html; + }; + + var headNodes = head.childNodes; + var bodyNodes = body.childNodes; + + headNodes.forEach(reparent); + bodyNodes.forEach(reparent); + html.childNodes = headNodes.concat(bodyNodes); + + process.stdout.write(dom5.serialize(doc)); +}); diff --git a/lib/matchers.js b/lib/matchers.js index 1b28fb2a4..2f29dd9f6 100644 --- a/lib/matchers.js +++ b/lib/matchers.js @@ -47,13 +47,7 @@ module.exports = { body: p.hasTagName('body'), base: p.AND( p.hasTagName('base'), - function(node) { - var href = dom5.getAttribute(node, 'href'); - if (href) { - return true; - } - return false; - } + p.hasAttr('href') ), domModule: p.AND( p.hasTagName('dom-module'), @@ -62,6 +56,10 @@ module.exports = { p.hasAttr('assetpath') ) ), + meta: p.AND( + p.hasTagName('meta'), + p.hasAttr('charset') + ), urlAttrs: urlAttrs, JS: jsMatcher, CSS: styleMatcher, diff --git a/lib/pathresolver.js b/lib/pathresolver.js index 1cfe88349..03254248f 100644 --- a/lib/pathresolver.js +++ b/lib/pathresolver.js @@ -48,17 +48,9 @@ function resolvePaths(importDoc, importUrl, mainDocUrl) { var styleNodes = dom5.queryAll(importDoc, matchers.CSS); for (i = 0, node; i < styleNodes.length; i++) { node = styleNodes[i]; - var styleText = ''; - if (!node.childNodes.length) { - return; - } else if (node.childNodes.length === 1) { - styleText = node.childNodes[0].value; - } else { - styleText = node.childNodes.map(function(tn) { return tn.value; }).join('\n'); - node.childNodes.length = 1; - } + var styleText = dom5.getTextContent(node); styleText = rewriteURL(importUrl, mainDocUrl, styleText); - node.childNodes[0].value = styleText; + dom5.setTextContent(node, styleText); } // add assetpath to dom-modules in importDoc var domModules = dom5.queryAll(importDoc, matchers.domModule); @@ -89,7 +81,7 @@ function rewriteRelPath(importUrl, mainDocUrl, relUrl) { hash: parsedTo.hash }); } - return relUrl; + return absUrl; } function rewriteURL(importUrl, mainDocUrl, cssText) { diff --git a/lib/vulcan.js b/lib/vulcan.js index 210552a4e..58a69c8f0 100644 --- a/lib/vulcan.js +++ b/lib/vulcan.js @@ -41,6 +41,12 @@ function flatten(tree, bodyContents) { continue; } var importDoc = flatten(im, bodyContents); + // remove tag + // hydrolysis has accounted for the href already in import.href + var base = dom5.query(importDoc, matchers.base); + if (base) { + dom5.remove(base); + } // rewrite urls pathResolver.resolvePaths(importDoc, im.href, tree.href); var importHead = dom5.query(importDoc, matchers.head); @@ -61,16 +67,30 @@ function flatten(tree, bodyContents) { return doc; } +// remove the effects of in main document +function acid(doc, docUrl) { + var base = dom5.query(doc, matchers.base); + if (base) { + dom5.remove(base); + } + var baseUrl = dom5.getAttribute(base, 'href') + '/'; + var documentBaseUri = require('url').resolve(baseUrl, docUrl); + pathResolver.resolvePaths(doc, documentBaseUri, docUrl); +} + function process(target, loader, cb) { var analyzer = new hyd.Analyzer(true, loader); analyzer.metadataTree(target).then(function(tree) { + // rewrite urls in main doc to remove + acid(tree.html.ast, tree.href); var bodyContents = []; var flatDoc = flatten(tree, bodyContents); var body = dom5.query(flatDoc, matchers.body); var reduced = bodyContents.reduce(function(a, b) { return a.concat(b); - }); + }, []); if (reduced.length) { + // hide bodies of imports from rendering var hiddenDiv = dom5.constructors.element('div'); dom5.setAttribute(hiddenDiv, 'hidden', ''); dom5.setAttribute(hiddenDiv, 'by-vulcanize', ''); From 4a09a5fd394ba7e734eeabca8aab150c5d6aef95 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Tue, 31 Mar 2015 14:18:49 -0700 Subject: [PATCH 0246/1006] add license file --- LICENSE | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..95987bac8 --- /dev/null +++ b/LICENSE @@ -0,0 +1,27 @@ +// Copyright (c) 2014 The Polymer Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. From bf1cd865aa857d390f0ecd64d0598c5132573a75 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Tue, 31 Mar 2015 14:56:37 -0700 Subject: [PATCH 0247/1006] Use published dom5 and hydrolysis versions --- package.json | 7 +++---- test/test.js | 6 +++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 38ddd3cad..fe47ab4f5 100644 --- a/package.json +++ b/package.json @@ -7,10 +7,9 @@ "vulcanize": "bin/vulcanize" }, "dependencies": { - "hydrolysis": "git://github.com/PolymerLabs/hydrolysis.git#master", - "nopt": "^3.0.1", - "dom5": "git://github.com/PolymerLabs/dom5.git#master", - "parse5": "^1.4.1" + "dom5": "^1.0.0", + "hydrolysis": "^1.0.0", + "nopt": "^3.0.1" }, "devDependencies": { "jshint": "^2.5.6", diff --git a/test/test.js b/test/test.js index b7eaeffc5..c01ad9fc3 100644 --- a/test/test.js +++ b/test/test.js @@ -11,13 +11,13 @@ var assert = require('assert'); var path = require('path'); -var parse5 = require('parse5'); +var dom5 = require('dom5'); function parse(text) { - return new (parse5.Parser)().parse(text); + return dom5.parse(text); } function serialize(ast) { - return new (parse5.Serializer)().serialize(ast); + return dom5.serialize(ast); } assert.AssertionError.prototype.showDiff = true; From 76a46cbba69411b94f2b9922bfe5f97e18fcd340 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Wed, 1 Apr 2015 12:53:02 -0700 Subject: [PATCH 0248/1006] Add a UTF-8 charset if one is missing Remove broken base handling to be replaced later --- lib/vulcan.js | 26 ++----- test/html/default.html | 1 - test/test.js | 169 +++++++++++++++++++++-------------------- 3 files changed, 93 insertions(+), 103 deletions(-) diff --git a/lib/vulcan.js b/lib/vulcan.js index 58a69c8f0..ac8d473be 100644 --- a/lib/vulcan.js +++ b/lib/vulcan.js @@ -41,12 +41,6 @@ function flatten(tree, bodyContents) { continue; } var importDoc = flatten(im, bodyContents); - // remove tag - // hydrolysis has accounted for the href already in import.href - var base = dom5.query(importDoc, matchers.base); - if (base) { - dom5.remove(base); - } // rewrite urls pathResolver.resolvePaths(importDoc, im.href, tree.href); var importHead = dom5.query(importDoc, matchers.head); @@ -67,22 +61,10 @@ function flatten(tree, bodyContents) { return doc; } -// remove the effects of in main document -function acid(doc, docUrl) { - var base = dom5.query(doc, matchers.base); - if (base) { - dom5.remove(base); - } - var baseUrl = dom5.getAttribute(base, 'href') + '/'; - var documentBaseUri = require('url').resolve(baseUrl, docUrl); - pathResolver.resolvePaths(doc, documentBaseUri, docUrl); -} - function process(target, loader, cb) { var analyzer = new hyd.Analyzer(true, loader); analyzer.metadataTree(target).then(function(tree) { // rewrite urls in main doc to remove - acid(tree.html.ast, tree.href); var bodyContents = []; var flatDoc = flatten(tree, bodyContents); var body = dom5.query(flatDoc, matchers.body); @@ -98,6 +80,14 @@ function process(target, loader, cb) { hiddenDiv.childNodes = reduced; dom5.insertBefore(body, body.childNodes[0], hiddenDiv); } + // make sure there's a in the page to force UTF-8 + var meta = dom5.query(flatDoc, matchers.meta); + if (!meta) { + meta = dom5.constructors.element('meta'); + dom5.setAttribute(meta, 'charset', 'UTF-8'); + var head = dom5.query(flatDoc, matchers.head); + dom5.insertBefore(head, head.childNodes[0], meta); + } var out = dom5.serialize(flatDoc); cb(null, out); }).catch(cb); diff --git a/test/html/default.html b/test/html/default.html index 68f1516d5..0783f3df5 100644 --- a/test/html/default.html +++ b/test/html/default.html @@ -13,7 +13,6 @@ - Sample Build diff --git a/test/test.js b/test/test.js index c01ad9fc3..2a8e98579 100644 --- a/test/test.js +++ b/test/test.js @@ -258,89 +258,90 @@ suite('Path Resolver', function() { }); -suite.skip('Vulcan', function() { - var vulcan = require('../lib/vulcan.js'); - var outputPath = path.resolve('test/html/actual.html'); - var inputPath = path.resolve('test/html/default.html'); - - var loader; - - var hyd = require('hydrolysis'); - - setup(function() { - loader = new hyd.Loader(); - loader.addResolver(new hyd.FSResolver({})); - }); - - function process(input, cb) { - } - - test('defaults', function(done) { - - process({input: inputPath, output: outputPath}, function(outputs) { - assert.equal(Object.keys(outputs).length, 1); - var vulcanized = outputs[outputPath]; - assert(vulcanized); - var $ = require('whacko').load(vulcanized); - assert.equal(searchAll($, 'body > div[hidden]').length, 1, 'only one div[hidden]'); - assert.equal(searchAll($, 'head > link[rel="import"]:not([href^="http://"])').length, 0, 'all relative imports removed'); - assert.equal(searchAll($, 'dom-module').length, 1, 'imports were deduplicated'); - assert.equal($('link', $('dom-module > template').get(0).children[0]).length, 0, 'external styles removed'); - assert.equal($('style', $('dom-module > template').get(0).children[0]).length, 1, 'styles inlined'); - assert.equal($('svg > *', $('dom-module > template').get(0).children[0]).length, 6, 'svg children propery nested'); - assert.equal(searchAll($, 'dom-module').attr('assetpath'), 'imports/', 'assetpath set'); - done(); - }); - }); - - test.skip('exclude', function(done) { - - var i = 3; - function reallyDone() { - if (--i === 0) { - done(); - } - } - - process({input: inputPath, output: outputPath, excludes: {imports: ['simple-import']}}, function(outputs) { - var vulcanized = outputs[outputPath]; - assert(vulcanized); - var $ = require('whacko').load(vulcanized); - assert.equal(searchAll($, 'head > link[href="imports/simple-import.html"]').length, 0, 'import excluded'); - assert.equal(searchAll($, 'head > link[rel="stylesheet"][href="imports/simple-style.css"]').length, 0, 'import content excluded'); - assert.equal(searchAll($, 'head > link[href="http://example.com/foo/bar.html"]').length, 1, 'external import is not excluded'); - reallyDone(); - }); - - process({input: inputPath, output: outputPath, excludes: {styles: ['simple-style']}}, function(outputs) { - var vulcanized = outputs[outputPath]; - assert(vulcanized); - var $ = require('whacko').load(vulcanized); - assert.equal(searchAll($, 'link[href="imports/simple-style.css"]').length, 1, 'style excluded'); - reallyDone(); - }); - - process({input: inputPath, output: outputPath, excludes: {imports: ['simple-import']}, 'strip-excludes': false}, function(outputs) { - var vulcanized = outputs[outputPath]; - assert(vulcanized); - var $ = require('whacko').load(vulcanized); - assert.equal(searchAll($, 'link[href="imports/simple-import.html"]').length, 1, 'excluded import not stripped'); - reallyDone(); - }); - }); - - test.skip('Handle tag', function(done) { - var options = {input: 'test/html/base.html', output: outputPath}; - process(options, function(outputs) { - var vulcanized = outputs[outputPath]; - assert(vulcanized); - var $ = require('whacko').load(vulcanized); - var spanHref = $('span').attr('href'); - assert.equal('imports/hello', spanHref, ' accounted for'); - var divHref = $('a').attr('href'); - assert.equal('imports/sub-base/sub-base.html', divHref); - done(); - }); - }); +suite('Vulcan', function() { + var vulcan = require('../lib/vulcan.js'); + var inputPath = path.resolve('test/html/default.html'); + + var preds = dom5.predicates; + var hyd = require('hydrolysis'); + var doc; + + suiteSetup(function(done) { + var loader = new hyd.Loader(); + loader.addResolver(new hyd.FSResolver({})); + vulcan.process(inputPath, loader, function(err, content) { + if (err) { + return done(err); + } + doc = dom5.parse(content); + done(); + }); + }); + + test('imports removed', function() { + var imports = preds.AND( + preds.hasTagName('link'), + preds.hasAttrValue('rel', 'import'), + preds.hasAttr('href') + ); + assert.equal(dom5.queryAll(doc, imports).length, 0); + }); + + test('imports were deduplicated', function() { + assert.equal(dom5.queryAll(doc, preds.hasTagName('dom-module')).length, 1); + }); + + test('svg is nested correctly', function() { + var svg = dom5.query(doc, preds.hasTagName('svg')); + assert.equal(svg.childNodes.filter(dom5.isElement).length, 6); + }); + + test('import bodies are in one hidden div', function() { + var hiddenDiv = preds.AND( + preds.hasTagName('div'), + preds.hasAttr('hidden'), + preds.hasAttr('by-vulcanize') + ); + assert.equal(dom5.queryAll(doc, hiddenDiv).length, 1); + }); + + test('dom-modules have assetpath', function() { + var assetpath = preds.AND( + preds.hasTagName('dom-module'), + preds.hasAttrValue('assetpath', 'imports/') + ); + assert.ok(dom5.query(doc, assetpath), 'assetpath set'); + }); + + test('output file is forced utf-8', function() { + var meta = preds.AND( + preds.hasTagName('meta'), + preds.hasAttrValue('charset', 'UTF-8') + ); + assert.ok(dom5.query(doc, meta)); + }); + + test.skip('Handle tag', function(done) { + var span = preds.AND( + preds.hasTagName('span'), + preds.hasAttrValue('href', 'imports/hello') + ); + var a = preds.AND( + preds.hasTagName('a'), + preds.hasAttrValue('href', 'imports/sub-base/sub-base.html') + ); + process('test/html/base.html', function(err, output) { + if (err) { + return done(err); + } + assert(output); + var doc = dom5.parse(output); + var spanHref = dom5.query(doc, span); + assert.ok(spanHref, ' accounted for'); + var anchorRef = dom5.query(doc, a); + assert.ok(a); + done(); + }); + }); }); From 321602805bffb9508cebfdca13bb5639266a21de Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Wed, 1 Apr 2015 15:25:11 -0700 Subject: [PATCH 0249/1006] cleaner test output --- test/test.js | 76 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 56 insertions(+), 20 deletions(-) diff --git a/test/test.js b/test/test.js index 2a8e98579..c7d1616f2 100644 --- a/test/test.js +++ b/test/test.js @@ -209,7 +209,7 @@ suite('Path Resolver', function() { assert.equal(actual, expected, 'relative'); }); - test.skip('Resolve Paths with ', function() { + test('Resolve Paths with ', function() { var htmlBase = [ '', '', @@ -235,6 +235,7 @@ suite('Path Resolver', function() { ].join('\n'); var ast = parse(htmlBase); + pathresolver.acid(ast, inputPath); pathresolver.resolvePaths(ast, inputPath, outputPath); var actual = serialize(ast); @@ -266,51 +267,82 @@ suite('Vulcan', function() { var hyd = require('hydrolysis'); var doc; - suiteSetup(function(done) { + function process(inputPath, cb) { var loader = new hyd.Loader(); loader.addResolver(new hyd.FSResolver({})); vulcan.process(inputPath, loader, function(err, content) { if (err) { - return done(err); + return cb(err); } doc = dom5.parse(content); - done(); + cb(null, doc); }); - }); + } - test('imports removed', function() { + test('imports removed', function(done) { var imports = preds.AND( preds.hasTagName('link'), preds.hasAttrValue('rel', 'import'), preds.hasAttr('href') ); - assert.equal(dom5.queryAll(doc, imports).length, 0); + process(inputPath, function(err, doc) { + if (err) { + return done(err); + } + assert.equal(dom5.queryAll(doc, imports).length, 0); + done(); + }); }); test('imports were deduplicated', function() { - assert.equal(dom5.queryAll(doc, preds.hasTagName('dom-module')).length, 1); + process(inputPath, function(err, doc) { + if (err) { + return done(err); + } + assert.equal(dom5.queryAll(doc, preds.hasTagName('dom-module')).length, 1); + done(); + }); }); - test('svg is nested correctly', function() { - var svg = dom5.query(doc, preds.hasTagName('svg')); - assert.equal(svg.childNodes.filter(dom5.isElement).length, 6); + test('svg is nested correctly', function(done) { + process(inputPath, function(err, doc) { + if (err) { + return done(err); + } + var svg = dom5.query(doc, preds.hasTagName('svg')); + assert.equal(svg.childNodes.filter(dom5.isElement).length, 6); + done(); + }); }); - test('import bodies are in one hidden div', function() { + test('import bodies are in one hidden div', function(done) { var hiddenDiv = preds.AND( preds.hasTagName('div'), preds.hasAttr('hidden'), preds.hasAttr('by-vulcanize') ); - assert.equal(dom5.queryAll(doc, hiddenDiv).length, 1); + + process(inputPath, function(err, doc) { + if (err) { + return done(err); + } + assert.equal(dom5.queryAll(doc, hiddenDiv).length, 1); + done(); + }); }); - test('dom-modules have assetpath', function() { + test('dom-modules have assetpath', function(done) { var assetpath = preds.AND( preds.hasTagName('dom-module'), preds.hasAttrValue('assetpath', 'imports/') ); - assert.ok(dom5.query(doc, assetpath), 'assetpath set'); + process(inputPath, function(err, doc) { + if (err) { + return done(err); + } + assert.ok(dom5.query(doc, assetpath), 'assetpath set'); + done(); + }); }); test('output file is forced utf-8', function() { @@ -318,7 +350,13 @@ suite('Vulcan', function() { preds.hasTagName('meta'), preds.hasAttrValue('charset', 'UTF-8') ); - assert.ok(dom5.query(doc, meta)); + process(inputPath, function(err, doc) { + if (err) { + return done(err); + } + assert.ok(dom5.query(doc, meta)); + done(); + }); }); test.skip('Handle tag', function(done) { @@ -330,14 +368,12 @@ suite('Vulcan', function() { preds.hasTagName('a'), preds.hasAttrValue('href', 'imports/sub-base/sub-base.html') ); - process('test/html/base.html', function(err, output) { + process('test/html/base.html', function(err, doc) { if (err) { return done(err); } - assert(output); - var doc = dom5.parse(output); var spanHref = dom5.query(doc, span); - assert.ok(spanHref, ' accounted for'); + assert.ok(spanHref); var anchorRef = dom5.query(doc, a); assert.ok(a); done(); From 77110084979511e02bf2cb1b8cab393bfcbc85a0 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Wed, 1 Apr 2015 15:25:17 -0700 Subject: [PATCH 0250/1006] Support in imports and main document Move bodyContent array to a disconnected node that can have path resolving applied Add `pathResolver.acid` that will remove and adjust urls for a document --- lib/pathresolver.js | 18 +++++++++++++++--- lib/vulcan.js | 40 +++++++++++++++++++++------------------- 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/lib/pathresolver.js b/lib/pathresolver.js index 03254248f..050c36e91 100644 --- a/lib/pathresolver.js +++ b/lib/pathresolver.js @@ -32,13 +32,13 @@ function resolvePaths(importDoc, importUrl, mainDocUrl) { attrValue = dom5.getAttribute(node, attr); if (attrValue && !isTemplatedUrl(attrValue)) { var relUrl; - if (attr !== 'style') { + if (attr === 'style') { + relUrl = rewriteURL(importUrl, mainDocUrl, attrValue); + } else { relUrl = rewriteRelPath(importUrl, mainDocUrl, attrValue); if (attr === 'assetpath') { relUrl += '/'; } - } else { - relUrl = rewriteURL(importUrl, mainDocUrl, attrValue); } dom5.setAttribute(node, attr, relUrl); } @@ -92,6 +92,18 @@ function rewriteURL(importUrl, mainDocUrl, cssText) { }); } +// remove effects of +function acid(doc, docUrl) { + var base = dom5.query(doc, matchers.base); + if (base) { + dom5.remove(base); + var baseUrl = dom5.getAttribute(base, 'href') + '/.index.html'; + var docBaseUrl = url.resolve(docUrl, baseUrl); + resolvePaths(doc, docBaseUrl, docUrl); + } +} + +exports.acid = acid; exports.resolvePaths = resolvePaths; exports.rewriteRelPath = rewriteRelPath; exports.rewriteURL = rewriteURL; diff --git a/lib/vulcan.js b/lib/vulcan.js index ac8d473be..24b8a9d8a 100644 --- a/lib/vulcan.js +++ b/lib/vulcan.js @@ -27,12 +27,19 @@ function reparent(newParent) { }; } -function flatten(tree, bodyContents) { +function replaceWith(parent, node, replacements) { + var idx = parent.childNodes.indexOf(node); + parent.childNodes = parent.childNodes.slice(0, idx). + concat(replacements, parent.childNodes.slice(idx + 1)); +} + +function flatten(tree, bodyFragment) { var doc = tree.html.ast; var imports = tree.imports; var head = dom5.query(doc, matchers.head); var body = dom5.query(doc, matchers.body); var importNodes = tree.html.import; + pathResolver.acid(doc, tree.href); if (imports) { for (var i = 0, im; i < imports.length; i++) { im = imports[i]; @@ -40,7 +47,7 @@ function flatten(tree, bodyContents) { dom5.remove(importNodes[i]); continue; } - var importDoc = flatten(im, bodyContents); + var importDoc = flatten(im, bodyFragment); // rewrite urls pathResolver.resolvePaths(importDoc, im.href, tree.href); var importHead = dom5.query(importDoc, matchers.head); @@ -50,11 +57,13 @@ function flatten(tree, bodyContents) { var importBodyChildren = importBody.childNodes; importHeadChildren.forEach(reparent(head)); // replace link in head with head elements from import - var idx = head.childNodes.indexOf(importNodes[i]); - head.childNodes = head.childNodes.slice(0, idx).concat(importHeadChildren, head.childNodes.slice(idx + 1)); + replaceWith(head, importNodes[i], importHeadChildren); + // adjust previous import body urls + pathResolver.resolvePaths(bodyFragment, im.href, tree.href); // defer body children to be inlined in-order if (importBodyChildren.length) { - bodyContents.push(importBodyChildren); + importBodyChildren.forEach(reparent(bodyFragment)); + bodyFragment.childNodes = bodyFragment.childNodes.concat(importBodyChildren); } } } @@ -64,21 +73,14 @@ function flatten(tree, bodyContents) { function process(target, loader, cb) { var analyzer = new hyd.Analyzer(true, loader); analyzer.metadataTree(target).then(function(tree) { - // rewrite urls in main doc to remove - var bodyContents = []; - var flatDoc = flatten(tree, bodyContents); + // hide bodies of imports from rendering + var bodyFragment = dom5.constructors.element('div'); + dom5.setAttribute(bodyFragment, 'hidden', ''); + dom5.setAttribute(bodyFragment, 'by-vulcanize', ''); + var flatDoc = flatten(tree, bodyFragment); var body = dom5.query(flatDoc, matchers.body); - var reduced = bodyContents.reduce(function(a, b) { - return a.concat(b); - }, []); - if (reduced.length) { - // hide bodies of imports from rendering - var hiddenDiv = dom5.constructors.element('div'); - dom5.setAttribute(hiddenDiv, 'hidden', ''); - dom5.setAttribute(hiddenDiv, 'by-vulcanize', ''); - reduced.forEach(reparent(hiddenDiv)); - hiddenDiv.childNodes = reduced; - dom5.insertBefore(body, body.childNodes[0], hiddenDiv); + if (bodyFragment.childNodes.length) { + dom5.insertBefore(body, body.childNodes[0], bodyFragment); } // make sure there's a in the page to force UTF-8 var meta = dom5.query(flatDoc, matchers.meta); From 1d4469e8346b8d638b503f9954451779efb6d77e Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Wed, 1 Apr 2015 15:27:50 -0700 Subject: [PATCH 0251/1006] renable base tests --- test/test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test.js b/test/test.js index c7d1616f2..9b9863264 100644 --- a/test/test.js +++ b/test/test.js @@ -359,7 +359,7 @@ suite('Vulcan', function() { }); }); - test.skip('Handle tag', function(done) { + test('Handle tag', function(done) { var span = preds.AND( preds.hasTagName('span'), preds.hasAttrValue('href', 'imports/hello') From a9d571724dc7cb1521fad22b6dadfab09a82de2f Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Fri, 3 Apr 2015 14:55:16 -0700 Subject: [PATCH 0252/1006] Use a given path as webroot - Add back option parser - Add abspath tests - Delete unused tests and commentmap --- bin/vulcanize | 68 ++++++++++++++++++++--- lib/commentmap.js | 40 -------------- lib/pathresolver.js | 7 +++ lib/vulcan.js | 7 +++ package.json | 6 +- test/broken_config.json | 3 - test/config.json | 6 -- test/html/broken-js.html | 12 ---- test/html/comments.html | 40 -------------- test/test.js | 116 ++++++++++++++++----------------------- 10 files changed, 125 insertions(+), 180 deletions(-) delete mode 100644 lib/commentmap.js delete mode 100644 test/broken_config.json delete mode 100644 test/config.json delete mode 100644 test/html/broken-js.html delete mode 100644 test/html/comments.html diff --git a/bin/vulcanize b/bin/vulcanize index c52841fb7..d1a95f69d 100755 --- a/bin/vulcanize +++ b/bin/vulcanize @@ -14,14 +14,18 @@ var hyd = require('hydrolysis'); var vulcan = require('../lib/vulcan'); - -var target = process.argv[2]; +var nopt = require('nopt'); var help = [ 'vulcanize: Reduce an HTML file and its dependent HTML Imports into one file', '', 'Usage:', ' vulcanize ', + '', + 'Options:', + ' -h: print this message', + ' -v: print version number', + ' -p : use as the "webserver root", make all adjusted urls absolute', 'Examples:', ' The command', '', @@ -36,14 +40,64 @@ var help = [ ' will inline the HTML Imports of `target.html` and print the result to build.html.' ].join('\n'); -if (!target) { - console.error(help); - process.exit(1); +var args = nopt( + { + help: Boolean, + version: Boolean, + abspath: String + }, + { + '-h': ['--help'], + '-v': ['--version'], + '-p': ['--abspath'] + } +); + +var target = args.argv.remain[0]; + +function printHelp() { + console.log(help); } -var loader = new hyd.Loader(); -loader.addResolver(new hyd.FSResolver({})); +var pkg = require('../package.json'); +function printVersion() { + console.log('vulcanize:', pkg.version); +} + +if (args.version) { + printVersion(); + process.exit(0); +} +if (args.help || !target) { + printHelp(); + process.exit(0); +} + +if (args['update-notifier'] !== false) { + (function() { + try { + require('update-notifier')({ + pkg: pkg + }).notify(); + } catch(_) {} + })(); +} + +var abspath = args.abspath; + +var options = {}; + +if (abspath) { + var path = require('path'); + options.root = path.resolve(abspath); + options.basePath = '/'; + target = path.join('/', target); + vulcan.setOptions({abspath: true}); +} + +var loader = new hyd.Loader(); +loader.addResolver(new hyd.FSResolver(options)); vulcan.process(target, loader, function(err, content) { if (err) { diff --git a/lib/commentmap.js b/lib/commentmap.js deleted file mode 100644 index 68831b332..000000000 --- a/lib/commentmap.js +++ /dev/null @@ -1,40 +0,0 @@ -/** - * @license - * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. - * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt - * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt - * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt - * Code distributed by Google as part of the polymer project is also - * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt - */ - -// jshint node: true - -function CommentMap() { - this.commentMap = Object.create(null); -} - -CommentMap.prototype = { - has: function(comment) { - var c = this.normalize(comment); - return !!this.commentMap[c]; - }, - set: function(comment) { - var c = this.normalize(comment); - this.commentMap[c] = 1; - }, - normalize: function (comment) { - var c = comment; - // remove leading slashes - c = c.replace(/^\/*/, ''); - // remove leading stars - c = c.replace(/^\s*[*]*/gm, ''); - // remove trailing stars and slash - c = c.replace(/[*]*\s*\/?$/, ''); - // remove all whitespace - c = c.replace(/\s/g, ''); - return c; - } -}; - -module.exports = CommentMap; diff --git a/lib/pathresolver.js b/lib/pathresolver.js index 050c36e91..d5bf17bed 100644 --- a/lib/pathresolver.js +++ b/lib/pathresolver.js @@ -71,6 +71,9 @@ function rewriteRelPath(importUrl, mainDocUrl, relUrl) { return relUrl; } var absUrl = url.resolve(importUrl, relUrl); + if (options.abspath) { + return url.resolve('/', absUrl); + } var parsedFrom = url.parse(mainDocUrl); var parsedTo = url.parse(absUrl); if (parsedFrom.protocol === parsedTo.protocol && parsedFrom.host === parsedTo.host) { @@ -103,6 +106,10 @@ function acid(doc, docUrl) { } } +var options = {}; +exports.setOptions = function(opts) { + options = opts; +}; exports.acid = acid; exports.resolvePaths = resolvePaths; exports.rewriteRelPath = rewriteRelPath; diff --git a/lib/vulcan.js b/lib/vulcan.js index 24b8a9d8a..93f7ff488 100644 --- a/lib/vulcan.js +++ b/lib/vulcan.js @@ -70,6 +70,12 @@ function flatten(tree, bodyFragment) { return doc; } +var options; +function setOptions(opts) { + options = opts; + pathResolver.setOptions(opts); +} + function process(target, loader, cb) { var analyzer = new hyd.Analyzer(true, loader); analyzer.metadataTree(target).then(function(tree) { @@ -96,5 +102,6 @@ function process(target, loader, cb) { } module.exports = { + setOptions: setOptions, process: process }; diff --git a/package.json b/package.json index fe47ab4f5..489a4ca86 100644 --- a/package.json +++ b/package.json @@ -1,14 +1,14 @@ { "name": "vulcanize", - "version": "0.7.9", + "version": "1.0.0", "description": "Process Web Components into one output file", "main": "lib/vulcan.js", "bin": { "vulcanize": "bin/vulcanize" }, "dependencies": { - "dom5": "^1.0.0", - "hydrolysis": "^1.0.0", + "dom5": "^1.0.1", + "hydrolysis": "^1.0.2", "nopt": "^3.0.1" }, "devDependencies": { diff --git a/test/broken_config.json b/test/broken_config.json deleted file mode 100644 index b6d570533..000000000 --- a/test/broken_config.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - input: "index.html", -} diff --git a/test/config.json b/test/config.json deleted file mode 100644 index be45e9a58..000000000 --- a/test/config.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "csp": true, - "excludes": { - "imports": [".*"] - } -} diff --git a/test/html/broken-js.html b/test/html/broken-js.html deleted file mode 100644 index c6fcd02f9..000000000 --- a/test/html/broken-js.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - diff --git a/test/html/comments.html b/test/html/comments.html deleted file mode 100644 index 3e70e572c..000000000 --- a/test/html/comments.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - Commented - - - - - - - - - - - - - diff --git a/test/test.js b/test/test.js index 9b9863264..01d0ce55e 100644 --- a/test/test.js +++ b/test/test.js @@ -70,65 +70,6 @@ suite('constants', function() { assert('foo[[bar]]baz'.match(tmpl), 'square infix'); assert('[[]]'.match(tmpl), 'empty square'); }); - - }); - -}); - -suite('CommentMap', function() { - var CommentMap = require('../lib/commentmap.js'); - - suite('Normalize', function() { - test('whitespace', function() { - var c = new CommentMap(); - var s = [ - 'Hi', - 'There' - ].join('\n'); - var e = 'HiThere'; - - assert.equal(c.normalize(s), e); - }); - - test('single comment', function() { - var c = new CommentMap(); - var s = '// foo'; - var e = 'foo'; - - assert.equal(c.normalize(s), e); - }); - - test('multiline comment', function() { - var c = new CommentMap(); - var s = [ - '/**', - ' * foo', - ' */' - ].join('\n'); - var e = 'foo'; - - assert.equal(c.normalize(s), e); - }); - }); - - suite('Set and Has', function() { - - test('Plain', function() { - var c = new CommentMap(); - var s = 'Test'; - - c.set(s); - assert.ok(c.has(s)); - }); - - test('Strip Comments', function() { - var c = new CommentMap(); - var m = '/** foo */'; - c.set(m); - var s = '// foo'; - assert.ok(c.has(s)); - }); - }); }); @@ -166,15 +107,23 @@ suite('Path Resolver', function() { assert.equal(actual, expected); }); + function testPath(val, expected, msg) { + var actual = pathresolver.rewriteRelPath(inputPath, outputPath, val); + assert.equal(actual, expected, msg); + } + test('Rewrite Paths', function() { - function testPath(val, expected, abs, msg) { - var actual = pathresolver.rewriteRelPath(inputPath, outputPath, val); - assert.equal(actual, expected, msg); - } - - testPath('biz.jpg', 'my-element/biz.jpg', null, 'local'); - testPath('http://foo/biz.jpg', 'http://foo/biz.jpg', null, 'remote'); - testPath('#foo', '#foo', null, 'hash'); + testPath('biz.jpg', 'my-element/biz.jpg', 'local'); + testPath('http://foo/biz.jpg', 'http://foo/biz.jpg', 'remote'); + testPath('#foo', '#foo', 'hash'); + }); + + test('Rewrite Paths with absolute paths', function() { + pathresolver.setOptions({abspath: true}); + testPath('biz.jpg', '/foo/bar/my-element/biz.jpg', 'local'); + testPath('http://foo/biz.jpg', 'http://foo/biz.jpg', 'local'); + testPath('#foo', '#foo', 'hash'); + pathresolver.setOptions({}); }); test('Resolve Paths', function() { @@ -267,9 +216,10 @@ suite('Vulcan', function() { var hyd = require('hydrolysis'); var doc; - function process(inputPath, cb) { + function process(inputPath, cb, loaderOptions) { + var options = loaderOptions || {}; var loader = new hyd.Loader(); - loader.addResolver(new hyd.FSResolver({})); + loader.addResolver(new hyd.FSResolver(options)); vulcan.process(inputPath, loader, function(err, content) { if (err) { return cb(err); @@ -380,4 +330,32 @@ suite('Vulcan', function() { }); }); + test('Output with Absolute paths with abspath', function(done) { + var root = path.resolve(inputPath, '../..'); + var target = '/html/default.html'; + vulcan.setOptions({abspath: true}); + var options = { + basePath: '/', + root: root + }; + var domModule = preds.AND( + preds.hasTagName('dom-module'), + preds.hasAttrValue('assetpath', '/html/imports/') + ); + var stylesheet = preds.AND( + preds.hasTagName('link'), + preds.hasAttrValue('rel', 'stylesheet'), + preds.hasAttrValue('href', '/html/imports/simple-style.css') + ); + var callback = function(err, doc) { + if (err) { + return done(err); + } + assert.ok(dom5.query(doc, domModule)); + assert.ok(dom5.query(doc, stylesheet)); + done(); + }; + process(target, callback, options); + }); + }); From 5a3737c50b29a57d3f1925b2c0382f532e4f2b7f Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Fri, 3 Apr 2015 17:31:56 -0700 Subject: [PATCH 0253/1006] wip for exclude --- bin/vulcanize | 17 +++++++- lib/optparser.js | 104 ----------------------------------------------- 2 files changed, 16 insertions(+), 105 deletions(-) delete mode 100644 lib/optparser.js diff --git a/bin/vulcanize b/bin/vulcanize index d1a95f69d..8a7f91f86 100755 --- a/bin/vulcanize +++ b/bin/vulcanize @@ -26,6 +26,7 @@ var help = [ ' -h: print this message', ' -v: print version number', ' -p : use as the "webserver root", make all adjusted urls absolute', + ' --exclude : exclude a subpath from root. Use multiple times to exclude multiple paths.', 'Examples:', ' The command', '', @@ -44,7 +45,8 @@ var args = nopt( { help: Boolean, version: Boolean, - abspath: String + abspath: String, + exclude: [String, Array] }, { '-h': ['--help'], @@ -96,9 +98,22 @@ if (abspath) { vulcan.setOptions({abspath: true}); } +// escape a string to be used in new RegExp +function escapeForRegExp(str) { + return str.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); +} + var loader = new hyd.Loader(); loader.addResolver(new hyd.FSResolver(options)); +if (args.exclude) { + args.exclude.forEach(function(ex) { + var excludeRegexp = escapeForRegExp(ex); + var noopResolver = new hyd.NoopResolver(excludeRegexp); + loader.addResolver(noopResolver); + }); +} + vulcan.process(target, loader, function(err, content) { if (err) { console.error(err); diff --git a/lib/optparser.js b/lib/optparser.js deleted file mode 100644 index 99502d555..000000000 --- a/lib/optparser.js +++ /dev/null @@ -1,104 +0,0 @@ -/** - * @license - * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. - * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt - * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt - * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt - * Code distributed by Google as part of the polymer project is also - * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt - */ - -var fs = require('fs'); -var path = require('path'); - -var CONSTANTS = require('./constants.js'); -var ABS_URL = CONSTANTS.ABS_URL; -var REMOTE_ABS_URL = CONSTANTS.REMOTE_ABS_URL; -var DEFAULT = 'vulcanized.html'; - -// validate options with boolean return -function processOptions(options, callback) { - var config = {}; - var excludes = { - imports: [], - scripts: [], - styles: [] - }; - - options = options || Object.create(null); - - if (options.config) { - var configBlob; - try { - // TODO(dfreedm): Make this async - configBlob = fs.readFileSync(options.config, 'utf8'); - } catch(e) { - return callback('Config file not found!'); - } - try { - config = JSON.parse(configBlob); - } catch(e) { - return callback('Malformed config JSON!'); - } - } - - options.input = options.input || config.input; - if (!options.input && !options.inputSrc) { - return callback('No input file or source string given!'); - } - - options.excludes = options.excludes || config.excludes; - if (options.excludes) { - var e = options.excludes; - try { - if (e.imports) { - e.imports.forEach(function(r) { - excludes.imports.push(new RegExp(r)); - }); - } - if (e.scripts) { - e.scripts.forEach(function(r) { - excludes.scripts.push(new RegExp(r)); - }); - } - if (e.styles) { - e.styles.forEach(function(r) { - excludes.styles.push(new RegExp(r)); - }); - } - } catch(_) { - return callback('Malformed import exclude config'); - } - } - - options.output = options.output || config.output; - if (!options.output) { - options.output = path.resolve(path.dirname(options.input), DEFAULT); - } - options.outputDir = path.dirname(options.output); - - options.csp = options.csp || config.csp; - if (options.csp) { - options.csp = options.output.replace(/\.html$/, '.js'); - } - - options.abspath = options.abspath || config.abspath; - if (options.abspath) { - options.abspath = path.resolve(options.abspath); - excludes.imports.push(REMOTE_ABS_URL); - excludes.scripts.push(REMOTE_ABS_URL); - excludes.styles.push(REMOTE_ABS_URL); - } else { - excludes.imports.push(ABS_URL); - excludes.scripts.push(ABS_URL); - excludes.styles.push(ABS_URL); - } - - options.excludes = excludes; - - options.keepExcludes = options['strip-excludes'] === false || config['strip-excludes'] === false; - - callback(null, options); -} - -exports.processOptions = processOptions; From 03866b7e4834ca2d89be8d376ff2f6249ef44179 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Mon, 6 Apr 2015 16:20:27 -0700 Subject: [PATCH 0254/1006] Move option processing into lib/vulcan Loader is handled by lib/vulcan, or supplied in options. bin/vulcanize now just forwards options (and changes excludes to regexes). Fix tests for new option parsing --- bin/vulcanize | 42 ++++++++------------------- lib/pathresolver.js | 8 ++++-- lib/vulcan.js | 69 +++++++++++++++++++++++++++++++++++++++------ test/test.js | 19 +++++++------ 4 files changed, 88 insertions(+), 50 deletions(-) diff --git a/bin/vulcanize b/bin/vulcanize index 8a7f91f86..8d58b5d53 100755 --- a/bin/vulcanize +++ b/bin/vulcanize @@ -12,9 +12,8 @@ // jshint node: true 'use strict'; -var hyd = require('hydrolysis'); -var vulcan = require('../lib/vulcan'); var nopt = require('nopt'); +var vulcan = require('../lib/vulcan'); var help = [ 'vulcanize: Reduce an HTML file and its dependent HTML Imports into one file', @@ -26,7 +25,8 @@ var help = [ ' -h: print this message', ' -v: print version number', ' -p : use as the "webserver root", make all adjusted urls absolute', - ' --exclude : exclude a subpath from root. Use multiple times to exclude multiple paths.', + ' --exclude : exclude a subpath from root. Use multiple times to exclude multiple paths. Tags to excluded paths are kept.', + ' --strip-excludes: Remove tags to external resources.', 'Examples:', ' The command', '', @@ -46,7 +46,8 @@ var args = nopt( help: Boolean, version: Boolean, abspath: String, - exclude: [String, Array] + exclude: [String, Array], + 'strip-excludes': Boolean }, { '-h': ['--help'], @@ -86,35 +87,16 @@ if (args['update-notifier'] !== false) { })(); } -var abspath = args.abspath; - -var options = {}; - -if (abspath) { - var path = require('path'); - options.root = path.resolve(abspath); - options.basePath = '/'; - target = path.join('/', target); - vulcan.setOptions({abspath: true}); -} - -// escape a string to be used in new RegExp -function escapeForRegExp(str) { - return str.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); +// escape a regex string and return a new RegExp +function stringToRegExp(str) { + return new RegExp(str.replace(/[-\/\\*+?.()|[\]{}]/g, '\\$&')); } -var loader = new hyd.Loader(); -loader.addResolver(new hyd.FSResolver(options)); - -if (args.exclude) { - args.exclude.forEach(function(ex) { - var excludeRegexp = escapeForRegExp(ex); - var noopResolver = new hyd.NoopResolver(excludeRegexp); - loader.addResolver(noopResolver); - }); -} +args.excludes = args.exclude ? args.exclude.map(stringToRegExp) : []; +args.stripExcludes = args['strip-excludes']; -vulcan.process(target, loader, function(err, content) { +vulcan.setOptions(args); +vulcan.process(target, function(err, content) { if (err) { console.error(err); console.error(err.stack); diff --git a/lib/pathresolver.js b/lib/pathresolver.js index d5bf17bed..d5e6b62e5 100644 --- a/lib/pathresolver.js +++ b/lib/pathresolver.js @@ -17,6 +17,8 @@ var dom5 = require('dom5'); var matchers = require('./matchers'); var constants = require('./constants'); +var options; + function isTemplatedUrl(href) { return href.search(constants.URL_TEMPLATE) >= 0; } @@ -106,10 +108,12 @@ function acid(doc, docUrl) { } } -var options = {}; exports.setOptions = function(opts) { - options = opts; + options = { + abspath: Boolean(opts.abspath) + }; }; + exports.acid = acid; exports.resolvePaths = resolvePaths; exports.rewriteRelPath = rewriteRelPath; diff --git a/lib/vulcan.js b/lib/vulcan.js index 93f7ff488..520275009 100644 --- a/lib/vulcan.js +++ b/lib/vulcan.js @@ -11,14 +11,17 @@ // jshint node: true 'use strict'; +var path = require('path'); var hyd = require('hydrolysis'); var dom5 = require('dom5'); var constants = require('./constants'); var matchers = require('./matchers'); var pathResolver = require('./pathresolver'); -function isUniqueImport(importNode) { - return Boolean(importNode.href); +var options; + +function isDuplicateImport(importMeta) { + return !Boolean(importMeta.href); } function reparent(newParent) { @@ -27,6 +30,16 @@ function reparent(newParent) { }; } +function isExcludedImport(importMeta) { + if (!options.excludes) { + return false; + } + var href = importMeta.href; + return options.excludes.some(function(r) { + return r.test(importMeta.href); + }); +} + function replaceWith(parent, node, replacements) { var idx = parent.childNodes.indexOf(node); parent.childNodes = parent.childNodes.slice(0, idx). @@ -43,10 +56,16 @@ function flatten(tree, bodyFragment) { if (imports) { for (var i = 0, im; i < imports.length; i++) { im = imports[i]; - if (!isUniqueImport(im)) { + if (isDuplicateImport(im)) { dom5.remove(importNodes[i]); continue; } + if (isExcludedImport(im)) { + if (options.stripExcludes) { + dom5.remove(importNodes[i]); + } + continue; + } var importDoc = flatten(im, bodyFragment); // rewrite urls pathResolver.resolvePaths(importDoc, im.href, tree.href); @@ -70,14 +89,36 @@ function flatten(tree, bodyFragment) { return doc; } -var options; function setOptions(opts) { - options = opts; pathResolver.setOptions(opts); + options = opts; + if (!options.loader) { + var loader = new hyd.Loader(); + var fsOptions = {}; + if (options.abspath) { + fsOptions.root = path.resolve(options.abspath); + fsOptions.basePath = '/'; + } + loader.addResolver(new hyd.FSResolver(fsOptions)); + if (options.excludes) { + options.excludes.forEach(function(r) { + loader.addResolver(new hyd.NoopResolver(r)); + }); + } + options.loader = loader; + } +} + +function prepend(parent, node) { + if (parent.childNodes.length) { + dom5.insertBefore(parent, parent.childNodes[0], node); + } else { + dom5.append(parent, node); + } } -function process(target, loader, cb) { - var analyzer = new hyd.Analyzer(true, loader); +function _process(target, cb) { + var analyzer = new hyd.Analyzer(true, options.loader); analyzer.metadataTree(target).then(function(tree) { // hide bodies of imports from rendering var bodyFragment = dom5.constructors.element('div'); @@ -86,7 +127,7 @@ function process(target, loader, cb) { var flatDoc = flatten(tree, bodyFragment); var body = dom5.query(flatDoc, matchers.body); if (bodyFragment.childNodes.length) { - dom5.insertBefore(body, body.childNodes[0], bodyFragment); + prepend(body, bodyFragment); } // make sure there's a in the page to force UTF-8 var meta = dom5.query(flatDoc, matchers.meta); @@ -94,13 +135,23 @@ function process(target, loader, cb) { meta = dom5.constructors.element('meta'); dom5.setAttribute(meta, 'charset', 'UTF-8'); var head = dom5.query(flatDoc, matchers.head); - dom5.insertBefore(head, head.childNodes[0], meta); + prepend(head, meta); } var out = dom5.serialize(flatDoc); cb(null, out); }).catch(cb); } +function process(target, cb) { + if (!options) { + setOptions({}); + } + if (options.abspath) { + target = path.resolve('/', target); + } + _process(target, cb); +} + module.exports = { setOptions: setOptions, process: process diff --git a/test/test.js b/test/test.js index 01d0ce55e..5bb40d839 100644 --- a/test/test.js +++ b/test/test.js @@ -78,6 +78,11 @@ suite('Path Resolver', function() { var inputPath = '/foo/bar/my-element/index.html'; var outputPath = '/foo/bar/index.html'; + setup(function() { + pathresolver.setOptions({}); + }); + + test('Rewrite URLs', function() { var css = [ 'x-element {', @@ -123,7 +128,6 @@ suite('Path Resolver', function() { testPath('biz.jpg', '/foo/bar/my-element/biz.jpg', 'local'); testPath('http://foo/biz.jpg', 'http://foo/biz.jpg', 'local'); testPath('#foo', '#foo', 'hash'); - pathresolver.setOptions({}); }); test('Resolve Paths', function() { @@ -216,11 +220,10 @@ suite('Vulcan', function() { var hyd = require('hydrolysis'); var doc; - function process(inputPath, cb, loaderOptions) { - var options = loaderOptions || {}; - var loader = new hyd.Loader(); - loader.addResolver(new hyd.FSResolver(options)); - vulcan.process(inputPath, loader, function(err, content) { + function process(inputPath, cb, vulcanizeOptions) { + var options = vulcanizeOptions || {}; + vulcan.setOptions(options); + vulcan.process(inputPath, function(err, content) { if (err) { return cb(err); } @@ -333,10 +336,8 @@ suite('Vulcan', function() { test('Output with Absolute paths with abspath', function(done) { var root = path.resolve(inputPath, '../..'); var target = '/html/default.html'; - vulcan.setOptions({abspath: true}); var options = { - basePath: '/', - root: root + abspath: root }; var domModule = preds.AND( preds.hasTagName('dom-module'), From d614fef9e3488954826fced73cf8afdc441bb21d Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Mon, 6 Apr 2015 16:39:16 -0700 Subject: [PATCH 0255/1006] make sure we have a clean string when appending --- bin/irving | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/irving b/bin/irving index 7dea9d6fe..a9d10fa33 100755 --- a/bin/irving +++ b/bin/irving @@ -19,7 +19,7 @@ var pred = dom5.predicates; var headMatcher = pred.hasTagName('head'); var bodyMatcher = pred.hasTagName('body'); -var docText; +var docText = ''; process.stdin.setEncoding('utf-8'); process.stdin.on('readable', function() { From 2a26684557c5751d999e057aa7f497f7283acd5e Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Mon, 6 Apr 2015 17:05:03 -0700 Subject: [PATCH 0256/1006] Captialize global options --- lib/pathresolver.js | 6 +++--- lib/vulcan.js | 28 ++++++++++++++-------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/lib/pathresolver.js b/lib/pathresolver.js index d5e6b62e5..470a10f9c 100644 --- a/lib/pathresolver.js +++ b/lib/pathresolver.js @@ -17,7 +17,7 @@ var dom5 = require('dom5'); var matchers = require('./matchers'); var constants = require('./constants'); -var options; +var Options; function isTemplatedUrl(href) { return href.search(constants.URL_TEMPLATE) >= 0; @@ -73,7 +73,7 @@ function rewriteRelPath(importUrl, mainDocUrl, relUrl) { return relUrl; } var absUrl = url.resolve(importUrl, relUrl); - if (options.abspath) { + if (Options.abspath) { return url.resolve('/', absUrl); } var parsedFrom = url.parse(mainDocUrl); @@ -109,7 +109,7 @@ function acid(doc, docUrl) { } exports.setOptions = function(opts) { - options = { + Options = { abspath: Boolean(opts.abspath) }; }; diff --git a/lib/vulcan.js b/lib/vulcan.js index 520275009..750dac695 100644 --- a/lib/vulcan.js +++ b/lib/vulcan.js @@ -18,7 +18,7 @@ var constants = require('./constants'); var matchers = require('./matchers'); var pathResolver = require('./pathresolver'); -var options; +var Options; function isDuplicateImport(importMeta) { return !Boolean(importMeta.href); @@ -31,11 +31,11 @@ function reparent(newParent) { } function isExcludedImport(importMeta) { - if (!options.excludes) { + if (!Options.excludes) { return false; } var href = importMeta.href; - return options.excludes.some(function(r) { + return Options.excludes.some(function(r) { return r.test(importMeta.href); }); } @@ -61,7 +61,7 @@ function flatten(tree, bodyFragment) { continue; } if (isExcludedImport(im)) { - if (options.stripExcludes) { + if (Options.stripExcludes) { dom5.remove(importNodes[i]); } continue; @@ -91,21 +91,21 @@ function flatten(tree, bodyFragment) { function setOptions(opts) { pathResolver.setOptions(opts); - options = opts; - if (!options.loader) { + Options = opts; + if (!Options.loader) { var loader = new hyd.Loader(); var fsOptions = {}; - if (options.abspath) { - fsOptions.root = path.resolve(options.abspath); + if (Options.abspath) { + fsOptions.root = path.resolve(Options.abspath); fsOptions.basePath = '/'; } loader.addResolver(new hyd.FSResolver(fsOptions)); - if (options.excludes) { - options.excludes.forEach(function(r) { + if (Options.excludes) { + Options.excludes.forEach(function(r) { loader.addResolver(new hyd.NoopResolver(r)); }); } - options.loader = loader; + Options.loader = loader; } } @@ -118,7 +118,7 @@ function prepend(parent, node) { } function _process(target, cb) { - var analyzer = new hyd.Analyzer(true, options.loader); + var analyzer = new hyd.Analyzer(true, Options.loader); analyzer.metadataTree(target).then(function(tree) { // hide bodies of imports from rendering var bodyFragment = dom5.constructors.element('div'); @@ -143,10 +143,10 @@ function _process(target, cb) { } function process(target, cb) { - if (!options) { + if (!Options) { setOptions({}); } - if (options.abspath) { + if (Options.abspath) { target = path.resolve('/', target); } _process(target, cb); From 6804599382dbf47809c73d8c1cb865deb48901b0 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Tue, 7 Apr 2015 13:55:18 -0700 Subject: [PATCH 0257/1006] Add tests and docs for excludes and strip-excludes options --- bin/vulcanize | 26 +++-- lib/vulcan.js | 2 +- test/test.js | 258 +++++++++++++++++++++++++++++--------------------- 3 files changed, 172 insertions(+), 114 deletions(-) diff --git a/bin/vulcanize b/bin/vulcanize index 8d58b5d53..758bd5b44 100755 --- a/bin/vulcanize +++ b/bin/vulcanize @@ -22,9 +22,9 @@ var help = [ ' vulcanize ', '', 'Options:', - ' -h: print this message', - ' -v: print version number', - ' -p : use as the "webserver root", make all adjusted urls absolute', + ' -h|--help: print this message', + ' -v|--version: print version number', + ' -p |--abspath : use as the "webserver root", make all adjusted urls absolute', ' --exclude : exclude a subpath from root. Use multiple times to exclude multiple paths. Tags to excluded paths are kept.', ' --strip-excludes: Remove tags to external resources.', 'Examples:', @@ -34,18 +34,32 @@ var help = [ '', ' will inline the HTML Imports of `target.html` and print the resulting HTML to standard output.', '', - ' The command', + ' The command', '', ' vulcanize target.html > build.html', '', - ' will inline the HTML Imports of `target.html` and print the result to build.html.' + ' will inline the HTML Imports of `target.html` and print the result to build.html.', + '', + ' The command', + '', + ' vulcanize -p "path/to/target/" /target.html', + '', + ' will inline the HTML Imports of `target.html`, treat `path/to/target/` as the webroot of target.html, and make all urls absolute to the provided webroot.', + '', + ' The command', + '', + ' vulcanize --exclude "path/to/target/subpath/" --exclude "path/to/target/subpath2/" target.html', + '', + ' will inline the HTML Imports of `target.html` that are not in the directory `path/to/target/subpath` nor `path/to/target/subpath2`.', + '', + ' If the `--strip-excludes` flag is used, the HTML Import `` tags that point to resources in `path/totarget/subpath` and `path/to/target/subpath2/` will also be removed.' ].join('\n'); var args = nopt( { help: Boolean, version: Boolean, - abspath: String, + abspath: require('path'), exclude: [String, Array], 'strip-excludes': Boolean }, diff --git a/lib/vulcan.js b/lib/vulcan.js index 750dac695..0dbb89860 100644 --- a/lib/vulcan.js +++ b/lib/vulcan.js @@ -36,7 +36,7 @@ function isExcludedImport(importMeta) { } var href = importMeta.href; return Options.excludes.some(function(r) { - return r.test(importMeta.href); + return r.test(href); }); } diff --git a/test/test.js b/test/test.js index 5bb40d839..482bbd197 100644 --- a/test/test.js +++ b/test/test.js @@ -124,7 +124,9 @@ suite('Path Resolver', function() { }); test('Rewrite Paths with absolute paths', function() { - pathresolver.setOptions({abspath: true}); + pathresolver.setOptions({ + abspath: true + }); testPath('biz.jpg', '/foo/bar/my-element/biz.jpg', 'local'); testPath('http://foo/biz.jpg', 'http://foo/biz.jpg', 'local'); testPath('#foo', '#foo', 'hash'); @@ -232,131 +234,173 @@ suite('Vulcan', function() { }); } - test('imports removed', function(done) { - var imports = preds.AND( - preds.hasTagName('link'), - preds.hasAttrValue('rel', 'import'), - preds.hasAttr('href') - ); - process(inputPath, function(err, doc) { - if (err) { - return done(err); - } - assert.equal(dom5.queryAll(doc, imports).length, 0); - done(); + suite('Default Options', function() { + test('imports removed', function(done) { + var imports = preds.AND( + preds.hasTagName('link'), + preds.hasAttrValue('rel', 'import'), + preds.hasAttr('href') + ); + process(inputPath, function(err, doc) { + if (err) { + return done(err); + } + assert.equal(dom5.queryAll(doc, imports).length, 0); + done(); + }); }); - }); - test('imports were deduplicated', function() { - process(inputPath, function(err, doc) { - if (err) { - return done(err); - } - assert.equal(dom5.queryAll(doc, preds.hasTagName('dom-module')).length, 1); - done(); + test('imports were deduplicated', function() { + process(inputPath, function(err, doc) { + if (err) { + return done(err); + } + assert.equal(dom5.queryAll(doc, preds.hasTagName('dom-module')).length, 1); + done(); + }); }); - }); - test('svg is nested correctly', function(done) { - process(inputPath, function(err, doc) { - if (err) { - return done(err); - } - var svg = dom5.query(doc, preds.hasTagName('svg')); - assert.equal(svg.childNodes.filter(dom5.isElement).length, 6); - done(); + test('svg is nested correctly', function(done) { + process(inputPath, function(err, doc) { + if (err) { + return done(err); + } + var svg = dom5.query(doc, preds.hasTagName('svg')); + assert.equal(svg.childNodes.filter(dom5.isElement).length, 6); + done(); + }); }); - }); - test('import bodies are in one hidden div', function(done) { - var hiddenDiv = preds.AND( - preds.hasTagName('div'), - preds.hasAttr('hidden'), - preds.hasAttr('by-vulcanize') - ); + test('import bodies are in one hidden div', function(done) { + var hiddenDiv = preds.AND( + preds.hasTagName('div'), + preds.hasAttr('hidden'), + preds.hasAttr('by-vulcanize') + ); + + process(inputPath, function(err, doc) { + if (err) { + return done(err); + } + assert.equal(dom5.queryAll(doc, hiddenDiv).length, 1); + done(); + }); + }); - process(inputPath, function(err, doc) { - if (err) { - return done(err); - } - assert.equal(dom5.queryAll(doc, hiddenDiv).length, 1); - done(); + test('dom-modules have assetpath', function(done) { + var assetpath = preds.AND( + preds.hasTagName('dom-module'), + preds.hasAttrValue('assetpath', 'imports/') + ); + process(inputPath, function(err, doc) { + if (err) { + return done(err); + } + assert.ok(dom5.query(doc, assetpath), 'assetpath set'); + done(); + }); }); - }); - test('dom-modules have assetpath', function(done) { - var assetpath = preds.AND( - preds.hasTagName('dom-module'), - preds.hasAttrValue('assetpath', 'imports/') - ); - process(inputPath, function(err, doc) { - if (err) { - return done(err); - } - assert.ok(dom5.query(doc, assetpath), 'assetpath set'); - done(); + test('output file is forced utf-8', function() { + var meta = preds.AND( + preds.hasTagName('meta'), + preds.hasAttrValue('charset', 'UTF-8') + ); + process(inputPath, function(err, doc) { + if (err) { + return done(err); + } + assert.ok(dom5.query(doc, meta)); + done(); + }); }); - }); - test('output file is forced utf-8', function() { - var meta = preds.AND( - preds.hasTagName('meta'), - preds.hasAttrValue('charset', 'UTF-8') - ); - process(inputPath, function(err, doc) { - if (err) { - return done(err); - } - assert.ok(dom5.query(doc, meta)); - done(); + test('Handle tag', function(done) { + var span = preds.AND( + preds.hasTagName('span'), + preds.hasAttrValue('href', 'imports/hello') + ); + var a = preds.AND( + preds.hasTagName('a'), + preds.hasAttrValue('href', 'imports/sub-base/sub-base.html') + ); + process('test/html/base.html', function(err, doc) { + if (err) { + return done(err); + } + var spanHref = dom5.query(doc, span); + assert.ok(spanHref); + var anchorRef = dom5.query(doc, a); + assert.ok(a); + done(); + }); }); }); - test('Handle tag', function(done) { - var span = preds.AND( - preds.hasTagName('span'), - preds.hasAttrValue('href', 'imports/hello') - ); - var a = preds.AND( - preds.hasTagName('a'), - preds.hasAttrValue('href', 'imports/sub-base/sub-base.html') - ); - process('test/html/base.html', function(err, doc) { - if (err) { - return done(err); - } - var spanHref = dom5.query(doc, span); - assert.ok(spanHref); - var anchorRef = dom5.query(doc, a); - assert.ok(a); - done(); + suite('Absolue Paths', function() { + test('Output with Absolute paths with abspath', function(done) { + var root = path.resolve(inputPath, '../..'); + var target = '/html/default.html'; + var options = { + abspath: root + }; + var domModule = preds.AND( + preds.hasTagName('dom-module'), + preds.hasAttrValue('assetpath', '/html/imports/') + ); + var stylesheet = preds.AND( + preds.hasTagName('link'), + preds.hasAttrValue('rel', 'stylesheet'), + preds.hasAttrValue('href', '/html/imports/simple-style.css') + ); + var callback = function(err, doc) { + if (err) { + return done(err); + } + assert.ok(dom5.query(doc, domModule)); + assert.ok(dom5.query(doc, stylesheet)); + done(); + }; + process(target, callback, options); }); }); - test('Output with Absolute paths with abspath', function(done) { - var root = path.resolve(inputPath, '../..'); - var target = '/html/default.html'; - var options = { - abspath: root - }; - var domModule = preds.AND( - preds.hasTagName('dom-module'), - preds.hasAttrValue('assetpath', '/html/imports/') - ); - var stylesheet = preds.AND( + suite('Excludes', function() { + + var excluded = preds.AND( preds.hasTagName('link'), - preds.hasAttrValue('rel', 'stylesheet'), - preds.hasAttrValue('href', '/html/imports/simple-style.css') + preds.hasAttrValue('rel', 'import'), + preds.hasAttrValue('href', 'imports/simple-import.html') ); - var callback = function(err, doc) { - if (err) { - return done(err); - } - assert.ok(dom5.query(doc, domModule)); - assert.ok(dom5.query(doc, stylesheet)); - done(); + + var options = { + excludes: [ + /simple-import\.html$/ + ] }; - process(target, callback, options); - }); + test('Excluded imports are not inlined', function(done) { + var callback = function(err, doc) { + if (err) { + return done(err); + } + var imports = dom5.queryAll(doc, excluded); + assert.ok(imports.length, 1); + done(); + }; + process(inputPath, callback, options); + }); + + test('Excluded imports with "Strip Excludes" are removed', function(done) { + var callback = function(err, doc) { + if (err) { + return done(err); + } + var imports = dom5.queryAll(doc, excluded); + assert.ok(imports.length, 0); + done(); + }; + process(inputPath, callback, options); + }); + }); }); From ebc30ae889bfcc18b59385fac4a7fac5e8f8ad34 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Tue, 7 Apr 2015 14:17:48 -0700 Subject: [PATCH 0258/1006] make casper read stdin from vulcanize --- bin/casper | 52 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/bin/casper b/bin/casper index 9cdcb479d..77f6d0ee8 100755 --- a/bin/casper +++ b/bin/casper @@ -32,26 +32,44 @@ var inlineScriptFinder = pred.AND( ) ); -var target = process.argv[2]; -var outhtml = path.resolve(process.argv[3]); -var outscript = path.resolve(process.argv[4]); +var outhtml = path.resolve(process.argv[2]); +var outscript = path.resolve(process.argv[3]); -var html = fs.readFileSync(target, 'utf-8'); +if (!outhtml) { + console.log('Missing output html file!'); + process.exit(1); +} -var doc = dom5.parse(html); -var head = dom5.query(doc, pred.hasTagName('head')); -var body = dom5.query(doc, pred.hasTagName('body')); -var scripts = dom5.queryAll(doc, inlineScriptFinder); +if (!outscript) { + console.log('Missing output js file!'); + process.exit(1); +} -var contents = []; -scripts.forEach(function(sn) { - dom5.remove(sn); - contents.push(dom5.getTextContent(sn)); +var docText = ''; +process.stdin.setEncoding('utf-8'); +process.stdin.on('readable', function() { + var chunk = process.stdin.read(); + if (chunk !== null) { + docText += chunk; + } }); +process.stdin.on('end', function() { + var doc = dom5.parse(docText); + var head = dom5.query(doc, pred.hasTagName('head')); + var body = dom5.query(doc, pred.hasTagName('body')); + var scripts = dom5.queryAll(doc, inlineScriptFinder); -var newScript = dom5.constructors.element('script'); -dom5.setAttribute(newScript, 'src', path.relative(path.dirname(outhtml), outscript)); -dom5.append(body, newScript); + var contents = []; + scripts.forEach(function(sn) { + dom5.remove(sn); + contents.push(dom5.getTextContent(sn)); + }); + + var newScript = dom5.constructors.element('script'); + dom5.setAttribute(newScript, 'src', path.relative(path.dirname(outhtml), outscript)); + dom5.append(body, newScript); + + fs.writeFileSync(outhtml, dom5.serialize(doc), 'utf-8'); + fs.writeFileSync(outscript, contents.join(';'), 'utf-8'); +}); -fs.writeFileSync(outhtml, dom5.serialize(doc), 'utf-8'); -fs.writeFileSync(outscript, contents.join(';'), 'utf-8'); From 8e2b020e537d41b08991a0e26ea95f84c122d66d Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Tue, 7 Apr 2015 15:38:30 -0700 Subject: [PATCH 0259/1006] Remove newlines when removing imports And scripts in casper --- bin/casper | 10 ++++++++-- lib/vulcan.js | 19 +++++++++++++++++-- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/bin/casper b/bin/casper index 77f6d0ee8..dc6810bfd 100755 --- a/bin/casper +++ b/bin/casper @@ -32,8 +32,8 @@ var inlineScriptFinder = pred.AND( ) ); -var outhtml = path.resolve(process.argv[2]); -var outscript = path.resolve(process.argv[3]); +var outhtml = process.argv[2]; +var outscript = process.argv[3]; if (!outhtml) { console.log('Missing output html file!'); @@ -61,7 +61,13 @@ process.stdin.on('end', function() { var contents = []; scripts.forEach(function(sn) { + var nidx = sn.parentNode.childNodes.indexOf(sn) + 1; + var next = sn.parentNode.childNodes[nidx]; dom5.remove(sn); + // remove newline after script to get rid of nasty whitespace + if (next && dom5.isTextNode(next) && !/\S/.test(dom5.getTextContent(next))) { + dom5.remove(next); + } contents.push(dom5.getTextContent(sn)); }); diff --git a/lib/vulcan.js b/lib/vulcan.js index 0dbb89860..50b0e4b9b 100644 --- a/lib/vulcan.js +++ b/lib/vulcan.js @@ -46,6 +46,21 @@ function replaceWith(parent, node, replacements) { concat(replacements, parent.childNodes.slice(idx + 1)); } +// when removing imports, remove the newline after it as well +function removeImportAndNewline(importNode) { + var parent = importNode.parentNode; + var nextIdx = parent.childNodes.indexOf(importNode) + 1; + var next = parent.childNodes[nextIdx]; + if (next && dom5.isTextNode(next)) { + var content = dom5.getTextContent(next); + // remove next node if it is blank text + if (!/\S/.test(content)) { + dom5.remove(next); + } + } + dom5.remove(importNode); +} + function flatten(tree, bodyFragment) { var doc = tree.html.ast; var imports = tree.imports; @@ -57,12 +72,12 @@ function flatten(tree, bodyFragment) { for (var i = 0, im; i < imports.length; i++) { im = imports[i]; if (isDuplicateImport(im)) { - dom5.remove(importNodes[i]); + removeImportAndNewline(importNodes[i]); continue; } if (isExcludedImport(im)) { if (Options.stripExcludes) { - dom5.remove(importNodes[i]); + removeImportAndNewline(importNodes[i]); } continue; } From 2403a26a48634b8f8971ea1ac60d7f23d6677e33 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Wed, 8 Apr 2015 10:51:27 -0700 Subject: [PATCH 0260/1006] move out casper --- .editorconfig | 19 ++++++++++++ .gitattributes | 1 + bin/casper | 81 -------------------------------------------------- 3 files changed, 20 insertions(+), 81 deletions(-) create mode 100644 .editorconfig create mode 100644 .gitattributes delete mode 100755 bin/casper diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..99b853347 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,19 @@ +# Copyright (c) 2014 The Polymer Project Authors. All rights reserved. +# This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt +# The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt +# The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt +# Code distributed by Google as part of the polymer project is also +# subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt + +# Polymer EditorConfig + +root = true + +[*] +charset = utf-8 +indent_size = 2 +indent_style = space +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false \ No newline at end of file diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..176a458f9 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto diff --git a/bin/casper b/bin/casper deleted file mode 100755 index dc6810bfd..000000000 --- a/bin/casper +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env node -/** - * @license - * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. - * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt - * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt - * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt - * Code distributed by Google as part of the polymer project is also - * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt - */ - -// jshint node: true -'use strict'; - -var path = require('path'); -var fs = require('fs'); - -var dom5 = require('dom5'); -var pred = dom5.predicates; - -var inlineScriptFinder = pred.AND( - pred.hasTagName('script'), - pred.OR( - pred.NOT( - pred.hasAttr('type') - ), - pred.hasAttrValue('type', 'application/javascript'), - pred.hasAttrValue('type', 'text/javascript') - ), - pred.NOT( - pred.hasAttr('src') - ) -); - -var outhtml = process.argv[2]; -var outscript = process.argv[3]; - -if (!outhtml) { - console.log('Missing output html file!'); - process.exit(1); -} - -if (!outscript) { - console.log('Missing output js file!'); - process.exit(1); -} - -var docText = ''; -process.stdin.setEncoding('utf-8'); -process.stdin.on('readable', function() { - var chunk = process.stdin.read(); - if (chunk !== null) { - docText += chunk; - } -}); -process.stdin.on('end', function() { - var doc = dom5.parse(docText); - var head = dom5.query(doc, pred.hasTagName('head')); - var body = dom5.query(doc, pred.hasTagName('body')); - var scripts = dom5.queryAll(doc, inlineScriptFinder); - - var contents = []; - scripts.forEach(function(sn) { - var nidx = sn.parentNode.childNodes.indexOf(sn) + 1; - var next = sn.parentNode.childNodes[nidx]; - dom5.remove(sn); - // remove newline after script to get rid of nasty whitespace - if (next && dom5.isTextNode(next) && !/\S/.test(dom5.getTextContent(next))) { - dom5.remove(next); - } - contents.push(dom5.getTextContent(sn)); - }); - - var newScript = dom5.constructors.element('script'); - dom5.setAttribute(newScript, 'src', path.relative(path.dirname(outhtml), outscript)); - dom5.append(body, newScript); - - fs.writeFileSync(outhtml, dom5.serialize(doc), 'utf-8'); - fs.writeFileSync(outscript, contents.join(';'), 'utf-8'); -}); - From 1cd161f4e6b8fdc4411e51cf6a219c69d188cb69 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Wed, 8 Apr 2015 12:27:28 -0700 Subject: [PATCH 0261/1006] Remove irving Gist: https://gist.github.com/azakus/dfc442589a9bd934070b --- bin/irving | 54 ------------------------------------------------------ 1 file changed, 54 deletions(-) delete mode 100755 bin/irving diff --git a/bin/irving b/bin/irving deleted file mode 100755 index a9d10fa33..000000000 --- a/bin/irving +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env node -/** - * @license - * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. - * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt - * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt - * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt - * Code distributed by Google as part of the polymer project is also - * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt - */ - -// jshint node: true -'use strict'; - -var fs = require('fs'); -var dom5 = require('dom5'); -var pred = dom5.predicates; - -var headMatcher = pred.hasTagName('head'); -var bodyMatcher = pred.hasTagName('body'); - -var docText = ''; - -process.stdin.setEncoding('utf-8'); -process.stdin.on('readable', function() { - var chunk = process.stdin.read(); - if (chunk !== null) { - docText += chunk; - } -}); - -process.stdin.on('end', function() { - var doc = dom5.parse(docText); - - var head = dom5.query(doc, headMatcher); - var body = dom5.query(doc, bodyMatcher); - var html = head.parentNode; - - dom5.remove(head); - dom5.remove(body); - - var reparent = function(node) { - node.parentNode = html; - }; - - var headNodes = head.childNodes; - var bodyNodes = body.childNodes; - - headNodes.forEach(reparent); - bodyNodes.forEach(reparent); - html.childNodes = headNodes.concat(bodyNodes); - - process.stdout.write(dom5.serialize(doc)); -}); From b5ec99abe901bd5d1adaa4fb6109dcde2ca47da2 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Wed, 8 Apr 2015 13:12:13 -0700 Subject: [PATCH 0262/1006] remove bower_components from example folder --- .gitignore | 1 + example/bower.json | 19 + example/bower_components/polymer/.bower.json | 33 - example/bower_components/polymer/PRIMER.md | 1391 ---- example/bower_components/polymer/README.md | 330 - example/bower_components/polymer/bower.json | 24 - example/bower_components/polymer/build.bat | 2 - .../bower_components/polymer/docs/index.html | 48 - .../polymer/explainer/data-bind.png | Bin 34533 -> 0 bytes .../polymer/explainer/data-bind.vsdx | Bin 38379 -> 0 bytes .../polymer/explainer/samples.html | 50 - .../polymer/polymer-micro.html | 35 - .../polymer/polymer-mini.html | 45 - example/bower_components/polymer/polymer.html | 55 - .../polymer/src/expr/focus.html | 22 - .../polymer/src/expr/gestures.html | 1 - .../polymer/src/expr/log.html | 21 - .../polymer/src/expr/polymer-expr.html | 57 - .../polymer/src/expr/sinspect.html | 235 - .../polymer/src/expr/style-auditor.html | 122 - .../polymer/src/expr/x-styling-defaults.html | 61 - .../polymer/src/expr/x-styling.html | 289 - .../src/features/micro/attributes.html | 176 - .../src/features/micro/constructor.html | 74 - .../polymer/src/features/micro/extends.html | 79 - .../polymer/src/features/micro/mixins.html | 40 - .../src/features/micro/properties.html | 96 - .../polymer/src/features/mini/ready.html | 120 - .../polymer/src/features/mini/shadow.html | 41 - .../polymer/src/features/mini/shady.html | 339 - .../polymer/src/features/mini/template.html | 60 - .../src/features/standard/annotations.html | 194 - .../src/features/standard/configure.html | 162 - .../src/features/standard/effects.html | 149 - .../polymer/src/features/standard/events.html | 114 - .../src/features/standard/notify-path.html | 266 - .../src/features/standard/resolveUrl.html | 27 - .../src/features/standard/styling.html | 155 - .../polymer/src/features/standard/utils.html | 139 - .../src/lib/annotations/annotations.html | 273 - .../src/lib/annotations/demo/app-chrome.html | 60 - .../polymer/src/lib/array-observe.html | 115 - .../polymer/src/lib/array-splice.html | 262 - .../polymer/src/lib/async.html | 68 - .../polymer/src/lib/base.html | 117 - .../src/lib/bind/bind-annotations.html | 74 - .../polymer/src/lib/bind/bind-effects.html | 188 - .../polymer/src/lib/bind/bind.html | 218 - .../polymer/src/lib/bind/demo/app-chrome.html | 28 - .../polymer/src/lib/bind/demo/app.html | 29 - .../bind/demo/src/annotations-bind-demo.html | 76 - .../src/lib/bind/demo/src/bind-demo.html | 83 - .../polymer/src/lib/collection.html | 164 - .../polymer/src/lib/css-parse.html | 131 - .../polymer/src/lib/debounce.html | 69 - .../polymer/src/lib/dom-api.html | 393 -- .../polymer/src/lib/dom-module.html | 50 - .../polymer/src/lib/lang.html | 21 - .../polymer/src/lib/module.html | 56 - .../polymer/src/lib/polymer.html | 78 - .../polymer/src/lib/resolve-url.html | 82 - .../polymer/src/lib/settings.html | 48 - .../polymer/src/lib/style-transformer.html | 166 - .../polymer/src/lib/style-util.html | 77 - .../polymer/src/lib/template/templatizer.html | 117 - .../src/lib/template/x-array-selector.html | 94 - .../polymer/src/lib/template/x-autobind.html | 36 - .../polymer/src/lib/template/x-repeat.html | 389 -- .../polymer/src/lib/template/x-template.html | 39 - .../bower_components/polymer/src/polymer.html | 14 - example/bower_components/polymer/wct.conf.js | 3 - .../webcomponentsjs/.bower.json | 24 - .../webcomponentsjs/CustomElements.js | 634 -- .../webcomponentsjs/CustomElements.min.js | 11 - .../webcomponentsjs/HTMLImports.js | 764 -- .../webcomponentsjs/HTMLImports.min.js | 11 - .../webcomponentsjs/README.md | 73 - .../webcomponentsjs/ShadowDOM.js | 4277 ------------ .../webcomponentsjs/ShadowDOM.min.js | 13 - .../webcomponentsjs/bower.json | 14 - .../webcomponentsjs/package.json | 31 - .../webcomponentsjs/webcomponents-lite.js | 1728 ----- .../webcomponentsjs/webcomponents-lite.min.js | 11 - .../webcomponentsjs/webcomponents.js | 6114 ----------------- .../webcomponentsjs/webcomponents.min.js | 14 - 85 files changed, 20 insertions(+), 22389 deletions(-) create mode 100644 example/bower.json delete mode 100644 example/bower_components/polymer/.bower.json delete mode 100644 example/bower_components/polymer/PRIMER.md delete mode 100644 example/bower_components/polymer/README.md delete mode 100644 example/bower_components/polymer/bower.json delete mode 100644 example/bower_components/polymer/build.bat delete mode 100644 example/bower_components/polymer/docs/index.html delete mode 100644 example/bower_components/polymer/explainer/data-bind.png delete mode 100644 example/bower_components/polymer/explainer/data-bind.vsdx delete mode 100644 example/bower_components/polymer/explainer/samples.html delete mode 100644 example/bower_components/polymer/polymer-micro.html delete mode 100644 example/bower_components/polymer/polymer-mini.html delete mode 100644 example/bower_components/polymer/polymer.html delete mode 100644 example/bower_components/polymer/src/expr/focus.html delete mode 100644 example/bower_components/polymer/src/expr/gestures.html delete mode 100644 example/bower_components/polymer/src/expr/log.html delete mode 100644 example/bower_components/polymer/src/expr/polymer-expr.html delete mode 100644 example/bower_components/polymer/src/expr/sinspect.html delete mode 100644 example/bower_components/polymer/src/expr/style-auditor.html delete mode 100644 example/bower_components/polymer/src/expr/x-styling-defaults.html delete mode 100644 example/bower_components/polymer/src/expr/x-styling.html delete mode 100644 example/bower_components/polymer/src/features/micro/attributes.html delete mode 100644 example/bower_components/polymer/src/features/micro/constructor.html delete mode 100644 example/bower_components/polymer/src/features/micro/extends.html delete mode 100644 example/bower_components/polymer/src/features/micro/mixins.html delete mode 100644 example/bower_components/polymer/src/features/micro/properties.html delete mode 100644 example/bower_components/polymer/src/features/mini/ready.html delete mode 100644 example/bower_components/polymer/src/features/mini/shadow.html delete mode 100644 example/bower_components/polymer/src/features/mini/shady.html delete mode 100644 example/bower_components/polymer/src/features/mini/template.html delete mode 100644 example/bower_components/polymer/src/features/standard/annotations.html delete mode 100644 example/bower_components/polymer/src/features/standard/configure.html delete mode 100644 example/bower_components/polymer/src/features/standard/effects.html delete mode 100644 example/bower_components/polymer/src/features/standard/events.html delete mode 100644 example/bower_components/polymer/src/features/standard/notify-path.html delete mode 100644 example/bower_components/polymer/src/features/standard/resolveUrl.html delete mode 100644 example/bower_components/polymer/src/features/standard/styling.html delete mode 100644 example/bower_components/polymer/src/features/standard/utils.html delete mode 100644 example/bower_components/polymer/src/lib/annotations/annotations.html delete mode 100644 example/bower_components/polymer/src/lib/annotations/demo/app-chrome.html delete mode 100644 example/bower_components/polymer/src/lib/array-observe.html delete mode 100644 example/bower_components/polymer/src/lib/array-splice.html delete mode 100644 example/bower_components/polymer/src/lib/async.html delete mode 100644 example/bower_components/polymer/src/lib/base.html delete mode 100644 example/bower_components/polymer/src/lib/bind/bind-annotations.html delete mode 100644 example/bower_components/polymer/src/lib/bind/bind-effects.html delete mode 100644 example/bower_components/polymer/src/lib/bind/bind.html delete mode 100644 example/bower_components/polymer/src/lib/bind/demo/app-chrome.html delete mode 100644 example/bower_components/polymer/src/lib/bind/demo/app.html delete mode 100644 example/bower_components/polymer/src/lib/bind/demo/src/annotations-bind-demo.html delete mode 100644 example/bower_components/polymer/src/lib/bind/demo/src/bind-demo.html delete mode 100644 example/bower_components/polymer/src/lib/collection.html delete mode 100644 example/bower_components/polymer/src/lib/css-parse.html delete mode 100644 example/bower_components/polymer/src/lib/debounce.html delete mode 100644 example/bower_components/polymer/src/lib/dom-api.html delete mode 100644 example/bower_components/polymer/src/lib/dom-module.html delete mode 100644 example/bower_components/polymer/src/lib/lang.html delete mode 100644 example/bower_components/polymer/src/lib/module.html delete mode 100644 example/bower_components/polymer/src/lib/polymer.html delete mode 100644 example/bower_components/polymer/src/lib/resolve-url.html delete mode 100644 example/bower_components/polymer/src/lib/settings.html delete mode 100644 example/bower_components/polymer/src/lib/style-transformer.html delete mode 100644 example/bower_components/polymer/src/lib/style-util.html delete mode 100644 example/bower_components/polymer/src/lib/template/templatizer.html delete mode 100644 example/bower_components/polymer/src/lib/template/x-array-selector.html delete mode 100644 example/bower_components/polymer/src/lib/template/x-autobind.html delete mode 100644 example/bower_components/polymer/src/lib/template/x-repeat.html delete mode 100644 example/bower_components/polymer/src/lib/template/x-template.html delete mode 100644 example/bower_components/polymer/src/polymer.html delete mode 100644 example/bower_components/polymer/wct.conf.js delete mode 100644 example/bower_components/webcomponentsjs/.bower.json delete mode 100644 example/bower_components/webcomponentsjs/CustomElements.js delete mode 100644 example/bower_components/webcomponentsjs/CustomElements.min.js delete mode 100644 example/bower_components/webcomponentsjs/HTMLImports.js delete mode 100644 example/bower_components/webcomponentsjs/HTMLImports.min.js delete mode 100644 example/bower_components/webcomponentsjs/README.md delete mode 100644 example/bower_components/webcomponentsjs/ShadowDOM.js delete mode 100644 example/bower_components/webcomponentsjs/ShadowDOM.min.js delete mode 100644 example/bower_components/webcomponentsjs/bower.json delete mode 100644 example/bower_components/webcomponentsjs/package.json delete mode 100644 example/bower_components/webcomponentsjs/webcomponents-lite.js delete mode 100644 example/bower_components/webcomponentsjs/webcomponents-lite.min.js delete mode 100644 example/bower_components/webcomponentsjs/webcomponents.js delete mode 100644 example/bower_components/webcomponentsjs/webcomponents.min.js diff --git a/.gitignore b/.gitignore index 3c3629e64..2a5e850b4 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ node_modules +example/bower_components diff --git a/example/bower.json b/example/bower.json new file mode 100644 index 000000000..cb7448113 --- /dev/null +++ b/example/bower.json @@ -0,0 +1,19 @@ +{ + "name": "example", + "version": "0.0.0", + "homepage": "https://github.com/Polymer/vulcanize", + "authors": [ + "The Polymer Authors" + ], + "license": "MIT", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ], + "dependencies": { + "polymer": "Polymer/polymer#0.8.0-rc.2" + } +} diff --git a/example/bower_components/polymer/.bower.json b/example/bower_components/polymer/.bower.json deleted file mode 100644 index b8897a65b..000000000 --- a/example/bower_components/polymer/.bower.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "polymer", - "main": [ - "polymer.html" - ], - "license": "http://polymer.github.io/LICENSE.txt", - "ignore": [ - "/.*", - "/test/" - ], - "authors": [ - "The Polymer Authors (http://polymer.github.io/AUTHORS.txt)" - ], - "repository": { - "type": "git", - "url": "https://github.com/Polymer/polymer.git" - }, - "devDependencies": { - "web-component-tester": "*", - "webcomponentsjs": "webcomponents/webcomponentsjs#master" - }, - "private": true, - "homepage": "https://github.com/Polymer/polymer", - "_release": "83b809def6", - "_resolution": { - "type": "branch", - "branch": "0.8-preview", - "commit": "83b809def627c84dc66b5136ea8dcddaa110a661" - }, - "_source": "git://github.com/Polymer/polymer.git", - "_target": "0.8-preview", - "_originalSource": "Polymer/polymer" -} \ No newline at end of file diff --git a/example/bower_components/polymer/PRIMER.md b/example/bower_components/polymer/PRIMER.md deleted file mode 100644 index 364b2217d..000000000 --- a/example/bower_components/polymer/PRIMER.md +++ /dev/null @@ -1,1391 +0,0 @@ -# Polymer 0.8 Primer - -**
Polymer 0.8 and this document are a WORK IN PROGRESS and APIs are subject to change.
** - -Table of Contents: - -* [Feature list](#feature-list) -* [Migration notes](#migration-notes) - -# Feature list - - -Below is a description of the current Polymer features, followed by individual feature guides. - - -Bare-minum Custom Element sugaring - -| Feature | Usage -|---------|------- -| [Custom element constructor](#element-constructor) | Polymer.Class({ … }); -| [Custom element registration](#register-element) | Polymer({ is: ‘...’, … }}; -| [Bespoke constructor support](#bespoke-constructor) | constructor: function() { … } -| [Basic lifecycle callbacks](#basic-callbacks) | created, attached, detached, attributeChanged -| [Native HTML element extension](#type-extension) | extends: ‘…’ -| [Configure properties](#property-config) | properties: { … } -| [Attribute deserialization to property](#attribute-deserialization) | properties: { \: \ } -| [Prototype Mixins](#prototype-mixins) | mixins: [ … ] - - -Template content stamped into "local DOM" and tree lifecycle - -| Feature | Usage -|---------|------- -| [Template stamping into local DOM](#template-stamping) | \\\ -| [DOM (re-)distribution](#dom-distribution) | \ -| [DOM API](#dom-api) | Polymer.dom -| [Configuring default values](#configure-values) | properties: \: { value: \\|\ } -| [Bottom-up callback after configuration](#ready-method) | ready: function() { … } - - -Declarative data binding, events, and property nofication - -| Feature | Usage -|---------|------- -| [Local node marshalling](#node-marshalling) | this.$.\ -| [Event listener setup](#event-listeners)| listeners: { ‘\.\’: ‘function’, ... } -| [Annotated event listener setup](#annotated-listeners) | \ -| [Property change callbacks](#change-callbacks) | properties: \: { observer: ‘function’ } -| [Declarative property binding](#property-binding) | \ -| [Property change notification](#property-notification) | properties: { \: { notify: true } } -| [Binding to structured data](#path-binding) | \ -| [Path change notification](#set-path) | setPathValue(\, \) -| [Declarative attribute binding](#attribute-binding) | \ -| [Reflecting properties to attributes](#attribute-reflection) | properties: \: { reflect: true } } -| [Computed properties](#computed-properties) | computed: { \: ‘function(\)’ } -| [Read-only properties](#read-only) | properties: { \: { readOnly: true } } -| [Utility functions](#utility-functions) | toggleClass, toggleAttribute, fire, async, … -| [Scoped styling](#scoped-styling) | \ - - - - - - -``` - -Loading remote stylesheets is also supported. The syntax is slightly different from how stylesheets are typically loaded. This is typically convenient for developers who like to separate styles or use style pre-processing tools. - -```html - - - - -``` - - -### Sharing stylesheets - -In addition to using remote stylesheets as described above, styles can be shared between elements by defining ``'s containing styles to be shared, and referencing shared styles to be included in a given element by listing the `dom-module` id in an array of `styleModules`. - -Example: - -```html - - - -``` - -```js -Polymer({ - is: 'element-one' - styleModules: ['common-styles'] -}); - -Polymer({ - is: 'element-two' - styleModules: ['common-styles'] -}); -``` - - -## Global Polymer settings - -Document-level global Polymer settings can be set before loading by setting a `Polymer` object on window as the first script in the main document: - -```html - - - - - - - - - - ... - -``` - -Settings can also be switched on the URL query string: - -``` -http://myserver.com/test-app/index.html?dom=shadow -``` - -Available settings: - -* `dom` - options: - * `shady` - all local DOM will be rendered using Shady DOM (even where shadow-DOM supported (current default) - * `shadow` - local DOM will be rendered using Shadow DOM where supported (this will be made default soon) - - - -## Feature layering - -Polymer 0.8 is currently layered into 3 sets of features provided as 3 discrete HTML imports, such that an individual element developer can depend on a version of Polymer whose feature set matches their tastes/needs. For authors who opt out of the more opinionated local DOM or data-binding features, their element's dependencies would not be payload- or runtime-burdened by these higher-level features, to the extent that a user didn't depend on other elements using those features on that page. That said, all features are designed to have low runtime cost when unused by a given element. - -Higher layers depend on lower layers, and elements requiring lower layers will actually be imbued with features of the highest-level version of Polymer used on the page (those elements would simply not use/take advantage of those features). This provides a good tradeoff between element authors being able to avoid direct dependencies on unused features when their element is used standalone, while also allowing end users to mix-and-match elements created with different layers on the same page. - -* polymer-micro.html: [Polymer micro features](#polymer-micro) -* polymer-mini.html: [Polymer mini features](#polymer-mini) -* polymer.html: [Polymer standard features](#polymer-standard) - ---- - - -# Migration Notes - -This section covers how to deal with yet-unimplemented and/or de-scoped features in Polymer 0.8 as compared to 0.5. Many of these are simply un-implemented; that is, we will likely have a final "solution" that addresses the need, we just haven't tackled that feature yet as we address items in priority order. Other solutions in 0.8 may be lower-level as compared to 0.5, and will be explained here. - -As the final 0.8 API solidifies, this section will be updated accordingly. As such, this section should be considered answers "how do I solve problem xyz TODAY", rather than a representation of the final Polymer 0.8 API. - -## Property casing - -TL;DR: When binding to camel-cased properties, use "dash-case" attribute names to indicate the "camelCase" property to bind to. - -Example: bind `this.myValue` to `.thatValue`: - -BEFORE: 0.5 - -```html - -``` - -AFTER: 0.8 - -```html - -``` - -In 0.5, binding annotations were allowed to mixed-case properties (despite the fact that attribute names always get converted to lower-case by the HTML parser), and the Node.bind implementation at the "receiving end" of the binding automatically inferred the mixed-case property it was assumed to refer to at instance time. - -In 0.8, "binding" is done at prorotype time before the type of the element being bound to is known, hence knowing the exact JS property to bind to allows better efficiency. - -## Binding limitations - -Current limitations that are on the backlog for evaluation/improvement are listed below, with current workarounds: - -* Sub-textContent/property binding - * You cannot currrently do any of the following: - - ```html -
stuff here: {{stuff}}
-
- - ``` - - * Instead, use ``'s to break up textContent into discrete elements: - - ```html -
stuff here: {{stuff}}
- ``` - - * Use computed properties for concatenating into properties/attributes: - - ```html -
- - ``` - -* CSS class binding: - * May bind entire class list from one property to `class` _attribute_: - `
` - * Otherwise, `this.classList.add/remove` from change handlers -* CSS inline-style binding: - * May bind entire inline style from one property to `style` _property_: - `
` - * Otherwise, assign `this.style.props` from change handlers - -## Structured data and path notification - -To notify non-bound structured data changes changes, use `setPathValue` and `notifyPath`: - -```js -this.setPathValue('user.manager', 'Matt'); -``` - -Which is equivalent to: - -```js -this.user.manager = 'Matt'; -this.notifyPath('user.manager', this.user.manager); -``` - -## Repeating elements - -Repeating templates is moved to a custom element (HTMLTemplateElement type extension called `x-repeat`): - -```html - -``` - -## Array notification - -This area is in high flux. Arrays bound to `x-repeat` are currently observed using `Array.observe` (or equivalent shim) and `x-repeat` will reflect changes to array mutations (push, pop, shift, unshift, splice) asynchronously. - -**In-place sort of array is not supported**. Sorting/filtering will likely be provided as a feature of `x-repeat` (and possibly other array-aware elements such as `x-list`) in the future. - -Implementation and usage details will likely change, stay tuned. - - -## Mixins / Inheritance - -TODO - use composition for now - -## Gesture support - -TODO - use standard DOM for now until gesture support is ported diff --git a/example/bower_components/polymer/README.md b/example/bower_components/polymer/README.md deleted file mode 100644 index 950836318..000000000 --- a/example/bower_components/polymer/README.md +++ /dev/null @@ -1,330 +0,0 @@ -# Polymer 0.8 Preview - -Authors interested in learning the core concepts in 0.8 may be interested in our [primer](https://github.com/Polymer/polymer/blob/0.8-preview/PRIMER.md). - -## From The Ground Up - -Let us begin this tale with a short stroll through the layers that Polymer is -built upon, and some of the rationale of how we got there. - -### Raw Custom Elements - -Custom Elements are a powerful emerging web standard that allows developers to create their own elements by attaching a class to a tag-name. - -#### document.registerElement - -The native API is very simple, it looks something like this: - -```js -document.registerElement(, {prototype: Object[, extends: String]}); -``` - -#### Typical Boilerplate - -There is a little bit of work one has to do to set up the class with the right prototypes and so on to construct a Custom Element. Here is an typical example (using ES5 syntax): - -```js -var ctor = function() { - return document.createElement('x-custom'); -}; -ctor.prototype = Object.create(HTMLElement.prototype); -ctor.prototype.constructor = ctor; -ctor.prototype.createdCallback = function() { - this.innerHTML = 'Hello World, I am a Custom Element!'; -} -document.registerElement('x-custom', ctor); -``` - -### Reluctant Polymer() Abstraction - -By principle, Polymer team tries to avoid abstracting DOM APIs, especially new ones. But in this case we finally decided the ergonomic benefit was worth it. By wrapping `registerElement` in our own function, we can reduce the above boilerplate to: - -```js -var ctor = Polymer({ - is: 'x-custom', - created: function() { - this.innerHTML = 'Hello World, I am a Custom Element!'; - } -}); -``` - -### Polymer() Does a Bit More - -You might notice the `Polymer()` invocation defines `created` instead of `createdCallback`. This is a feature of `Polymer.Base`, a tiny prototype that `Polymer()` adds to your prototype chain as it's handling the boilerplate above. `Polymer.Base` hooks the standard Custom Element lifecycle callbacks to provide helper implementations. The hooks in turn call shorter-named lifecycle methods on your prototype. - -- `created` instead of `createdCallback` -- `attached` instead of `attachedCallback` -- `detached` instead of `detachedCallback` -- `attributeChanged` instead of `attributeChangedCallback` - -You can always fallback to using the low-level methods if you wish (iow, you could simply implement `createdCallback` in your prototype). - -`Polymer.Base` also implements `registerCallback` on your prototype. `Polymer()` calls `registerCallback` which allows `Polymer.Base` to supply a layering system for Polymer abstractions so that no element needs to pay for features it doesn't use. - -## Features - -By default, the default Polymer distribution include several features. Although `Polymer.Base` itself is tiny, if you examine `Polymer.Base` you will probably see several methods that have been plugged-in to that prototype by feature definitions. The next few sections will explain these features and why we include them in the default set. Keep in mind that it's entirely possible to construct custom feature sets, or even use a trivial, featureless form of `Polymer()`. - -### Feature: _property-config_ - -The first feature implements support for the `properties` property. By placing a object-valued `properties` property on your prototype, let's you define various aspects of your custom-elements public API. - -By itself, the `properties` feature **doesn't do anything**. It only provides API for asking questions about these special properties (see [link to docs] for details). - -```js -Polymer({ - - is: 'x-custom', - - properties: { - user: String, - isHappy: Boolean, - count: { - type: Number, - readOnly: true, - notify: true - } - }, - - created: function() { - this.innerHTML = 'Hello World, I am a Custom Element!'; - } - -}); -``` - -Remember that the fields assigned to `count`, such as `readOnly` and `notify` don't do anything by themselves, it requires other features to give them life. - -### Feature: _attributes_ - -Many custom elements want to support configuration using HTML attributes. Custom Elements provides the `attributeChanged` callback gives us the raw API for this ability, but then we have to deal with initialization and type conversion (attributes are always strings). Here is an example of a custom element that supports a `user` attribute using the raw API. - -```js - Polymer({ - - is: 'x-custom', - - created: function() { - // handle any initial value - this.attributeChanged('user'); - // render - this.innerHTML = 'Hello World, my user is ' + (this.user || 'nobody') + '.'; - }, - - attributeChanged: function(name) { - switch(name) { - case 'user': - // pretty easy since user is a String, for other types - // we have to do more work - if (this.hasAttribute('user')) { - this.user = this.getAttribute('user'); - } - break; - } - } - - }); -``` - -Although it's relatively simple, having to write this code becomes annoying when working with multiple attributes or non-String types. It's also not very DRY. - -Instead, Polymer's `attributes` feature handles this work for you (using the `properties` feature data). If an attribute is set that matches a property listed in the `properties` object, the value is captured into the matching property. Strings are automatically converted to the specified type. - -The type system includes support for Object values expressed as JSON, or Date objects expressed as any Date-parsable string representation. Boolean properties are mapped to Boolean attributes, in other words, if the attribute exists at all, its value is true, regardless of its string-value (and the value is only false if the attribute does not exist). - -Here is the equivalent of the above code, taking advantage of the `attributes` feature. - -```html - - - -``` - -### [ToDoc] attributes:hostAttributes - -### Feature: _template_ - -HTML templates are an emerging web standard that we like to consider part of the Web Components family. Templates are a great way to provide archetypal DOM content for your custom element, and this is where the `template` feature comes in. - -As usual, we started by writing basic template support by hand. It generally looks something like this: - -```html - - - -``` - -Again, it's simple, but it's a common pattern, so the `template` feature does it automatically. By default it looks for a template as the first element before the script, so our code can look like this: - -```html - - - -``` - -### Feature: _annotations_ - -Most elements need to customize the DOM instanced from a template. For this reason, it's handy to encode markers into your template to indicate special nodes, attributes, or text. Polymer calls these markers _annotations_. The `annotations` feature scans the template (once per element, at registration time) and builds a data-structure into the prototype that identifies markers it finds in the DOM (see [link to docs] for details). Normally you do not need to work with this data directly, Polymer does it for you. - -### Feature: _annotations-nodes_ - -Traditionally, modifying DOM is done by querying for elements to manipulate. Here is an example: - -```html - - - -``` - -This example is very simple. But in real projects, repeating queries is inefficient, so query results are often stored (memoized). Also, as DOM composition becomes more tricky, crafting correct queries can be difficult. For these reasons, automatically capturing nodes makes a good feature. - -The `annotations-nodes` feature builds a map of instance nodes by `id` in `this.$` (using the `annotations` feature data). Here is how the `annotations-nodes` feature simplifies the above example. - -```html - - - -``` - -### Feature: _annotations-events_ - -Most elements also need to listen for events. The standard DOM method `addEventListener` provides the low-level support: - -```html - - - -``` - -Again, this is pretty simple, but it's so common that it's worth making even simpler. The `annotations-events` feature supports declaring event listeners directly in our template. - -Declaring listeners in the template is convenient, and also helps us decouple view from behavior. - -```html - - - -``` - -Notice that the `kickAction` method doesn't know anything about `button`. If we decided that kicking should be performed by a key-press, or a menu-item, the element code doesn't need to know. We can change the UI however we want. Also notice that by attaching the event declaratively, we have removed the need to give the button an id. - -### [ToDoc] events feature - -### [ToDoc] keys feature - -### [ToDoc] content feature - - diff --git a/example/bower_components/polymer/bower.json b/example/bower_components/polymer/bower.json deleted file mode 100644 index f7cd3ac5e..000000000 --- a/example/bower_components/polymer/bower.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "polymer", - "version": "0.8", - "main": [ - "polymer.html" - ], - "license": "http://polymer.github.io/LICENSE.txt", - "ignore": [ - "/.*", - "/test/" - ], - "authors": [ - "The Polymer Authors (http://polymer.github.io/AUTHORS.txt)" - ], - "repository": { - "type": "git", - "url": "https://github.com/Polymer/polymer.git" - }, - "devDependencies": { - "web-component-tester": "*", - "webcomponentsjs": "webcomponents/webcomponentsjs#master" - }, - "private": true -} diff --git a/example/bower_components/polymer/build.bat b/example/bower_components/polymer/build.bat deleted file mode 100644 index 12479f7da..000000000 --- a/example/bower_components/polymer/build.bat +++ /dev/null @@ -1,2 +0,0 @@ -START /B vulcanize polymer-simplex.html --inline --strip -output dist/polymer-simplex.html -START /B vulcanize polymer.html --inline --strip -output dist/polymer.html diff --git a/example/bower_components/polymer/docs/index.html b/example/bower_components/polymer/docs/index.html deleted file mode 100644 index b2fa01610..000000000 --- a/example/bower_components/polymer/docs/index.html +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - x-doc-viewer - - - - - - - - - - - - - - - - - - - - - diff --git a/example/bower_components/polymer/explainer/data-bind.png b/example/bower_components/polymer/explainer/data-bind.png deleted file mode 100644 index c55816df3ea7fabc3a64f90425be3a346f431bbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34533 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 diff --git a/example/bower_components/polymer/explainer/data-bind.vsdx b/example/bower_components/polymer/explainer/data-bind.vsdx deleted file mode 100644 index e699a26bb30541b189fcd7d811b2d138d2ccb6c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38379 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 Pu_6qKz$yBY2_PN-g`tXp diff --git a/example/bower_components/polymer/explainer/samples.html b/example/bower_components/polymer/explainer/samples.html deleted file mode 100644 index 7a22c3108..000000000 --- a/example/bower_components/polymer/explainer/samples.html +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - Explainer Samples - - - - - - - - - - - - - - - - - diff --git a/example/bower_components/polymer/polymer-micro.html b/example/bower_components/polymer/polymer-micro.html deleted file mode 100644 index 4acbc14ee..000000000 --- a/example/bower_components/polymer/polymer-micro.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - diff --git a/example/bower_components/polymer/polymer-mini.html b/example/bower_components/polymer/polymer-mini.html deleted file mode 100644 index 50b089bf7..000000000 --- a/example/bower_components/polymer/polymer-mini.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - diff --git a/example/bower_components/polymer/polymer.html b/example/bower_components/polymer/polymer.html deleted file mode 100644 index 114fa8317..000000000 --- a/example/bower_components/polymer/polymer.html +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/example/bower_components/polymer/src/expr/focus.html b/example/bower_components/polymer/src/expr/focus.html deleted file mode 100644 index d02e74e61..000000000 --- a/example/bower_components/polymer/src/expr/focus.html +++ /dev/null @@ -1,22 +0,0 @@ - - diff --git a/example/bower_components/polymer/src/expr/gestures.html b/example/bower_components/polymer/src/expr/gestures.html deleted file mode 100644 index 0c4560412..000000000 --- a/example/bower_components/polymer/src/expr/gestures.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/example/bower_components/polymer/src/expr/log.html b/example/bower_components/polymer/src/expr/log.html deleted file mode 100644 index 05d8fceea..000000000 --- a/example/bower_components/polymer/src/expr/log.html +++ /dev/null @@ -1,21 +0,0 @@ - - diff --git a/example/bower_components/polymer/src/expr/polymer-expr.html b/example/bower_components/polymer/src/expr/polymer-expr.html deleted file mode 100644 index 226374470..000000000 --- a/example/bower_components/polymer/src/expr/polymer-expr.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/example/bower_components/polymer/src/expr/sinspect.html b/example/bower_components/polymer/src/expr/sinspect.html deleted file mode 100644 index 009653a26..000000000 --- a/example/bower_components/polymer/src/expr/sinspect.html +++ /dev/null @@ -1,235 +0,0 @@ - - diff --git a/example/bower_components/polymer/src/expr/style-auditor.html b/example/bower_components/polymer/src/expr/style-auditor.html deleted file mode 100644 index d12f49164..000000000 --- a/example/bower_components/polymer/src/expr/style-auditor.html +++ /dev/null @@ -1,122 +0,0 @@ - diff --git a/example/bower_components/polymer/src/expr/x-styling-defaults.html b/example/bower_components/polymer/src/expr/x-styling-defaults.html deleted file mode 100644 index 4c986c8a0..000000000 --- a/example/bower_components/polymer/src/expr/x-styling-defaults.html +++ /dev/null @@ -1,61 +0,0 @@ - - - diff --git a/example/bower_components/polymer/src/expr/x-styling.html b/example/bower_components/polymer/src/expr/x-styling.html deleted file mode 100644 index 47c797c2e..000000000 --- a/example/bower_components/polymer/src/expr/x-styling.html +++ /dev/null @@ -1,289 +0,0 @@ - - - - - - diff --git a/example/bower_components/polymer/src/features/micro/attributes.html b/example/bower_components/polymer/src/features/micro/attributes.html deleted file mode 100644 index 17e5e3ea2..000000000 --- a/example/bower_components/polymer/src/features/micro/attributes.html +++ /dev/null @@ -1,176 +0,0 @@ - - - - - diff --git a/example/bower_components/polymer/src/features/micro/constructor.html b/example/bower_components/polymer/src/features/micro/constructor.html deleted file mode 100644 index b7e656eef..000000000 --- a/example/bower_components/polymer/src/features/micro/constructor.html +++ /dev/null @@ -1,74 +0,0 @@ - - diff --git a/example/bower_components/polymer/src/features/micro/extends.html b/example/bower_components/polymer/src/features/micro/extends.html deleted file mode 100644 index 53805f425..000000000 --- a/example/bower_components/polymer/src/features/micro/extends.html +++ /dev/null @@ -1,79 +0,0 @@ - - diff --git a/example/bower_components/polymer/src/features/micro/mixins.html b/example/bower_components/polymer/src/features/micro/mixins.html deleted file mode 100644 index fa1114fc5..000000000 --- a/example/bower_components/polymer/src/features/micro/mixins.html +++ /dev/null @@ -1,40 +0,0 @@ - - diff --git a/example/bower_components/polymer/src/features/micro/properties.html b/example/bower_components/polymer/src/features/micro/properties.html deleted file mode 100644 index 85d005029..000000000 --- a/example/bower_components/polymer/src/features/micro/properties.html +++ /dev/null @@ -1,96 +0,0 @@ - - diff --git a/example/bower_components/polymer/src/features/mini/ready.html b/example/bower_components/polymer/src/features/mini/ready.html deleted file mode 100644 index 91341b9a5..000000000 --- a/example/bower_components/polymer/src/features/mini/ready.html +++ /dev/null @@ -1,120 +0,0 @@ - - diff --git a/example/bower_components/polymer/src/features/mini/shadow.html b/example/bower_components/polymer/src/features/mini/shadow.html deleted file mode 100644 index ebcb8c098..000000000 --- a/example/bower_components/polymer/src/features/mini/shadow.html +++ /dev/null @@ -1,41 +0,0 @@ - - - diff --git a/example/bower_components/polymer/src/features/mini/shady.html b/example/bower_components/polymer/src/features/mini/shady.html deleted file mode 100644 index 25763e2be..000000000 --- a/example/bower_components/polymer/src/features/mini/shady.html +++ /dev/null @@ -1,339 +0,0 @@ - - - - diff --git a/example/bower_components/polymer/src/features/mini/template.html b/example/bower_components/polymer/src/features/mini/template.html deleted file mode 100644 index d0655d8b6..000000000 --- a/example/bower_components/polymer/src/features/mini/template.html +++ /dev/null @@ -1,60 +0,0 @@ - - diff --git a/example/bower_components/polymer/src/features/standard/annotations.html b/example/bower_components/polymer/src/features/standard/annotations.html deleted file mode 100644 index 9c2fb2c02..000000000 --- a/example/bower_components/polymer/src/features/standard/annotations.html +++ /dev/null @@ -1,194 +0,0 @@ - - - - - - - diff --git a/example/bower_components/polymer/src/features/standard/configure.html b/example/bower_components/polymer/src/features/standard/configure.html deleted file mode 100644 index 266bd0ebe..000000000 --- a/example/bower_components/polymer/src/features/standard/configure.html +++ /dev/null @@ -1,162 +0,0 @@ - - - \ No newline at end of file diff --git a/example/bower_components/polymer/src/features/standard/effects.html b/example/bower_components/polymer/src/features/standard/effects.html deleted file mode 100644 index ad61d5556..000000000 --- a/example/bower_components/polymer/src/features/standard/effects.html +++ /dev/null @@ -1,149 +0,0 @@ - - - - - - - diff --git a/example/bower_components/polymer/src/features/standard/events.html b/example/bower_components/polymer/src/features/standard/events.html deleted file mode 100644 index a7b9d929b..000000000 --- a/example/bower_components/polymer/src/features/standard/events.html +++ /dev/null @@ -1,114 +0,0 @@ - - diff --git a/example/bower_components/polymer/src/features/standard/notify-path.html b/example/bower_components/polymer/src/features/standard/notify-path.html deleted file mode 100644 index 097d35b29..000000000 --- a/example/bower_components/polymer/src/features/standard/notify-path.html +++ /dev/null @@ -1,266 +0,0 @@ - - diff --git a/example/bower_components/polymer/src/features/standard/resolveUrl.html b/example/bower_components/polymer/src/features/standard/resolveUrl.html deleted file mode 100644 index f715f9bd1..000000000 --- a/example/bower_components/polymer/src/features/standard/resolveUrl.html +++ /dev/null @@ -1,27 +0,0 @@ - - diff --git a/example/bower_components/polymer/src/features/standard/styling.html b/example/bower_components/polymer/src/features/standard/styling.html deleted file mode 100644 index b26328aca..000000000 --- a/example/bower_components/polymer/src/features/standard/styling.html +++ /dev/null @@ -1,155 +0,0 @@ - - - - - - - - diff --git a/example/bower_components/polymer/src/features/standard/utils.html b/example/bower_components/polymer/src/features/standard/utils.html deleted file mode 100644 index 57bafccf9..000000000 --- a/example/bower_components/polymer/src/features/standard/utils.html +++ /dev/null @@ -1,139 +0,0 @@ - - - - - - diff --git a/example/bower_components/polymer/src/lib/annotations/annotations.html b/example/bower_components/polymer/src/lib/annotations/annotations.html deleted file mode 100644 index 226d65a13..000000000 --- a/example/bower_components/polymer/src/lib/annotations/annotations.html +++ /dev/null @@ -1,273 +0,0 @@ - - - - diff --git a/example/bower_components/polymer/src/lib/annotations/demo/app-chrome.html b/example/bower_components/polymer/src/lib/annotations/demo/app-chrome.html deleted file mode 100644 index 48030ab6d..000000000 --- a/example/bower_components/polymer/src/lib/annotations/demo/app-chrome.html +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - Template Test - - - - - - - - - - - - - - - - - - -

-
-  
-
-  
-
-
-
diff --git a/example/bower_components/polymer/src/lib/array-observe.html b/example/bower_components/polymer/src/lib/array-observe.html
deleted file mode 100644
index a99d01f29..000000000
--- a/example/bower_components/polymer/src/lib/array-observe.html
+++ /dev/null
@@ -1,115 +0,0 @@
-
-
-
-
diff --git a/example/bower_components/polymer/src/lib/array-splice.html b/example/bower_components/polymer/src/lib/array-splice.html
deleted file mode 100644
index f51279a71..000000000
--- a/example/bower_components/polymer/src/lib/array-splice.html
+++ /dev/null
@@ -1,262 +0,0 @@
-
-
\ No newline at end of file
diff --git a/example/bower_components/polymer/src/lib/async.html b/example/bower_components/polymer/src/lib/async.html
deleted file mode 100644
index 652bf53c8..000000000
--- a/example/bower_components/polymer/src/lib/async.html
+++ /dev/null
@@ -1,68 +0,0 @@
-
-
diff --git a/example/bower_components/polymer/src/lib/base.html b/example/bower_components/polymer/src/lib/base.html
deleted file mode 100644
index a195eaecf..000000000
--- a/example/bower_components/polymer/src/lib/base.html
+++ /dev/null
@@ -1,117 +0,0 @@
-
-
diff --git a/example/bower_components/polymer/src/lib/bind/bind-annotations.html b/example/bower_components/polymer/src/lib/bind/bind-annotations.html
deleted file mode 100644
index 84e280cb3..000000000
--- a/example/bower_components/polymer/src/lib/bind/bind-annotations.html
+++ /dev/null
@@ -1,74 +0,0 @@
-
-
-
diff --git a/example/bower_components/polymer/src/lib/bind/bind-effects.html b/example/bower_components/polymer/src/lib/bind/bind-effects.html
deleted file mode 100644
index 652e5fd00..000000000
--- a/example/bower_components/polymer/src/lib/bind/bind-effects.html
+++ /dev/null
@@ -1,188 +0,0 @@
-
-
diff --git a/example/bower_components/polymer/src/lib/bind/bind.html b/example/bower_components/polymer/src/lib/bind/bind.html
deleted file mode 100644
index 20b5051f9..000000000
--- a/example/bower_components/polymer/src/lib/bind/bind.html
+++ /dev/null
@@ -1,218 +0,0 @@
-
-
diff --git a/example/bower_components/polymer/src/lib/bind/demo/app-chrome.html b/example/bower_components/polymer/src/lib/bind/demo/app-chrome.html
deleted file mode 100644
index d5be36edb..000000000
--- a/example/bower_components/polymer/src/lib/bind/demo/app-chrome.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-  Bind Test
-
-  
-  
-
-  
-
-  
-  
-
-
-
-
-  

-
-  

-
-
-
diff --git a/example/bower_components/polymer/src/lib/bind/demo/app.html b/example/bower_components/polymer/src/lib/bind/demo/app.html
deleted file mode 100644
index fe7d2160b..000000000
--- a/example/bower_components/polymer/src/lib/bind/demo/app.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-  Bind Test
-
-  
-  
-
-  
-
-  
-
-  
-  
-
-
-
-
-  

-  

-
-
-
diff --git a/example/bower_components/polymer/src/lib/bind/demo/src/annotations-bind-demo.html b/example/bower_components/polymer/src/lib/bind/demo/src/annotations-bind-demo.html
deleted file mode 100644
index 747ba0899..000000000
--- a/example/bower_components/polymer/src/lib/bind/demo/src/annotations-bind-demo.html
+++ /dev/null
@@ -1,76 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/example/bower_components/polymer/src/lib/bind/demo/src/bind-demo.html b/example/bower_components/polymer/src/lib/bind/demo/src/bind-demo.html
deleted file mode 100644
index dcb9e9cdb..000000000
--- a/example/bower_components/polymer/src/lib/bind/demo/src/bind-demo.html
+++ /dev/null
@@ -1,83 +0,0 @@
-
-
-
-  
-
\ No newline at end of file
diff --git a/example/bower_components/polymer/src/lib/collection.html b/example/bower_components/polymer/src/lib/collection.html
deleted file mode 100644
index 5717b1aec..000000000
--- a/example/bower_components/polymer/src/lib/collection.html
+++ /dev/null
@@ -1,164 +0,0 @@
-
-
-
-
-
-
diff --git a/example/bower_components/polymer/src/lib/css-parse.html b/example/bower_components/polymer/src/lib/css-parse.html
deleted file mode 100644
index 97deac195..000000000
--- a/example/bower_components/polymer/src/lib/css-parse.html
+++ /dev/null
@@ -1,131 +0,0 @@
-
\ No newline at end of file
diff --git a/example/bower_components/polymer/src/lib/debounce.html b/example/bower_components/polymer/src/lib/debounce.html
deleted file mode 100644
index f78767017..000000000
--- a/example/bower_components/polymer/src/lib/debounce.html
+++ /dev/null
@@ -1,69 +0,0 @@
-
-
diff --git a/example/bower_components/polymer/src/lib/dom-api.html b/example/bower_components/polymer/src/lib/dom-api.html
deleted file mode 100644
index 34338eee5..000000000
--- a/example/bower_components/polymer/src/lib/dom-api.html
+++ /dev/null
@@ -1,393 +0,0 @@
-
-
-
diff --git a/example/bower_components/polymer/src/lib/dom-module.html b/example/bower_components/polymer/src/lib/dom-module.html
deleted file mode 100644
index e97de14f5..000000000
--- a/example/bower_components/polymer/src/lib/dom-module.html
+++ /dev/null
@@ -1,50 +0,0 @@
-
\ No newline at end of file
diff --git a/example/bower_components/polymer/src/lib/lang.html b/example/bower_components/polymer/src/lib/lang.html
deleted file mode 100644
index d80e8fd1b..000000000
--- a/example/bower_components/polymer/src/lib/lang.html
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
diff --git a/example/bower_components/polymer/src/lib/module.html b/example/bower_components/polymer/src/lib/module.html
deleted file mode 100644
index 4bbd6b384..000000000
--- a/example/bower_components/polymer/src/lib/module.html
+++ /dev/null
@@ -1,56 +0,0 @@
-
-
diff --git a/example/bower_components/polymer/src/lib/polymer.html b/example/bower_components/polymer/src/lib/polymer.html
deleted file mode 100644
index 1819f42da..000000000
--- a/example/bower_components/polymer/src/lib/polymer.html
+++ /dev/null
@@ -1,78 +0,0 @@
-
-
-
diff --git a/example/bower_components/polymer/src/lib/resolve-url.html b/example/bower_components/polymer/src/lib/resolve-url.html
deleted file mode 100644
index 9d6e18684..000000000
--- a/example/bower_components/polymer/src/lib/resolve-url.html
+++ /dev/null
@@ -1,82 +0,0 @@
-
-
\ No newline at end of file
diff --git a/example/bower_components/polymer/src/lib/settings.html b/example/bower_components/polymer/src/lib/settings.html
deleted file mode 100644
index f7ae9c5b8..000000000
--- a/example/bower_components/polymer/src/lib/settings.html
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
\ No newline at end of file
diff --git a/example/bower_components/polymer/src/lib/style-transformer.html b/example/bower_components/polymer/src/lib/style-transformer.html
deleted file mode 100644
index e39833c20..000000000
--- a/example/bower_components/polymer/src/lib/style-transformer.html
+++ /dev/null
@@ -1,166 +0,0 @@
-
-
-
-
-
diff --git a/example/bower_components/polymer/src/lib/style-util.html b/example/bower_components/polymer/src/lib/style-util.html
deleted file mode 100644
index b9634e43a..000000000
--- a/example/bower_components/polymer/src/lib/style-util.html
+++ /dev/null
@@ -1,77 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/example/bower_components/polymer/src/lib/template/templatizer.html b/example/bower_components/polymer/src/lib/template/templatizer.html
deleted file mode 100644
index bab1c06f9..000000000
--- a/example/bower_components/polymer/src/lib/template/templatizer.html
+++ /dev/null
@@ -1,117 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/example/bower_components/polymer/src/lib/template/x-array-selector.html b/example/bower_components/polymer/src/lib/template/x-array-selector.html
deleted file mode 100644
index 9d90cd304..000000000
--- a/example/bower_components/polymer/src/lib/template/x-array-selector.html
+++ /dev/null
@@ -1,94 +0,0 @@
-
-
-
diff --git a/example/bower_components/polymer/src/lib/template/x-autobind.html b/example/bower_components/polymer/src/lib/template/x-autobind.html
deleted file mode 100644
index 5e78eb657..000000000
--- a/example/bower_components/polymer/src/lib/template/x-autobind.html
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
diff --git a/example/bower_components/polymer/src/lib/template/x-repeat.html b/example/bower_components/polymer/src/lib/template/x-repeat.html
deleted file mode 100644
index ce85afabb..000000000
--- a/example/bower_components/polymer/src/lib/template/x-repeat.html
+++ /dev/null
@@ -1,389 +0,0 @@
-
-
-
-
-
-
-
diff --git a/example/bower_components/polymer/src/lib/template/x-template.html b/example/bower_components/polymer/src/lib/template/x-template.html
deleted file mode 100644
index da2430c2e..000000000
--- a/example/bower_components/polymer/src/lib/template/x-template.html
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
-
diff --git a/example/bower_components/polymer/src/polymer.html b/example/bower_components/polymer/src/polymer.html
deleted file mode 100644
index e4627ca77..000000000
--- a/example/bower_components/polymer/src/polymer.html
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
diff --git a/example/bower_components/polymer/wct.conf.js b/example/bower_components/polymer/wct.conf.js
deleted file mode 100644
index 111deea50..000000000
--- a/example/bower_components/polymer/wct.conf.js
+++ /dev/null
@@ -1,3 +0,0 @@
-module.exports = {
-  suites: ['test/runner.html'], 
-};
diff --git a/example/bower_components/webcomponentsjs/.bower.json b/example/bower_components/webcomponentsjs/.bower.json
deleted file mode 100644
index afd9ea954..000000000
--- a/example/bower_components/webcomponentsjs/.bower.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
-  "name": "webcomponentsjs",
-  "main": "webcomponents.js",
-  "version": "0.5.5",
-  "homepage": "http://webcomponents.org",
-  "authors": [
-    "The Polymer Authors"
-  ],
-  "keywords": [
-    "webcomponents"
-  ],
-  "license": "BSD",
-  "ignore": [],
-  "_release": "0.5.5",
-  "_resolution": {
-    "type": "version",
-    "tag": "0.5.5",
-    "commit": "46f8f2665f7b91e3f248bc9bdb20a29b91f921b5"
-  },
-  "_source": "git://github.com/webcomponents/webcomponentsjs.git",
-  "_target": "~0.5.5",
-  "_originalSource": "webcomponents/webcomponentsjs",
-  "_direct": true
-}
\ No newline at end of file
diff --git a/example/bower_components/webcomponentsjs/CustomElements.js b/example/bower_components/webcomponentsjs/CustomElements.js
deleted file mode 100644
index 8ec15f6b8..000000000
--- a/example/bower_components/webcomponentsjs/CustomElements.js
+++ /dev/null
@@ -1,634 +0,0 @@
-/**
- * @license
- * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
- * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
- * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
- * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
- * Code distributed by Google as part of the polymer project is also
- * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
- */
-// @version 0.5.5
-if (typeof WeakMap === "undefined") {
-  (function() {
-    var defineProperty = Object.defineProperty;
-    var counter = Date.now() % 1e9;
-    var WeakMap = function() {
-      this.name = "__st" + (Math.random() * 1e9 >>> 0) + (counter++ + "__");
-    };
-    WeakMap.prototype = {
-      set: function(key, value) {
-        var entry = key[this.name];
-        if (entry && entry[0] === key) entry[1] = value; else defineProperty(key, this.name, {
-          value: [ key, value ],
-          writable: true
-        });
-        return this;
-      },
-      get: function(key) {
-        var entry;
-        return (entry = key[this.name]) && entry[0] === key ? entry[1] : undefined;
-      },
-      "delete": function(key) {
-        var entry = key[this.name];
-        if (!entry || entry[0] !== key) return false;
-        entry[0] = entry[1] = undefined;
-        return true;
-      },
-      has: function(key) {
-        var entry = key[this.name];
-        if (!entry) return false;
-        return entry[0] === key;
-      }
-    };
-    window.WeakMap = WeakMap;
-  })();
-}
-
-window.CustomElements = window.CustomElements || {
-  flags: {}
-};
-
-(function(scope) {
-  var flags = scope.flags;
-  var modules = [];
-  var addModule = function(module) {
-    modules.push(module);
-  };
-  var initializeModules = function() {
-    modules.forEach(function(module) {
-      module(scope);
-    });
-  };
-  scope.addModule = addModule;
-  scope.initializeModules = initializeModules;
-  scope.hasNative = Boolean(document.registerElement);
-  scope.useNative = !flags.register && scope.hasNative && !window.ShadowDOMPolyfill && (!window.HTMLImports || HTMLImports.useNative);
-})(CustomElements);
-
-CustomElements.addModule(function(scope) {
-  var IMPORT_LINK_TYPE = window.HTMLImports ? HTMLImports.IMPORT_LINK_TYPE : "none";
-  function forSubtree(node, cb) {
-    findAllElements(node, function(e) {
-      if (cb(e)) {
-        return true;
-      }
-      forRoots(e, cb);
-    });
-    forRoots(node, cb);
-  }
-  function findAllElements(node, find, data) {
-    var e = node.firstElementChild;
-    if (!e) {
-      e = node.firstChild;
-      while (e && e.nodeType !== Node.ELEMENT_NODE) {
-        e = e.nextSibling;
-      }
-    }
-    while (e) {
-      if (find(e, data) !== true) {
-        findAllElements(e, find, data);
-      }
-      e = e.nextElementSibling;
-    }
-    return null;
-  }
-  function forRoots(node, cb) {
-    var root = node.shadowRoot;
-    while (root) {
-      forSubtree(root, cb);
-      root = root.olderShadowRoot;
-    }
-  }
-  var processingDocuments;
-  function forDocumentTree(doc, cb) {
-    processingDocuments = [];
-    _forDocumentTree(doc, cb);
-    processingDocuments = null;
-  }
-  function _forDocumentTree(doc, cb) {
-    doc = wrap(doc);
-    if (processingDocuments.indexOf(doc) >= 0) {
-      return;
-    }
-    processingDocuments.push(doc);
-    var imports = doc.querySelectorAll("link[rel=" + IMPORT_LINK_TYPE + "]");
-    for (var i = 0, l = imports.length, n; i < l && (n = imports[i]); i++) {
-      if (n.import) {
-        _forDocumentTree(n.import, cb);
-      }
-    }
-    cb(doc);
-  }
-  scope.forDocumentTree = forDocumentTree;
-  scope.forSubtree = forSubtree;
-});
-
-CustomElements.addModule(function(scope) {
-  var flags = scope.flags;
-  var forSubtree = scope.forSubtree;
-  var forDocumentTree = scope.forDocumentTree;
-  function addedNode(node) {
-    return added(node) || addedSubtree(node);
-  }
-  function added(node) {
-    if (scope.upgrade(node)) {
-      return true;
-    }
-    attached(node);
-  }
-  function addedSubtree(node) {
-    forSubtree(node, function(e) {
-      if (added(e)) {
-        return true;
-      }
-    });
-  }
-  function attachedNode(node) {
-    attached(node);
-    if (inDocument(node)) {
-      forSubtree(node, function(e) {
-        attached(e);
-      });
-    }
-  }
-  var hasPolyfillMutations = !window.MutationObserver || window.MutationObserver === window.JsMutationObserver;
-  scope.hasPolyfillMutations = hasPolyfillMutations;
-  var isPendingMutations = false;
-  var pendingMutations = [];
-  function deferMutation(fn) {
-    pendingMutations.push(fn);
-    if (!isPendingMutations) {
-      isPendingMutations = true;
-      setTimeout(takeMutations);
-    }
-  }
-  function takeMutations() {
-    isPendingMutations = false;
-    var $p = pendingMutations;
-    for (var i = 0, l = $p.length, p; i < l && (p = $p[i]); i++) {
-      p();
-    }
-    pendingMutations = [];
-  }
-  function attached(element) {
-    if (hasPolyfillMutations) {
-      deferMutation(function() {
-        _attached(element);
-      });
-    } else {
-      _attached(element);
-    }
-  }
-  function _attached(element) {
-    if (element.__upgraded__ && (element.attachedCallback || element.detachedCallback)) {
-      if (!element.__attached && inDocument(element)) {
-        element.__attached = true;
-        if (element.attachedCallback) {
-          element.attachedCallback();
-        }
-      }
-    }
-  }
-  function detachedNode(node) {
-    detached(node);
-    forSubtree(node, function(e) {
-      detached(e);
-    });
-  }
-  function detached(element) {
-    if (hasPolyfillMutations) {
-      deferMutation(function() {
-        _detached(element);
-      });
-    } else {
-      _detached(element);
-    }
-  }
-  function _detached(element) {
-    if (element.__upgraded__ && (element.attachedCallback || element.detachedCallback)) {
-      if (element.__attached && !inDocument(element)) {
-        element.__attached = false;
-        if (element.detachedCallback) {
-          element.detachedCallback();
-        }
-      }
-    }
-  }
-  function inDocument(element) {
-    var p = element;
-    var doc = wrap(document);
-    while (p) {
-      if (p == doc) {
-        return true;
-      }
-      p = p.parentNode || p.host;
-    }
-  }
-  function watchShadow(node) {
-    if (node.shadowRoot && !node.shadowRoot.__watched) {
-      flags.dom && console.log("watching shadow-root for: ", node.localName);
-      var root = node.shadowRoot;
-      while (root) {
-        observe(root);
-        root = root.olderShadowRoot;
-      }
-    }
-  }
-  function handler(mutations) {
-    if (flags.dom) {
-      var mx = mutations[0];
-      if (mx && mx.type === "childList" && mx.addedNodes) {
-        if (mx.addedNodes) {
-          var d = mx.addedNodes[0];
-          while (d && d !== document && !d.host) {
-            d = d.parentNode;
-          }
-          var u = d && (d.URL || d._URL || d.host && d.host.localName) || "";
-          u = u.split("/?").shift().split("/").pop();
-        }
-      }
-      console.group("mutations (%d) [%s]", mutations.length, u || "");
-    }
-    mutations.forEach(function(mx) {
-      if (mx.type === "childList") {
-        forEach(mx.addedNodes, function(n) {
-          if (!n.localName) {
-            return;
-          }
-          addedNode(n);
-        });
-        forEach(mx.removedNodes, function(n) {
-          if (!n.localName) {
-            return;
-          }
-          detachedNode(n);
-        });
-      }
-    });
-    flags.dom && console.groupEnd();
-  }
-  function takeRecords(node) {
-    node = wrap(node);
-    if (!node) {
-      node = wrap(document);
-    }
-    while (node.parentNode) {
-      node = node.parentNode;
-    }
-    var observer = node.__observer;
-    if (observer) {
-      handler(observer.takeRecords());
-      takeMutations();
-    }
-  }
-  var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);
-  function observe(inRoot) {
-    if (inRoot.__observer) {
-      return;
-    }
-    var observer = new MutationObserver(handler);
-    observer.observe(inRoot, {
-      childList: true,
-      subtree: true
-    });
-    inRoot.__observer = observer;
-  }
-  function upgradeDocument(doc) {
-    doc = wrap(doc);
-    flags.dom && console.group("upgradeDocument: ", doc.baseURI.split("/").pop());
-    addedNode(doc);
-    observe(doc);
-    flags.dom && console.groupEnd();
-  }
-  function upgradeDocumentTree(doc) {
-    forDocumentTree(doc, upgradeDocument);
-  }
-  var originalCreateShadowRoot = Element.prototype.createShadowRoot;
-  if (originalCreateShadowRoot) {
-    Element.prototype.createShadowRoot = function() {
-      var root = originalCreateShadowRoot.call(this);
-      CustomElements.watchShadow(this);
-      return root;
-    };
-  }
-  scope.watchShadow = watchShadow;
-  scope.upgradeDocumentTree = upgradeDocumentTree;
-  scope.upgradeSubtree = addedSubtree;
-  scope.upgradeAll = addedNode;
-  scope.attachedNode = attachedNode;
-  scope.takeRecords = takeRecords;
-});
-
-CustomElements.addModule(function(scope) {
-  var flags = scope.flags;
-  function upgrade(node) {
-    if (!node.__upgraded__ && node.nodeType === Node.ELEMENT_NODE) {
-      var is = node.getAttribute("is");
-      var definition = scope.getRegisteredDefinition(is || node.localName);
-      if (definition) {
-        if (is && definition.tag == node.localName) {
-          return upgradeWithDefinition(node, definition);
-        } else if (!is && !definition.extends) {
-          return upgradeWithDefinition(node, definition);
-        }
-      }
-    }
-  }
-  function upgradeWithDefinition(element, definition) {
-    flags.upgrade && console.group("upgrade:", element.localName);
-    if (definition.is) {
-      element.setAttribute("is", definition.is);
-    }
-    implementPrototype(element, definition);
-    element.__upgraded__ = true;
-    created(element);
-    scope.attachedNode(element);
-    scope.upgradeSubtree(element);
-    flags.upgrade && console.groupEnd();
-    return element;
-  }
-  function implementPrototype(element, definition) {
-    if (Object.__proto__) {
-      element.__proto__ = definition.prototype;
-    } else {
-      customMixin(element, definition.prototype, definition.native);
-      element.__proto__ = definition.prototype;
-    }
-  }
-  function customMixin(inTarget, inSrc, inNative) {
-    var used = {};
-    var p = inSrc;
-    while (p !== inNative && p !== HTMLElement.prototype) {
-      var keys = Object.getOwnPropertyNames(p);
-      for (var i = 0, k; k = keys[i]; i++) {
-        if (!used[k]) {
-          Object.defineProperty(inTarget, k, Object.getOwnPropertyDescriptor(p, k));
-          used[k] = 1;
-        }
-      }
-      p = Object.getPrototypeOf(p);
-    }
-  }
-  function created(element) {
-    if (element.createdCallback) {
-      element.createdCallback();
-    }
-  }
-  scope.upgrade = upgrade;
-  scope.upgradeWithDefinition = upgradeWithDefinition;
-  scope.implementPrototype = implementPrototype;
-});
-
-CustomElements.addModule(function(scope) {
-  var upgradeDocumentTree = scope.upgradeDocumentTree;
-  var upgrade = scope.upgrade;
-  var upgradeWithDefinition = scope.upgradeWithDefinition;
-  var implementPrototype = scope.implementPrototype;
-  var useNative = scope.useNative;
-  function register(name, options) {
-    var definition = options || {};
-    if (!name) {
-      throw new Error("document.registerElement: first argument `name` must not be empty");
-    }
-    if (name.indexOf("-") < 0) {
-      throw new Error("document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '" + String(name) + "'.");
-    }
-    if (isReservedTag(name)) {
-      throw new Error("Failed to execute 'registerElement' on 'Document': Registration failed for type '" + String(name) + "'. The type name is invalid.");
-    }
-    if (getRegisteredDefinition(name)) {
-      throw new Error("DuplicateDefinitionError: a type with name '" + String(name) + "' is already registered");
-    }
-    if (!definition.prototype) {
-      definition.prototype = Object.create(HTMLElement.prototype);
-    }
-    definition.__name = name.toLowerCase();
-    definition.lifecycle = definition.lifecycle || {};
-    definition.ancestry = ancestry(definition.extends);
-    resolveTagName(definition);
-    resolvePrototypeChain(definition);
-    overrideAttributeApi(definition.prototype);
-    registerDefinition(definition.__name, definition);
-    definition.ctor = generateConstructor(definition);
-    definition.ctor.prototype = definition.prototype;
-    definition.prototype.constructor = definition.ctor;
-    if (scope.ready) {
-      upgradeDocumentTree(document);
-    }
-    return definition.ctor;
-  }
-  function overrideAttributeApi(prototype) {
-    if (prototype.setAttribute._polyfilled) {
-      return;
-    }
-    var setAttribute = prototype.setAttribute;
-    prototype.setAttribute = function(name, value) {
-      changeAttribute.call(this, name, value, setAttribute);
-    };
-    var removeAttribute = prototype.removeAttribute;
-    prototype.removeAttribute = function(name) {
-      changeAttribute.call(this, name, null, removeAttribute);
-    };
-    prototype.setAttribute._polyfilled = true;
-  }
-  function changeAttribute(name, value, operation) {
-    name = name.toLowerCase();
-    var oldValue = this.getAttribute(name);
-    operation.apply(this, arguments);
-    var newValue = this.getAttribute(name);
-    if (this.attributeChangedCallback && newValue !== oldValue) {
-      this.attributeChangedCallback(name, oldValue, newValue);
-    }
-  }
-  function isReservedTag(name) {
-    for (var i = 0; i < reservedTagList.length; i++) {
-      if (name === reservedTagList[i]) {
-        return true;
-      }
-    }
-  }
-  var reservedTagList = [ "annotation-xml", "color-profile", "font-face", "font-face-src", "font-face-uri", "font-face-format", "font-face-name", "missing-glyph" ];
-  function ancestry(extnds) {
-    var extendee = getRegisteredDefinition(extnds);
-    if (extendee) {
-      return ancestry(extendee.extends).concat([ extendee ]);
-    }
-    return [];
-  }
-  function resolveTagName(definition) {
-    var baseTag = definition.extends;
-    for (var i = 0, a; a = definition.ancestry[i]; i++) {
-      baseTag = a.is && a.tag;
-    }
-    definition.tag = baseTag || definition.__name;
-    if (baseTag) {
-      definition.is = definition.__name;
-    }
-  }
-  function resolvePrototypeChain(definition) {
-    if (!Object.__proto__) {
-      var nativePrototype = HTMLElement.prototype;
-      if (definition.is) {
-        var inst = document.createElement(definition.tag);
-        var expectedPrototype = Object.getPrototypeOf(inst);
-        if (expectedPrototype === definition.prototype) {
-          nativePrototype = expectedPrototype;
-        }
-      }
-      var proto = definition.prototype, ancestor;
-      while (proto && proto !== nativePrototype) {
-        ancestor = Object.getPrototypeOf(proto);
-        proto.__proto__ = ancestor;
-        proto = ancestor;
-      }
-      definition.native = nativePrototype;
-    }
-  }
-  function instantiate(definition) {
-    return upgradeWithDefinition(domCreateElement(definition.tag), definition);
-  }
-  var registry = {};
-  function getRegisteredDefinition(name) {
-    if (name) {
-      return registry[name.toLowerCase()];
-    }
-  }
-  function registerDefinition(name, definition) {
-    registry[name] = definition;
-  }
-  function generateConstructor(definition) {
-    return function() {
-      return instantiate(definition);
-    };
-  }
-  var HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
-  function createElementNS(namespace, tag, typeExtension) {
-    if (namespace === HTML_NAMESPACE) {
-      return createElement(tag, typeExtension);
-    } else {
-      return domCreateElementNS(namespace, tag);
-    }
-  }
-  function createElement(tag, typeExtension) {
-    var definition = getRegisteredDefinition(typeExtension || tag);
-    if (definition) {
-      if (tag == definition.tag && typeExtension == definition.is) {
-        return new definition.ctor();
-      }
-      if (!typeExtension && !definition.is) {
-        return new definition.ctor();
-      }
-    }
-    var element;
-    if (typeExtension) {
-      element = createElement(tag);
-      element.setAttribute("is", typeExtension);
-      return element;
-    }
-    element = domCreateElement(tag);
-    if (tag.indexOf("-") >= 0) {
-      implementPrototype(element, HTMLElement);
-    }
-    return element;
-  }
-  function cloneNode(deep) {
-    var n = domCloneNode.call(this, deep);
-    upgrade(n);
-    return n;
-  }
-  var domCreateElement = document.createElement.bind(document);
-  var domCreateElementNS = document.createElementNS.bind(document);
-  var domCloneNode = Node.prototype.cloneNode;
-  var isInstance;
-  if (!Object.__proto__ && !useNative) {
-    isInstance = function(obj, ctor) {
-      var p = obj;
-      while (p) {
-        if (p === ctor.prototype) {
-          return true;
-        }
-        p = p.__proto__;
-      }
-      return false;
-    };
-  } else {
-    isInstance = function(obj, base) {
-      return obj instanceof base;
-    };
-  }
-  document.registerElement = register;
-  document.createElement = createElement;
-  document.createElementNS = createElementNS;
-  Node.prototype.cloneNode = cloneNode;
-  scope.registry = registry;
-  scope.instanceof = isInstance;
-  scope.reservedTagList = reservedTagList;
-  scope.getRegisteredDefinition = getRegisteredDefinition;
-  document.register = document.registerElement;
-});
-
-(function(scope) {
-  var useNative = scope.useNative;
-  var initializeModules = scope.initializeModules;
-  var isIE11OrOlder = /Trident/.test(navigator.userAgent);
-  if (useNative) {
-    var nop = function() {};
-    scope.watchShadow = nop;
-    scope.upgrade = nop;
-    scope.upgradeAll = nop;
-    scope.upgradeDocumentTree = nop;
-    scope.upgradeSubtree = nop;
-    scope.takeRecords = nop;
-    scope.instanceof = function(obj, base) {
-      return obj instanceof base;
-    };
-  } else {
-    initializeModules();
-  }
-  var upgradeDocumentTree = scope.upgradeDocumentTree;
-  if (!window.wrap) {
-    if (window.ShadowDOMPolyfill) {
-      window.wrap = ShadowDOMPolyfill.wrapIfNeeded;
-      window.unwrap = ShadowDOMPolyfill.unwrapIfNeeded;
-    } else {
-      window.wrap = window.unwrap = function(node) {
-        return node;
-      };
-    }
-  }
-  function bootstrap() {
-    upgradeDocumentTree(wrap(document));
-    if (window.HTMLImports) {
-      HTMLImports.__importsParsingHook = function(elt) {
-        upgradeDocumentTree(wrap(elt.import));
-      };
-    }
-    CustomElements.ready = true;
-    setTimeout(function() {
-      CustomElements.readyTime = Date.now();
-      if (window.HTMLImports) {
-        CustomElements.elapsed = CustomElements.readyTime - HTMLImports.readyTime;
-      }
-      document.dispatchEvent(new CustomEvent("WebComponentsReady", {
-        bubbles: true
-      }));
-    });
-  }
-  if (isIE11OrOlder && typeof window.CustomEvent !== "function") {
-    window.CustomEvent = function(inType, params) {
-      params = params || {};
-      var e = document.createEvent("CustomEvent");
-      e.initCustomEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable), params.detail);
-      return e;
-    };
-    window.CustomEvent.prototype = window.Event.prototype;
-  }
-  if (document.readyState === "complete" || scope.flags.eager) {
-    bootstrap();
-  } else if (document.readyState === "interactive" && !window.attachEvent && (!window.HTMLImports || window.HTMLImports.ready)) {
-    bootstrap();
-  } else {
-    var loadEvent = window.HTMLImports && !HTMLImports.ready ? "HTMLImportsLoaded" : "DOMContentLoaded";
-    window.addEventListener(loadEvent, bootstrap);
-  }
-})(window.CustomElements);
\ No newline at end of file
diff --git a/example/bower_components/webcomponentsjs/CustomElements.min.js b/example/bower_components/webcomponentsjs/CustomElements.min.js
deleted file mode 100644
index c29c57e3f..000000000
--- a/example/bower_components/webcomponentsjs/CustomElements.min.js
+++ /dev/null
@@ -1,11 +0,0 @@
-/**
- * @license
- * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
- * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
- * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
- * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
- * Code distributed by Google as part of the polymer project is also
- * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
- */
-// @version 0.5.5
-"undefined"==typeof WeakMap&&!function(){var e=Object.defineProperty,t=Date.now()%1e9,o=function(){this.name="__st"+(1e9*Math.random()>>>0)+(t++ +"__")};o.prototype={set:function(t,o){var n=t[this.name];return n&&n[0]===t?n[1]=o:e(t,this.name,{value:[t,o],writable:!0}),this},get:function(e){var t;return(t=e[this.name])&&t[0]===e?t[1]:void 0},"delete":function(e){var t=e[this.name];return t&&t[0]===e?(t[0]=t[1]=void 0,!0):!1},has:function(e){var t=e[this.name];return t?t[0]===e:!1}},window.WeakMap=o}(),window.CustomElements=window.CustomElements||{flags:{}},function(e){var t=e.flags,o=[],n=function(e){o.push(e)},r=function(){o.forEach(function(t){t(e)})};e.addModule=n,e.initializeModules=r,e.hasNative=Boolean(document.registerElement),e.useNative=!t.register&&e.hasNative&&!window.ShadowDOMPolyfill&&(!window.HTMLImports||HTMLImports.useNative)}(CustomElements),CustomElements.addModule(function(e){function t(e,t){o(e,function(e){return t(e)?!0:void n(e,t)}),n(e,t)}function o(e,t,n){var r=e.firstElementChild;if(!r)for(r=e.firstChild;r&&r.nodeType!==Node.ELEMENT_NODE;)r=r.nextSibling;for(;r;)t(r,n)!==!0&&o(r,t,n),r=r.nextElementSibling;return null}function n(e,o){for(var n=e.shadowRoot;n;)t(n,o),n=n.olderShadowRoot}function r(e,t){i=[],a(e,t),i=null}function a(e,t){if(e=wrap(e),!(i.indexOf(e)>=0)){i.push(e);for(var o,n=e.querySelectorAll("link[rel="+u+"]"),r=0,d=n.length;d>r&&(o=n[r]);r++)o["import"]&&a(o["import"],t);t(e)}}var i,u=window.HTMLImports?HTMLImports.IMPORT_LINK_TYPE:"none";e.forDocumentTree=r,e.forSubtree=t}),CustomElements.addModule(function(e){function t(e){return o(e)||n(e)}function o(t){return e.upgrade(t)?!0:void u(t)}function n(e){y(e,function(e){return o(e)?!0:void 0})}function r(e){u(e),f(e)&&y(e,function(e){u(e)})}function a(e){M.push(e),C||(C=!0,setTimeout(i))}function i(){C=!1;for(var e,t=M,o=0,n=t.length;n>o&&(e=t[o]);o++)e();M=[]}function u(e){E?a(function(){d(e)}):d(e)}function d(e){e.__upgraded__&&(e.attachedCallback||e.detachedCallback)&&!e.__attached&&f(e)&&(e.__attached=!0,e.attachedCallback&&e.attachedCallback())}function c(e){s(e),y(e,function(e){s(e)})}function s(e){E?a(function(){l(e)}):l(e)}function l(e){e.__upgraded__&&(e.attachedCallback||e.detachedCallback)&&e.__attached&&!f(e)&&(e.__attached=!1,e.detachedCallback&&e.detachedCallback())}function f(e){for(var t=e,o=wrap(document);t;){if(t==o)return!0;t=t.parentNode||t.host}}function p(e){if(e.shadowRoot&&!e.shadowRoot.__watched){_.dom&&console.log("watching shadow-root for: ",e.localName);for(var t=e.shadowRoot;t;)h(t),t=t.olderShadowRoot}}function m(e){if(_.dom){var o=e[0];if(o&&"childList"===o.type&&o.addedNodes&&o.addedNodes){for(var n=o.addedNodes[0];n&&n!==document&&!n.host;)n=n.parentNode;var r=n&&(n.URL||n._URL||n.host&&n.host.localName)||"";r=r.split("/?").shift().split("/").pop()}console.group("mutations (%d) [%s]",e.length,r||"")}e.forEach(function(e){"childList"===e.type&&(N(e.addedNodes,function(e){e.localName&&t(e)}),N(e.removedNodes,function(e){e.localName&&c(e)}))}),_.dom&&console.groupEnd()}function w(e){for(e=wrap(e),e||(e=wrap(document));e.parentNode;)e=e.parentNode;var t=e.__observer;t&&(m(t.takeRecords()),i())}function h(e){if(!e.__observer){var t=new MutationObserver(m);t.observe(e,{childList:!0,subtree:!0}),e.__observer=t}}function g(e){e=wrap(e),_.dom&&console.group("upgradeDocument: ",e.baseURI.split("/").pop()),t(e),h(e),_.dom&&console.groupEnd()}function v(e){b(e,g)}var _=e.flags,y=e.forSubtree,b=e.forDocumentTree,E=!window.MutationObserver||window.MutationObserver===window.JsMutationObserver;e.hasPolyfillMutations=E;var C=!1,M=[],N=Array.prototype.forEach.call.bind(Array.prototype.forEach),T=Element.prototype.createShadowRoot;T&&(Element.prototype.createShadowRoot=function(){var e=T.call(this);return CustomElements.watchShadow(this),e}),e.watchShadow=p,e.upgradeDocumentTree=v,e.upgradeSubtree=n,e.upgradeAll=t,e.attachedNode=r,e.takeRecords=w}),CustomElements.addModule(function(e){function t(t){if(!t.__upgraded__&&t.nodeType===Node.ELEMENT_NODE){var n=t.getAttribute("is"),r=e.getRegisteredDefinition(n||t.localName);if(r){if(n&&r.tag==t.localName)return o(t,r);if(!n&&!r["extends"])return o(t,r)}}}function o(t,o){return i.upgrade&&console.group("upgrade:",t.localName),o.is&&t.setAttribute("is",o.is),n(t,o),t.__upgraded__=!0,a(t),e.attachedNode(t),e.upgradeSubtree(t),i.upgrade&&console.groupEnd(),t}function n(e,t){Object.__proto__?e.__proto__=t.prototype:(r(e,t.prototype,t["native"]),e.__proto__=t.prototype)}function r(e,t,o){for(var n={},r=t;r!==o&&r!==HTMLElement.prototype;){for(var a,i=Object.getOwnPropertyNames(r),u=0;a=i[u];u++)n[a]||(Object.defineProperty(e,a,Object.getOwnPropertyDescriptor(r,a)),n[a]=1);r=Object.getPrototypeOf(r)}}function a(e){e.createdCallback&&e.createdCallback()}var i=e.flags;e.upgrade=t,e.upgradeWithDefinition=o,e.implementPrototype=n}),CustomElements.addModule(function(e){function t(t,n){var d=n||{};if(!t)throw new Error("document.registerElement: first argument `name` must not be empty");if(t.indexOf("-")<0)throw new Error("document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '"+String(t)+"'.");if(r(t))throw new Error("Failed to execute 'registerElement' on 'Document': Registration failed for type '"+String(t)+"'. The type name is invalid.");if(c(t))throw new Error("DuplicateDefinitionError: a type with name '"+String(t)+"' is already registered");return d.prototype||(d.prototype=Object.create(HTMLElement.prototype)),d.__name=t.toLowerCase(),d.lifecycle=d.lifecycle||{},d.ancestry=a(d["extends"]),i(d),u(d),o(d.prototype),s(d.__name,d),d.ctor=l(d),d.ctor.prototype=d.prototype,d.prototype.constructor=d.ctor,e.ready&&h(document),d.ctor}function o(e){if(!e.setAttribute._polyfilled){var t=e.setAttribute;e.setAttribute=function(e,o){n.call(this,e,o,t)};var o=e.removeAttribute;e.removeAttribute=function(e){n.call(this,e,null,o)},e.setAttribute._polyfilled=!0}}function n(e,t,o){e=e.toLowerCase();var n=this.getAttribute(e);o.apply(this,arguments);var r=this.getAttribute(e);this.attributeChangedCallback&&r!==n&&this.attributeChangedCallback(e,n,r)}function r(e){for(var t=0;t=0&&_(n,HTMLElement),n)}function m(e){var t=T.call(this,e);return g(t),t}var w,h=e.upgradeDocumentTree,g=e.upgrade,v=e.upgradeWithDefinition,_=e.implementPrototype,y=e.useNative,b=["annotation-xml","color-profile","font-face","font-face-src","font-face-uri","font-face-format","font-face-name","missing-glyph"],E={},C="http://www.w3.org/1999/xhtml",M=document.createElement.bind(document),N=document.createElementNS.bind(document),T=Node.prototype.cloneNode;w=Object.__proto__||y?function(e,t){return e instanceof t}:function(e,t){for(var o=e;o;){if(o===t.prototype)return!0;o=o.__proto__}return!1},document.registerElement=t,document.createElement=p,document.createElementNS=f,Node.prototype.cloneNode=m,e.registry=E,e["instanceof"]=w,e.reservedTagList=b,e.getRegisteredDefinition=c,document.register=document.registerElement}),function(e){function t(){i(wrap(document)),window.HTMLImports&&(HTMLImports.__importsParsingHook=function(e){i(wrap(e["import"]))}),CustomElements.ready=!0,setTimeout(function(){CustomElements.readyTime=Date.now(),window.HTMLImports&&(CustomElements.elapsed=CustomElements.readyTime-HTMLImports.readyTime),document.dispatchEvent(new CustomEvent("WebComponentsReady",{bubbles:!0}))})}var o=e.useNative,n=e.initializeModules,r=/Trident/.test(navigator.userAgent);if(o){var a=function(){};e.watchShadow=a,e.upgrade=a,e.upgradeAll=a,e.upgradeDocumentTree=a,e.upgradeSubtree=a,e.takeRecords=a,e["instanceof"]=function(e,t){return e instanceof t}}else n();var i=e.upgradeDocumentTree;if(window.wrap||(window.ShadowDOMPolyfill?(window.wrap=ShadowDOMPolyfill.wrapIfNeeded,window.unwrap=ShadowDOMPolyfill.unwrapIfNeeded):window.wrap=window.unwrap=function(e){return e}),r&&"function"!=typeof window.CustomEvent&&(window.CustomEvent=function(e,t){t=t||{};var o=document.createEvent("CustomEvent");return o.initCustomEvent(e,Boolean(t.bubbles),Boolean(t.cancelable),t.detail),o},window.CustomEvent.prototype=window.Event.prototype),"complete"===document.readyState||e.flags.eager)t();else if("interactive"!==document.readyState||window.attachEvent||window.HTMLImports&&!window.HTMLImports.ready){var u=window.HTMLImports&&!HTMLImports.ready?"HTMLImportsLoaded":"DOMContentLoaded";window.addEventListener(u,t)}else t()}(window.CustomElements);
\ No newline at end of file
diff --git a/example/bower_components/webcomponentsjs/HTMLImports.js b/example/bower_components/webcomponentsjs/HTMLImports.js
deleted file mode 100644
index 9a194e144..000000000
--- a/example/bower_components/webcomponentsjs/HTMLImports.js
+++ /dev/null
@@ -1,764 +0,0 @@
-/**
- * @license
- * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
- * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
- * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
- * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
- * Code distributed by Google as part of the polymer project is also
- * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
- */
-// @version 0.5.5
-if (typeof WeakMap === "undefined") {
-  (function() {
-    var defineProperty = Object.defineProperty;
-    var counter = Date.now() % 1e9;
-    var WeakMap = function() {
-      this.name = "__st" + (Math.random() * 1e9 >>> 0) + (counter++ + "__");
-    };
-    WeakMap.prototype = {
-      set: function(key, value) {
-        var entry = key[this.name];
-        if (entry && entry[0] === key) entry[1] = value; else defineProperty(key, this.name, {
-          value: [ key, value ],
-          writable: true
-        });
-        return this;
-      },
-      get: function(key) {
-        var entry;
-        return (entry = key[this.name]) && entry[0] === key ? entry[1] : undefined;
-      },
-      "delete": function(key) {
-        var entry = key[this.name];
-        if (!entry || entry[0] !== key) return false;
-        entry[0] = entry[1] = undefined;
-        return true;
-      },
-      has: function(key) {
-        var entry = key[this.name];
-        if (!entry) return false;
-        return entry[0] === key;
-      }
-    };
-    window.WeakMap = WeakMap;
-  })();
-}
-
-window.HTMLImports = window.HTMLImports || {
-  flags: {}
-};
-
-(function(scope) {
-  var IMPORT_LINK_TYPE = "import";
-  var useNative = Boolean(IMPORT_LINK_TYPE in document.createElement("link"));
-  var hasShadowDOMPolyfill = Boolean(window.ShadowDOMPolyfill);
-  var wrap = function(node) {
-    return hasShadowDOMPolyfill ? ShadowDOMPolyfill.wrapIfNeeded(node) : node;
-  };
-  var rootDocument = wrap(document);
-  var currentScriptDescriptor = {
-    get: function() {
-      var script = HTMLImports.currentScript || document.currentScript || (document.readyState !== "complete" ? document.scripts[document.scripts.length - 1] : null);
-      return wrap(script);
-    },
-    configurable: true
-  };
-  Object.defineProperty(document, "_currentScript", currentScriptDescriptor);
-  Object.defineProperty(rootDocument, "_currentScript", currentScriptDescriptor);
-  var isIE = /Trident|Edge/.test(navigator.userAgent);
-  function whenReady(callback, doc) {
-    doc = doc || rootDocument;
-    whenDocumentReady(function() {
-      watchImportsLoad(callback, doc);
-    }, doc);
-  }
-  var requiredReadyState = isIE ? "complete" : "interactive";
-  var READY_EVENT = "readystatechange";
-  function isDocumentReady(doc) {
-    return doc.readyState === "complete" || doc.readyState === requiredReadyState;
-  }
-  function whenDocumentReady(callback, doc) {
-    if (!isDocumentReady(doc)) {
-      var checkReady = function() {
-        if (doc.readyState === "complete" || doc.readyState === requiredReadyState) {
-          doc.removeEventListener(READY_EVENT, checkReady);
-          whenDocumentReady(callback, doc);
-        }
-      };
-      doc.addEventListener(READY_EVENT, checkReady);
-    } else if (callback) {
-      callback();
-    }
-  }
-  function markTargetLoaded(event) {
-    event.target.__loaded = true;
-  }
-  function watchImportsLoad(callback, doc) {
-    var imports = doc.querySelectorAll("link[rel=import]");
-    var loaded = 0, l = imports.length;
-    function checkDone(d) {
-      if (loaded == l && callback) {
-        callback();
-      }
-    }
-    function loadedImport(e) {
-      markTargetLoaded(e);
-      loaded++;
-      checkDone();
-    }
-    if (l) {
-      for (var i = 0, imp; i < l && (imp = imports[i]); i++) {
-        if (isImportLoaded(imp)) {
-          loadedImport.call(imp, {
-            target: imp
-          });
-        } else {
-          imp.addEventListener("load", loadedImport);
-          imp.addEventListener("error", loadedImport);
-        }
-      }
-    } else {
-      checkDone();
-    }
-  }
-  function isImportLoaded(link) {
-    return useNative ? link.__loaded || link.import && link.import.readyState !== "loading" : link.__importParsed;
-  }
-  if (useNative) {
-    new MutationObserver(function(mxns) {
-      for (var i = 0, l = mxns.length, m; i < l && (m = mxns[i]); i++) {
-        if (m.addedNodes) {
-          handleImports(m.addedNodes);
-        }
-      }
-    }).observe(document.head, {
-      childList: true
-    });
-    function handleImports(nodes) {
-      for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {
-        if (isImport(n)) {
-          handleImport(n);
-        }
-      }
-    }
-    function isImport(element) {
-      return element.localName === "link" && element.rel === "import";
-    }
-    function handleImport(element) {
-      var loaded = element.import;
-      if (loaded) {
-        markTargetLoaded({
-          target: element
-        });
-      } else {
-        element.addEventListener("load", markTargetLoaded);
-        element.addEventListener("error", markTargetLoaded);
-      }
-    }
-    (function() {
-      if (document.readyState === "loading") {
-        var imports = document.querySelectorAll("link[rel=import]");
-        for (var i = 0, l = imports.length, imp; i < l && (imp = imports[i]); i++) {
-          handleImport(imp);
-        }
-      }
-    })();
-  }
-  whenReady(function() {
-    HTMLImports.ready = true;
-    HTMLImports.readyTime = new Date().getTime();
-    var evt = rootDocument.createEvent("CustomEvent");
-    evt.initCustomEvent("HTMLImportsLoaded", true, true, {});
-    rootDocument.dispatchEvent(evt);
-  });
-  scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;
-  scope.useNative = useNative;
-  scope.rootDocument = rootDocument;
-  scope.whenReady = whenReady;
-  scope.isIE = isIE;
-})(HTMLImports);
-
-(function(scope) {
-  var modules = [];
-  var addModule = function(module) {
-    modules.push(module);
-  };
-  var initializeModules = function() {
-    modules.forEach(function(module) {
-      module(scope);
-    });
-  };
-  scope.addModule = addModule;
-  scope.initializeModules = initializeModules;
-})(HTMLImports);
-
-HTMLImports.addModule(function(scope) {
-  var CSS_URL_REGEXP = /(url\()([^)]*)(\))/g;
-  var CSS_IMPORT_REGEXP = /(@import[\s]+(?!url\())([^;]*)(;)/g;
-  var path = {
-    resolveUrlsInStyle: function(style) {
-      var doc = style.ownerDocument;
-      var resolver = doc.createElement("a");
-      style.textContent = this.resolveUrlsInCssText(style.textContent, resolver);
-      return style;
-    },
-    resolveUrlsInCssText: function(cssText, urlObj) {
-      var r = this.replaceUrls(cssText, urlObj, CSS_URL_REGEXP);
-      r = this.replaceUrls(r, urlObj, CSS_IMPORT_REGEXP);
-      return r;
-    },
-    replaceUrls: function(text, urlObj, regexp) {
-      return text.replace(regexp, function(m, pre, url, post) {
-        var urlPath = url.replace(/["']/g, "");
-        urlObj.href = urlPath;
-        urlPath = urlObj.href;
-        return pre + "'" + urlPath + "'" + post;
-      });
-    }
-  };
-  scope.path = path;
-});
-
-HTMLImports.addModule(function(scope) {
-  var xhr = {
-    async: true,
-    ok: function(request) {
-      return request.status >= 200 && request.status < 300 || request.status === 304 || request.status === 0;
-    },
-    load: function(url, next, nextContext) {
-      var request = new XMLHttpRequest();
-      if (scope.flags.debug || scope.flags.bust) {
-        url += "?" + Math.random();
-      }
-      request.open("GET", url, xhr.async);
-      request.addEventListener("readystatechange", function(e) {
-        if (request.readyState === 4) {
-          var locationHeader = request.getResponseHeader("Location");
-          var redirectedUrl = null;
-          if (locationHeader) {
-            var redirectedUrl = locationHeader.substr(0, 1) === "/" ? location.origin + locationHeader : locationHeader;
-          }
-          next.call(nextContext, !xhr.ok(request) && request, request.response || request.responseText, redirectedUrl);
-        }
-      });
-      request.send();
-      return request;
-    },
-    loadDocument: function(url, next, nextContext) {
-      this.load(url, next, nextContext).responseType = "document";
-    }
-  };
-  scope.xhr = xhr;
-});
-
-HTMLImports.addModule(function(scope) {
-  var xhr = scope.xhr;
-  var flags = scope.flags;
-  var Loader = function(onLoad, onComplete) {
-    this.cache = {};
-    this.onload = onLoad;
-    this.oncomplete = onComplete;
-    this.inflight = 0;
-    this.pending = {};
-  };
-  Loader.prototype = {
-    addNodes: function(nodes) {
-      this.inflight += nodes.length;
-      for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {
-        this.require(n);
-      }
-      this.checkDone();
-    },
-    addNode: function(node) {
-      this.inflight++;
-      this.require(node);
-      this.checkDone();
-    },
-    require: function(elt) {
-      var url = elt.src || elt.href;
-      elt.__nodeUrl = url;
-      if (!this.dedupe(url, elt)) {
-        this.fetch(url, elt);
-      }
-    },
-    dedupe: function(url, elt) {
-      if (this.pending[url]) {
-        this.pending[url].push(elt);
-        return true;
-      }
-      var resource;
-      if (this.cache[url]) {
-        this.onload(url, elt, this.cache[url]);
-        this.tail();
-        return true;
-      }
-      this.pending[url] = [ elt ];
-      return false;
-    },
-    fetch: function(url, elt) {
-      flags.load && console.log("fetch", url, elt);
-      if (!url) {
-        setTimeout(function() {
-          this.receive(url, elt, {
-            error: "href must be specified"
-          }, null);
-        }.bind(this), 0);
-      } else if (url.match(/^data:/)) {
-        var pieces = url.split(",");
-        var header = pieces[0];
-        var body = pieces[1];
-        if (header.indexOf(";base64") > -1) {
-          body = atob(body);
-        } else {
-          body = decodeURIComponent(body);
-        }
-        setTimeout(function() {
-          this.receive(url, elt, null, body);
-        }.bind(this), 0);
-      } else {
-        var receiveXhr = function(err, resource, redirectedUrl) {
-          this.receive(url, elt, err, resource, redirectedUrl);
-        }.bind(this);
-        xhr.load(url, receiveXhr);
-      }
-    },
-    receive: function(url, elt, err, resource, redirectedUrl) {
-      this.cache[url] = resource;
-      var $p = this.pending[url];
-      for (var i = 0, l = $p.length, p; i < l && (p = $p[i]); i++) {
-        this.onload(url, p, resource, err, redirectedUrl);
-        this.tail();
-      }
-      this.pending[url] = null;
-    },
-    tail: function() {
-      --this.inflight;
-      this.checkDone();
-    },
-    checkDone: function() {
-      if (!this.inflight) {
-        this.oncomplete();
-      }
-    }
-  };
-  scope.Loader = Loader;
-});
-
-HTMLImports.addModule(function(scope) {
-  var Observer = function(addCallback) {
-    this.addCallback = addCallback;
-    this.mo = new MutationObserver(this.handler.bind(this));
-  };
-  Observer.prototype = {
-    handler: function(mutations) {
-      for (var i = 0, l = mutations.length, m; i < l && (m = mutations[i]); i++) {
-        if (m.type === "childList" && m.addedNodes.length) {
-          this.addedNodes(m.addedNodes);
-        }
-      }
-    },
-    addedNodes: function(nodes) {
-      if (this.addCallback) {
-        this.addCallback(nodes);
-      }
-      for (var i = 0, l = nodes.length, n, loading; i < l && (n = nodes[i]); i++) {
-        if (n.children && n.children.length) {
-          this.addedNodes(n.children);
-        }
-      }
-    },
-    observe: function(root) {
-      this.mo.observe(root, {
-        childList: true,
-        subtree: true
-      });
-    }
-  };
-  scope.Observer = Observer;
-});
-
-HTMLImports.addModule(function(scope) {
-  var path = scope.path;
-  var rootDocument = scope.rootDocument;
-  var flags = scope.flags;
-  var isIE = scope.isIE;
-  var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;
-  var IMPORT_SELECTOR = "link[rel=" + IMPORT_LINK_TYPE + "]";
-  var importParser = {
-    documentSelectors: IMPORT_SELECTOR,
-    importsSelectors: [ IMPORT_SELECTOR, "link[rel=stylesheet]", "style", "script:not([type])", 'script[type="text/javascript"]' ].join(","),
-    map: {
-      link: "parseLink",
-      script: "parseScript",
-      style: "parseStyle"
-    },
-    dynamicElements: [],
-    parseNext: function() {
-      var next = this.nextToParse();
-      if (next) {
-        this.parse(next);
-      }
-    },
-    parse: function(elt) {
-      if (this.isParsed(elt)) {
-        flags.parse && console.log("[%s] is already parsed", elt.localName);
-        return;
-      }
-      var fn = this[this.map[elt.localName]];
-      if (fn) {
-        this.markParsing(elt);
-        fn.call(this, elt);
-      }
-    },
-    parseDynamic: function(elt, quiet) {
-      this.dynamicElements.push(elt);
-      if (!quiet) {
-        this.parseNext();
-      }
-    },
-    markParsing: function(elt) {
-      flags.parse && console.log("parsing", elt);
-      this.parsingElement = elt;
-    },
-    markParsingComplete: function(elt) {
-      elt.__importParsed = true;
-      this.markDynamicParsingComplete(elt);
-      if (elt.__importElement) {
-        elt.__importElement.__importParsed = true;
-        this.markDynamicParsingComplete(elt.__importElement);
-      }
-      this.parsingElement = null;
-      flags.parse && console.log("completed", elt);
-    },
-    markDynamicParsingComplete: function(elt) {
-      var i = this.dynamicElements.indexOf(elt);
-      if (i >= 0) {
-        this.dynamicElements.splice(i, 1);
-      }
-    },
-    parseImport: function(elt) {
-      if (HTMLImports.__importsParsingHook) {
-        HTMLImports.__importsParsingHook(elt);
-      }
-      if (elt.import) {
-        elt.import.__importParsed = true;
-      }
-      this.markParsingComplete(elt);
-      if (elt.__resource && !elt.__error) {
-        elt.dispatchEvent(new CustomEvent("load", {
-          bubbles: false
-        }));
-      } else {
-        elt.dispatchEvent(new CustomEvent("error", {
-          bubbles: false
-        }));
-      }
-      if (elt.__pending) {
-        var fn;
-        while (elt.__pending.length) {
-          fn = elt.__pending.shift();
-          if (fn) {
-            fn({
-              target: elt
-            });
-          }
-        }
-      }
-      this.parseNext();
-    },
-    parseLink: function(linkElt) {
-      if (nodeIsImport(linkElt)) {
-        this.parseImport(linkElt);
-      } else {
-        linkElt.href = linkElt.href;
-        this.parseGeneric(linkElt);
-      }
-    },
-    parseStyle: function(elt) {
-      var src = elt;
-      elt = cloneStyle(elt);
-      elt.__importElement = src;
-      this.parseGeneric(elt);
-    },
-    parseGeneric: function(elt) {
-      this.trackElement(elt);
-      this.addElementToDocument(elt);
-    },
-    rootImportForElement: function(elt) {
-      var n = elt;
-      while (n.ownerDocument.__importLink) {
-        n = n.ownerDocument.__importLink;
-      }
-      return n;
-    },
-    addElementToDocument: function(elt) {
-      var port = this.rootImportForElement(elt.__importElement || elt);
-      port.parentNode.insertBefore(elt, port);
-    },
-    trackElement: function(elt, callback) {
-      var self = this;
-      var done = function(e) {
-        if (callback) {
-          callback(e);
-        }
-        self.markParsingComplete(elt);
-        self.parseNext();
-      };
-      elt.addEventListener("load", done);
-      elt.addEventListener("error", done);
-      if (isIE && elt.localName === "style") {
-        var fakeLoad = false;
-        if (elt.textContent.indexOf("@import") == -1) {
-          fakeLoad = true;
-        } else if (elt.sheet) {
-          fakeLoad = true;
-          var csr = elt.sheet.cssRules;
-          var len = csr ? csr.length : 0;
-          for (var i = 0, r; i < len && (r = csr[i]); i++) {
-            if (r.type === CSSRule.IMPORT_RULE) {
-              fakeLoad = fakeLoad && Boolean(r.styleSheet);
-            }
-          }
-        }
-        if (fakeLoad) {
-          elt.dispatchEvent(new CustomEvent("load", {
-            bubbles: false
-          }));
-        }
-      }
-    },
-    parseScript: function(scriptElt) {
-      var script = document.createElement("script");
-      script.__importElement = scriptElt;
-      script.src = scriptElt.src ? scriptElt.src : generateScriptDataUrl(scriptElt);
-      scope.currentScript = scriptElt;
-      this.trackElement(script, function(e) {
-        script.parentNode.removeChild(script);
-        scope.currentScript = null;
-      });
-      this.addElementToDocument(script);
-    },
-    nextToParse: function() {
-      this._mayParse = [];
-      return !this.parsingElement && (this.nextToParseInDoc(rootDocument) || this.nextToParseDynamic());
-    },
-    nextToParseInDoc: function(doc, link) {
-      if (doc && this._mayParse.indexOf(doc) < 0) {
-        this._mayParse.push(doc);
-        var nodes = doc.querySelectorAll(this.parseSelectorsForNode(doc));
-        for (var i = 0, l = nodes.length, p = 0, n; i < l && (n = nodes[i]); i++) {
-          if (!this.isParsed(n)) {
-            if (this.hasResource(n)) {
-              return nodeIsImport(n) ? this.nextToParseInDoc(n.import, n) : n;
-            } else {
-              return;
-            }
-          }
-        }
-      }
-      return link;
-    },
-    nextToParseDynamic: function() {
-      return this.dynamicElements[0];
-    },
-    parseSelectorsForNode: function(node) {
-      var doc = node.ownerDocument || node;
-      return doc === rootDocument ? this.documentSelectors : this.importsSelectors;
-    },
-    isParsed: function(node) {
-      return node.__importParsed;
-    },
-    needsDynamicParsing: function(elt) {
-      return this.dynamicElements.indexOf(elt) >= 0;
-    },
-    hasResource: function(node) {
-      if (nodeIsImport(node) && node.import === undefined) {
-        return false;
-      }
-      return true;
-    }
-  };
-  function nodeIsImport(elt) {
-    return elt.localName === "link" && elt.rel === IMPORT_LINK_TYPE;
-  }
-  function generateScriptDataUrl(script) {
-    var scriptContent = generateScriptContent(script);
-    return "data:text/javascript;charset=utf-8," + encodeURIComponent(scriptContent);
-  }
-  function generateScriptContent(script) {
-    return script.textContent + generateSourceMapHint(script);
-  }
-  function generateSourceMapHint(script) {
-    var owner = script.ownerDocument;
-    owner.__importedScripts = owner.__importedScripts || 0;
-    var moniker = script.ownerDocument.baseURI;
-    var num = owner.__importedScripts ? "-" + owner.__importedScripts : "";
-    owner.__importedScripts++;
-    return "\n//# sourceURL=" + moniker + num + ".js\n";
-  }
-  function cloneStyle(style) {
-    var clone = style.ownerDocument.createElement("style");
-    clone.textContent = style.textContent;
-    path.resolveUrlsInStyle(clone);
-    return clone;
-  }
-  scope.parser = importParser;
-  scope.IMPORT_SELECTOR = IMPORT_SELECTOR;
-});
-
-HTMLImports.addModule(function(scope) {
-  var flags = scope.flags;
-  var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;
-  var IMPORT_SELECTOR = scope.IMPORT_SELECTOR;
-  var rootDocument = scope.rootDocument;
-  var Loader = scope.Loader;
-  var Observer = scope.Observer;
-  var parser = scope.parser;
-  var importer = {
-    documents: {},
-    documentPreloadSelectors: IMPORT_SELECTOR,
-    importsPreloadSelectors: [ IMPORT_SELECTOR ].join(","),
-    loadNode: function(node) {
-      importLoader.addNode(node);
-    },
-    loadSubtree: function(parent) {
-      var nodes = this.marshalNodes(parent);
-      importLoader.addNodes(nodes);
-    },
-    marshalNodes: function(parent) {
-      return parent.querySelectorAll(this.loadSelectorsForNode(parent));
-    },
-    loadSelectorsForNode: function(node) {
-      var doc = node.ownerDocument || node;
-      return doc === rootDocument ? this.documentPreloadSelectors : this.importsPreloadSelectors;
-    },
-    loaded: function(url, elt, resource, err, redirectedUrl) {
-      flags.load && console.log("loaded", url, elt);
-      elt.__resource = resource;
-      elt.__error = err;
-      if (isImportLink(elt)) {
-        var doc = this.documents[url];
-        if (doc === undefined) {
-          doc = err ? null : makeDocument(resource, redirectedUrl || url);
-          if (doc) {
-            doc.__importLink = elt;
-            this.bootDocument(doc);
-          }
-          this.documents[url] = doc;
-        }
-        elt.import = doc;
-      }
-      parser.parseNext();
-    },
-    bootDocument: function(doc) {
-      this.loadSubtree(doc);
-      this.observer.observe(doc);
-      parser.parseNext();
-    },
-    loadedAll: function() {
-      parser.parseNext();
-    }
-  };
-  var importLoader = new Loader(importer.loaded.bind(importer), importer.loadedAll.bind(importer));
-  importer.observer = new Observer();
-  function isImportLink(elt) {
-    return isLinkRel(elt, IMPORT_LINK_TYPE);
-  }
-  function isLinkRel(elt, rel) {
-    return elt.localName === "link" && elt.getAttribute("rel") === rel;
-  }
-  function hasBaseURIAccessor(doc) {
-    return !!Object.getOwnPropertyDescriptor(doc, "baseURI");
-  }
-  function makeDocument(resource, url) {
-    var doc = document.implementation.createHTMLDocument(IMPORT_LINK_TYPE);
-    doc._URL = url;
-    var base = doc.createElement("base");
-    base.setAttribute("href", url);
-    if (!doc.baseURI && !hasBaseURIAccessor(doc)) {
-      Object.defineProperty(doc, "baseURI", {
-        value: url
-      });
-    }
-    var meta = doc.createElement("meta");
-    meta.setAttribute("charset", "utf-8");
-    doc.head.appendChild(meta);
-    doc.head.appendChild(base);
-    doc.body.innerHTML = resource;
-    if (window.HTMLTemplateElement && HTMLTemplateElement.bootstrap) {
-      HTMLTemplateElement.bootstrap(doc);
-    }
-    return doc;
-  }
-  if (!document.baseURI) {
-    var baseURIDescriptor = {
-      get: function() {
-        var base = document.querySelector("base");
-        return base ? base.href : window.location.href;
-      },
-      configurable: true
-    };
-    Object.defineProperty(document, "baseURI", baseURIDescriptor);
-    Object.defineProperty(rootDocument, "baseURI", baseURIDescriptor);
-  }
-  scope.importer = importer;
-  scope.importLoader = importLoader;
-});
-
-HTMLImports.addModule(function(scope) {
-  var parser = scope.parser;
-  var importer = scope.importer;
-  var dynamic = {
-    added: function(nodes) {
-      var owner, parsed, loading;
-      for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {
-        if (!owner) {
-          owner = n.ownerDocument;
-          parsed = parser.isParsed(owner);
-        }
-        loading = this.shouldLoadNode(n);
-        if (loading) {
-          importer.loadNode(n);
-        }
-        if (this.shouldParseNode(n) && parsed) {
-          parser.parseDynamic(n, loading);
-        }
-      }
-    },
-    shouldLoadNode: function(node) {
-      return node.nodeType === 1 && matches.call(node, importer.loadSelectorsForNode(node));
-    },
-    shouldParseNode: function(node) {
-      return node.nodeType === 1 && matches.call(node, parser.parseSelectorsForNode(node));
-    }
-  };
-  importer.observer.addCallback = dynamic.added.bind(dynamic);
-  var matches = HTMLElement.prototype.matches || HTMLElement.prototype.matchesSelector || HTMLElement.prototype.webkitMatchesSelector || HTMLElement.prototype.mozMatchesSelector || HTMLElement.prototype.msMatchesSelector;
-});
-
-(function(scope) {
-  var initializeModules = scope.initializeModules;
-  var isIE = scope.isIE;
-  if (scope.useNative) {
-    return;
-  }
-  if (isIE && typeof window.CustomEvent !== "function") {
-    window.CustomEvent = function(inType, params) {
-      params = params || {};
-      var e = document.createEvent("CustomEvent");
-      e.initCustomEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable), params.detail);
-      return e;
-    };
-    window.CustomEvent.prototype = window.Event.prototype;
-  }
-  initializeModules();
-  var rootDocument = scope.rootDocument;
-  function bootstrap() {
-    HTMLImports.importer.bootDocument(rootDocument);
-  }
-  if (document.readyState === "complete" || document.readyState === "interactive" && !window.attachEvent) {
-    bootstrap();
-  } else {
-    document.addEventListener("DOMContentLoaded", bootstrap);
-  }
-})(HTMLImports);
\ No newline at end of file
diff --git a/example/bower_components/webcomponentsjs/HTMLImports.min.js b/example/bower_components/webcomponentsjs/HTMLImports.min.js
deleted file mode 100644
index a1a45ce17..000000000
--- a/example/bower_components/webcomponentsjs/HTMLImports.min.js
+++ /dev/null
@@ -1,11 +0,0 @@
-/**
- * @license
- * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
- * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
- * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
- * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
- * Code distributed by Google as part of the polymer project is also
- * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
- */
-// @version 0.5.5
-"undefined"==typeof WeakMap&&!function(){var e=Object.defineProperty,t=Date.now()%1e9,n=function(){this.name="__st"+(1e9*Math.random()>>>0)+(t++ +"__")};n.prototype={set:function(t,n){var r=t[this.name];return r&&r[0]===t?r[1]=n:e(t,this.name,{value:[t,n],writable:!0}),this},get:function(e){var t;return(t=e[this.name])&&t[0]===e?t[1]:void 0},"delete":function(e){var t=e[this.name];return t&&t[0]===e?(t[0]=t[1]=void 0,!0):!1},has:function(e){var t=e[this.name];return t?t[0]===e:!1}},window.WeakMap=n}(),window.HTMLImports=window.HTMLImports||{flags:{}},function(e){function t(e,t){t=t||h,r(function(){i(e,t)},t)}function n(e){return"complete"===e.readyState||e.readyState===g}function r(e,t){if(n(t))e&&e();else{var o=function(){("complete"===t.readyState||t.readyState===g)&&(t.removeEventListener(_,o),r(e,t))};t.addEventListener(_,o)}}function o(e){e.target.__loaded=!0}function i(e,t){function n(){s==c&&e&&e()}function r(e){o(e),s++,n()}var i=t.querySelectorAll("link[rel=import]"),s=0,c=i.length;if(c)for(var d,l=0;c>l&&(d=i[l]);l++)a(d)?r.call(d,{target:d}):(d.addEventListener("load",r),d.addEventListener("error",r));else n()}function a(e){return u?e.__loaded||e["import"]&&"loading"!==e["import"].readyState:e.__importParsed}function s(e){for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)c(t)&&d(t)}function c(e){return"link"===e.localName&&"import"===e.rel}function d(e){var t=e["import"];t?o({target:e}):(e.addEventListener("load",o),e.addEventListener("error",o))}var l="import",u=Boolean(l in document.createElement("link")),m=Boolean(window.ShadowDOMPolyfill),p=function(e){return m?ShadowDOMPolyfill.wrapIfNeeded(e):e},h=p(document),f={get:function(){var e=HTMLImports.currentScript||document.currentScript||("complete"!==document.readyState?document.scripts[document.scripts.length-1]:null);return p(e)},configurable:!0};Object.defineProperty(document,"_currentScript",f),Object.defineProperty(h,"_currentScript",f);var v=/Trident|Edge/.test(navigator.userAgent),g=v?"complete":"interactive",_="readystatechange";u&&(new MutationObserver(function(e){for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)t.addedNodes&&s(t.addedNodes)}).observe(document.head,{childList:!0}),function(){if("loading"===document.readyState)for(var e,t=document.querySelectorAll("link[rel=import]"),n=0,r=t.length;r>n&&(e=t[n]);n++)d(e)}()),t(function(){HTMLImports.ready=!0,HTMLImports.readyTime=(new Date).getTime();var e=h.createEvent("CustomEvent");e.initCustomEvent("HTMLImportsLoaded",!0,!0,{}),h.dispatchEvent(e)}),e.IMPORT_LINK_TYPE=l,e.useNative=u,e.rootDocument=h,e.whenReady=t,e.isIE=v}(HTMLImports),function(e){var t=[],n=function(e){t.push(e)},r=function(){t.forEach(function(t){t(e)})};e.addModule=n,e.initializeModules=r}(HTMLImports),HTMLImports.addModule(function(e){var t=/(url\()([^)]*)(\))/g,n=/(@import[\s]+(?!url\())([^;]*)(;)/g,r={resolveUrlsInStyle:function(e){var t=e.ownerDocument,n=t.createElement("a");return e.textContent=this.resolveUrlsInCssText(e.textContent,n),e},resolveUrlsInCssText:function(e,r){var o=this.replaceUrls(e,r,t);return o=this.replaceUrls(o,r,n)},replaceUrls:function(e,t,n){return e.replace(n,function(e,n,r,o){var i=r.replace(/["']/g,"");return t.href=i,i=t.href,n+"'"+i+"'"+o})}};e.path=r}),HTMLImports.addModule(function(e){var t={async:!0,ok:function(e){return e.status>=200&&e.status<300||304===e.status||0===e.status},load:function(n,r,o){var i=new XMLHttpRequest;return(e.flags.debug||e.flags.bust)&&(n+="?"+Math.random()),i.open("GET",n,t.async),i.addEventListener("readystatechange",function(){if(4===i.readyState){var e=i.getResponseHeader("Location"),n=null;if(e)var n="/"===e.substr(0,1)?location.origin+e:e;r.call(o,!t.ok(i)&&i,i.response||i.responseText,n)}}),i.send(),i},loadDocument:function(e,t,n){this.load(e,t,n).responseType="document"}};e.xhr=t}),HTMLImports.addModule(function(e){var t=e.xhr,n=e.flags,r=function(e,t){this.cache={},this.onload=e,this.oncomplete=t,this.inflight=0,this.pending={}};r.prototype={addNodes:function(e){this.inflight+=e.length;for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)this.require(t);this.checkDone()},addNode:function(e){this.inflight++,this.require(e),this.checkDone()},require:function(e){var t=e.src||e.href;e.__nodeUrl=t,this.dedupe(t,e)||this.fetch(t,e)},dedupe:function(e,t){if(this.pending[e])return this.pending[e].push(t),!0;return this.cache[e]?(this.onload(e,t,this.cache[e]),this.tail(),!0):(this.pending[e]=[t],!1)},fetch:function(e,r){if(n.load&&console.log("fetch",e,r),e)if(e.match(/^data:/)){var o=e.split(","),i=o[0],a=o[1];a=i.indexOf(";base64")>-1?atob(a):decodeURIComponent(a),setTimeout(function(){this.receive(e,r,null,a)}.bind(this),0)}else{var s=function(t,n,o){this.receive(e,r,t,n,o)}.bind(this);t.load(e,s)}else setTimeout(function(){this.receive(e,r,{error:"href must be specified"},null)}.bind(this),0)},receive:function(e,t,n,r,o){this.cache[e]=r;for(var i,a=this.pending[e],s=0,c=a.length;c>s&&(i=a[s]);s++)this.onload(e,i,r,n,o),this.tail();this.pending[e]=null},tail:function(){--this.inflight,this.checkDone()},checkDone:function(){this.inflight||this.oncomplete()}},e.Loader=r}),HTMLImports.addModule(function(e){var t=function(e){this.addCallback=e,this.mo=new MutationObserver(this.handler.bind(this))};t.prototype={handler:function(e){for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)"childList"===t.type&&t.addedNodes.length&&this.addedNodes(t.addedNodes)},addedNodes:function(e){this.addCallback&&this.addCallback(e);for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)t.children&&t.children.length&&this.addedNodes(t.children)},observe:function(e){this.mo.observe(e,{childList:!0,subtree:!0})}},e.Observer=t}),HTMLImports.addModule(function(e){function t(e){return"link"===e.localName&&e.rel===l}function n(e){var t=r(e);return"data:text/javascript;charset=utf-8,"+encodeURIComponent(t)}function r(e){return e.textContent+o(e)}function o(e){var t=e.ownerDocument;t.__importedScripts=t.__importedScripts||0;var n=e.ownerDocument.baseURI,r=t.__importedScripts?"-"+t.__importedScripts:"";return t.__importedScripts++,"\n//# sourceURL="+n+r+".js\n"}function i(e){var t=e.ownerDocument.createElement("style");return t.textContent=e.textContent,a.resolveUrlsInStyle(t),t}var a=e.path,s=e.rootDocument,c=e.flags,d=e.isIE,l=e.IMPORT_LINK_TYPE,u="link[rel="+l+"]",m={documentSelectors:u,importsSelectors:[u,"link[rel=stylesheet]","style","script:not([type])",'script[type="text/javascript"]'].join(","),map:{link:"parseLink",script:"parseScript",style:"parseStyle"},dynamicElements:[],parseNext:function(){var e=this.nextToParse();e&&this.parse(e)},parse:function(e){if(this.isParsed(e))return void(c.parse&&console.log("[%s] is already parsed",e.localName));var t=this[this.map[e.localName]];t&&(this.markParsing(e),t.call(this,e))},parseDynamic:function(e,t){this.dynamicElements.push(e),t||this.parseNext()},markParsing:function(e){c.parse&&console.log("parsing",e),this.parsingElement=e},markParsingComplete:function(e){e.__importParsed=!0,this.markDynamicParsingComplete(e),e.__importElement&&(e.__importElement.__importParsed=!0,this.markDynamicParsingComplete(e.__importElement)),this.parsingElement=null,c.parse&&console.log("completed",e)},markDynamicParsingComplete:function(e){var t=this.dynamicElements.indexOf(e);t>=0&&this.dynamicElements.splice(t,1)},parseImport:function(e){if(HTMLImports.__importsParsingHook&&HTMLImports.__importsParsingHook(e),e["import"]&&(e["import"].__importParsed=!0),this.markParsingComplete(e),e.dispatchEvent(e.__resource&&!e.__error?new CustomEvent("load",{bubbles:!1}):new CustomEvent("error",{bubbles:!1})),e.__pending)for(var t;e.__pending.length;)t=e.__pending.shift(),t&&t({target:e});this.parseNext()},parseLink:function(e){t(e)?this.parseImport(e):(e.href=e.href,this.parseGeneric(e))},parseStyle:function(e){var t=e;e=i(e),e.__importElement=t,this.parseGeneric(e)},parseGeneric:function(e){this.trackElement(e),this.addElementToDocument(e)},rootImportForElement:function(e){for(var t=e;t.ownerDocument.__importLink;)t=t.ownerDocument.__importLink;return t},addElementToDocument:function(e){var t=this.rootImportForElement(e.__importElement||e);t.parentNode.insertBefore(e,t)},trackElement:function(e,t){var n=this,r=function(r){t&&t(r),n.markParsingComplete(e),n.parseNext()};if(e.addEventListener("load",r),e.addEventListener("error",r),d&&"style"===e.localName){var o=!1;if(-1==e.textContent.indexOf("@import"))o=!0;else if(e.sheet){o=!0;for(var i,a=e.sheet.cssRules,s=a?a.length:0,c=0;s>c&&(i=a[c]);c++)i.type===CSSRule.IMPORT_RULE&&(o=o&&Boolean(i.styleSheet))}o&&e.dispatchEvent(new CustomEvent("load",{bubbles:!1}))}},parseScript:function(t){var r=document.createElement("script");r.__importElement=t,r.src=t.src?t.src:n(t),e.currentScript=t,this.trackElement(r,function(){r.parentNode.removeChild(r),e.currentScript=null}),this.addElementToDocument(r)},nextToParse:function(){return this._mayParse=[],!this.parsingElement&&(this.nextToParseInDoc(s)||this.nextToParseDynamic())},nextToParseInDoc:function(e,n){if(e&&this._mayParse.indexOf(e)<0){this._mayParse.push(e);for(var r,o=e.querySelectorAll(this.parseSelectorsForNode(e)),i=0,a=o.length;a>i&&(r=o[i]);i++)if(!this.isParsed(r))return this.hasResource(r)?t(r)?this.nextToParseInDoc(r["import"],r):r:void 0}return n},nextToParseDynamic:function(){return this.dynamicElements[0]},parseSelectorsForNode:function(e){var t=e.ownerDocument||e;return t===s?this.documentSelectors:this.importsSelectors},isParsed:function(e){return e.__importParsed},needsDynamicParsing:function(e){return this.dynamicElements.indexOf(e)>=0},hasResource:function(e){return t(e)&&void 0===e["import"]?!1:!0}};e.parser=m,e.IMPORT_SELECTOR=u}),HTMLImports.addModule(function(e){function t(e){return n(e,a)}function n(e,t){return"link"===e.localName&&e.getAttribute("rel")===t}function r(e){return!!Object.getOwnPropertyDescriptor(e,"baseURI")}function o(e,t){var n=document.implementation.createHTMLDocument(a);n._URL=t;var o=n.createElement("base");o.setAttribute("href",t),n.baseURI||r(n)||Object.defineProperty(n,"baseURI",{value:t});var i=n.createElement("meta");return i.setAttribute("charset","utf-8"),n.head.appendChild(i),n.head.appendChild(o),n.body.innerHTML=e,window.HTMLTemplateElement&&HTMLTemplateElement.bootstrap&&HTMLTemplateElement.bootstrap(n),n}var i=e.flags,a=e.IMPORT_LINK_TYPE,s=e.IMPORT_SELECTOR,c=e.rootDocument,d=e.Loader,l=e.Observer,u=e.parser,m={documents:{},documentPreloadSelectors:s,importsPreloadSelectors:[s].join(","),loadNode:function(e){p.addNode(e)},loadSubtree:function(e){var t=this.marshalNodes(e);p.addNodes(t)},marshalNodes:function(e){return e.querySelectorAll(this.loadSelectorsForNode(e))},loadSelectorsForNode:function(e){var t=e.ownerDocument||e;return t===c?this.documentPreloadSelectors:this.importsPreloadSelectors},loaded:function(e,n,r,a,s){if(i.load&&console.log("loaded",e,n),n.__resource=r,n.__error=a,t(n)){var c=this.documents[e];void 0===c&&(c=a?null:o(r,s||e),c&&(c.__importLink=n,this.bootDocument(c)),this.documents[e]=c),n["import"]=c}u.parseNext()},bootDocument:function(e){this.loadSubtree(e),this.observer.observe(e),u.parseNext()},loadedAll:function(){u.parseNext()}},p=new d(m.loaded.bind(m),m.loadedAll.bind(m));if(m.observer=new l,!document.baseURI){var h={get:function(){var e=document.querySelector("base");return e?e.href:window.location.href},configurable:!0};Object.defineProperty(document,"baseURI",h),Object.defineProperty(c,"baseURI",h)}e.importer=m,e.importLoader=p}),HTMLImports.addModule(function(e){var t=e.parser,n=e.importer,r={added:function(e){for(var r,o,i,a,s=0,c=e.length;c>s&&(a=e[s]);s++)r||(r=a.ownerDocument,o=t.isParsed(r)),i=this.shouldLoadNode(a),i&&n.loadNode(a),this.shouldParseNode(a)&&o&&t.parseDynamic(a,i)},shouldLoadNode:function(e){return 1===e.nodeType&&o.call(e,n.loadSelectorsForNode(e))},shouldParseNode:function(e){return 1===e.nodeType&&o.call(e,t.parseSelectorsForNode(e))}};n.observer.addCallback=r.added.bind(r);var o=HTMLElement.prototype.matches||HTMLElement.prototype.matchesSelector||HTMLElement.prototype.webkitMatchesSelector||HTMLElement.prototype.mozMatchesSelector||HTMLElement.prototype.msMatchesSelector}),function(e){function t(){HTMLImports.importer.bootDocument(o)}var n=e.initializeModules,r=e.isIE;if(!e.useNative){r&&"function"!=typeof window.CustomEvent&&(window.CustomEvent=function(e,t){t=t||{};var n=document.createEvent("CustomEvent");return n.initCustomEvent(e,Boolean(t.bubbles),Boolean(t.cancelable),t.detail),n},window.CustomEvent.prototype=window.Event.prototype),n();var o=e.rootDocument;"complete"===document.readyState||"interactive"===document.readyState&&!window.attachEvent?t():document.addEventListener("DOMContentLoaded",t)}}(HTMLImports);
\ No newline at end of file
diff --git a/example/bower_components/webcomponentsjs/README.md b/example/bower_components/webcomponentsjs/README.md
deleted file mode 100644
index 49ed2b64f..000000000
--- a/example/bower_components/webcomponentsjs/README.md
+++ /dev/null
@@ -1,73 +0,0 @@
-webcomponents.js
-================
-
-[![Join the chat at https://gitter.im/webcomponents/webcomponentsjs](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/webcomponents/webcomponentsjs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-
-A suite of polyfills supporting the [Web Components](http://webcomponents.org) specs:
-
-**Custom Elements**: allows authors to define their own custom tags ([spec](https://w3c.github.io/webcomponents/spec/custom/)).
-
-**HTML Imports**: a way to include and reuse HTML documents via other HTML documents ([spec](https://w3c.github.io/webcomponents/spec/imports/)).
-
-**Shadow DOM**: provides encapsulation by hiding DOM subtrees under shadow roots ([spec](https://w3c.github.io/webcomponents/spec/shadow/)).
-
-This also folds in polyfills for `MutationObserver` and `WeakMap`.
-
-
-## Releases
-
-Pre-built (concatenated & minified) versions of the polyfills are maintained in the [tagged versions](https://github.com/webcomponents/webcomponentsjs/releases) of this repo. There are two variants:
-
-`webcomponents.js` includes all of the polyfills.
-
-`webcomponents-lite.js` includes all polyfills except for shadow DOM.
-
-
-## Browser Support
-
-Our polyfills are intended to work in the latest versions of evergreen browsers. See below
-for our complete browser support matrix:
-
-| Polyfill   | IE10 | IE11+ | Chrome* | Firefox* | Safari 7+* | Chrome Android* | Mobile Safari* |
-| ---------- |:----:|:-----:|:-------:|:--------:|:----------:|:---------------:|:--------------:|
-| Custom Elements | ~ | ✓ | ✓ | ✓ | ✓ | ✓| ✓ |
-| HTML Imports | ~ | ✓ | ✓ | ✓ | ✓| ✓| ✓ |
-| Shadow DOM | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
-| Templates | ✓ | ✓ | ✓ | ✓| ✓ | ✓ | ✓ |
-
-
-*Indicates the current version of the browser
-
-~Indicates support may be flaky. If using Custom Elements or HTML Imports with Shadow DOM,
-you will get the non-flaky Mutation Observer polyfill that Shadow DOM includes.
-
-The polyfills may work in older browsers, however require additional polyfills (such as classList)
-to be used. We cannot guarantee support for browsers outside of our compatibility matrix.
-
-
-### Manually Building
-
-If you wish to build the polyfills yourself, you'll need `node` and `gulp` on your system:
-
- * install [node.js](http://nodejs.org/) using the instructions on their website
- * use `npm` to install [gulp.js](http://gulpjs.com/): `npm install -g gulp`
-
-Now you are ready to build the polyfills with:
-
-    # install dependencies
-    npm install
-    # build
-    gulp build
-
-The builds will be placed into the `dist/` directory.
-
-## Contribute
-
-See the [contributing guide](CONTRIBUTING.md)
-
-## License
-
-Everything in this repository is BSD style license unless otherwise specified.
-
-Copyright (c) 2015 The Polymer Authors. All rights reserved.
-
diff --git a/example/bower_components/webcomponentsjs/ShadowDOM.js b/example/bower_components/webcomponentsjs/ShadowDOM.js
deleted file mode 100644
index fb5c08f34..000000000
--- a/example/bower_components/webcomponentsjs/ShadowDOM.js
+++ /dev/null
@@ -1,4277 +0,0 @@
-/**
- * @license
- * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
- * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
- * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
- * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
- * Code distributed by Google as part of the polymer project is also
- * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
- */
-// @version 0.5.5
-if (typeof WeakMap === "undefined") {
-  (function() {
-    var defineProperty = Object.defineProperty;
-    var counter = Date.now() % 1e9;
-    var WeakMap = function() {
-      this.name = "__st" + (Math.random() * 1e9 >>> 0) + (counter++ + "__");
-    };
-    WeakMap.prototype = {
-      set: function(key, value) {
-        var entry = key[this.name];
-        if (entry && entry[0] === key) entry[1] = value; else defineProperty(key, this.name, {
-          value: [ key, value ],
-          writable: true
-        });
-        return this;
-      },
-      get: function(key) {
-        var entry;
-        return (entry = key[this.name]) && entry[0] === key ? entry[1] : undefined;
-      },
-      "delete": function(key) {
-        var entry = key[this.name];
-        if (!entry || entry[0] !== key) return false;
-        entry[0] = entry[1] = undefined;
-        return true;
-      },
-      has: function(key) {
-        var entry = key[this.name];
-        if (!entry) return false;
-        return entry[0] === key;
-      }
-    };
-    window.WeakMap = WeakMap;
-  })();
-}
-
-window.ShadowDOMPolyfill = {};
-
-(function(scope) {
-  "use strict";
-  var constructorTable = new WeakMap();
-  var nativePrototypeTable = new WeakMap();
-  var wrappers = Object.create(null);
-  function detectEval() {
-    if (typeof chrome !== "undefined" && chrome.app && chrome.app.runtime) {
-      return false;
-    }
-    if (navigator.getDeviceStorage) {
-      return false;
-    }
-    try {
-      var f = new Function("return true;");
-      return f();
-    } catch (ex) {
-      return false;
-    }
-  }
-  var hasEval = detectEval();
-  function assert(b) {
-    if (!b) throw new Error("Assertion failed");
-  }
-  var defineProperty = Object.defineProperty;
-  var getOwnPropertyNames = Object.getOwnPropertyNames;
-  var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
-  function mixin(to, from) {
-    var names = getOwnPropertyNames(from);
-    for (var i = 0; i < names.length; i++) {
-      var name = names[i];
-      defineProperty(to, name, getOwnPropertyDescriptor(from, name));
-    }
-    return to;
-  }
-  function mixinStatics(to, from) {
-    var names = getOwnPropertyNames(from);
-    for (var i = 0; i < names.length; i++) {
-      var name = names[i];
-      switch (name) {
-       case "arguments":
-       case "caller":
-       case "length":
-       case "name":
-       case "prototype":
-       case "toString":
-        continue;
-      }
-      defineProperty(to, name, getOwnPropertyDescriptor(from, name));
-    }
-    return to;
-  }
-  function oneOf(object, propertyNames) {
-    for (var i = 0; i < propertyNames.length; i++) {
-      if (propertyNames[i] in object) return propertyNames[i];
-    }
-  }
-  var nonEnumerableDataDescriptor = {
-    value: undefined,
-    configurable: true,
-    enumerable: false,
-    writable: true
-  };
-  function defineNonEnumerableDataProperty(object, name, value) {
-    nonEnumerableDataDescriptor.value = value;
-    defineProperty(object, name, nonEnumerableDataDescriptor);
-  }
-  getOwnPropertyNames(window);
-  function getWrapperConstructor(node) {
-    var nativePrototype = node.__proto__ || Object.getPrototypeOf(node);
-    if (isFirefox) {
-      try {
-        getOwnPropertyNames(nativePrototype);
-      } catch (error) {
-        nativePrototype = nativePrototype.__proto__;
-      }
-    }
-    var wrapperConstructor = constructorTable.get(nativePrototype);
-    if (wrapperConstructor) return wrapperConstructor;
-    var parentWrapperConstructor = getWrapperConstructor(nativePrototype);
-    var GeneratedWrapper = createWrapperConstructor(parentWrapperConstructor);
-    registerInternal(nativePrototype, GeneratedWrapper, node);
-    return GeneratedWrapper;
-  }
-  function addForwardingProperties(nativePrototype, wrapperPrototype) {
-    installProperty(nativePrototype, wrapperPrototype, true);
-  }
-  function registerInstanceProperties(wrapperPrototype, instanceObject) {
-    installProperty(instanceObject, wrapperPrototype, false);
-  }
-  var isFirefox = /Firefox/.test(navigator.userAgent);
-  var dummyDescriptor = {
-    get: function() {},
-    set: function(v) {},
-    configurable: true,
-    enumerable: true
-  };
-  function isEventHandlerName(name) {
-    return /^on[a-z]+$/.test(name);
-  }
-  function isIdentifierName(name) {
-    return /^\w[a-zA-Z_0-9]*$/.test(name);
-  }
-  function getGetter(name) {
-    return hasEval && isIdentifierName(name) ? new Function("return this.__impl4cf1e782hg__." + name) : function() {
-      return this.__impl4cf1e782hg__[name];
-    };
-  }
-  function getSetter(name) {
-    return hasEval && isIdentifierName(name) ? new Function("v", "this.__impl4cf1e782hg__." + name + " = v") : function(v) {
-      this.__impl4cf1e782hg__[name] = v;
-    };
-  }
-  function getMethod(name) {
-    return hasEval && isIdentifierName(name) ? new Function("return this.__impl4cf1e782hg__." + name + ".apply(this.__impl4cf1e782hg__, arguments)") : function() {
-      return this.__impl4cf1e782hg__[name].apply(this.__impl4cf1e782hg__, arguments);
-    };
-  }
-  function getDescriptor(source, name) {
-    try {
-      return Object.getOwnPropertyDescriptor(source, name);
-    } catch (ex) {
-      return dummyDescriptor;
-    }
-  }
-  var isBrokenSafari = function() {
-    var descr = Object.getOwnPropertyDescriptor(Node.prototype, "nodeType");
-    return descr && !descr.get && !descr.set;
-  }();
-  function installProperty(source, target, allowMethod, opt_blacklist) {
-    var names = getOwnPropertyNames(source);
-    for (var i = 0; i < names.length; i++) {
-      var name = names[i];
-      if (name === "polymerBlackList_") continue;
-      if (name in target) continue;
-      if (source.polymerBlackList_ && source.polymerBlackList_[name]) continue;
-      if (isFirefox) {
-        source.__lookupGetter__(name);
-      }
-      var descriptor = getDescriptor(source, name);
-      var getter, setter;
-      if (allowMethod && typeof descriptor.value === "function") {
-        target[name] = getMethod(name);
-        continue;
-      }
-      var isEvent = isEventHandlerName(name);
-      if (isEvent) getter = scope.getEventHandlerGetter(name); else getter = getGetter(name);
-      if (descriptor.writable || descriptor.set || isBrokenSafari) {
-        if (isEvent) setter = scope.getEventHandlerSetter(name); else setter = getSetter(name);
-      }
-      var configurable = isBrokenSafari || descriptor.configurable;
-      defineProperty(target, name, {
-        get: getter,
-        set: setter,
-        configurable: configurable,
-        enumerable: descriptor.enumerable
-      });
-    }
-  }
-  function register(nativeConstructor, wrapperConstructor, opt_instance) {
-    var nativePrototype = nativeConstructor.prototype;
-    registerInternal(nativePrototype, wrapperConstructor, opt_instance);
-    mixinStatics(wrapperConstructor, nativeConstructor);
-  }
-  function registerInternal(nativePrototype, wrapperConstructor, opt_instance) {
-    var wrapperPrototype = wrapperConstructor.prototype;
-    assert(constructorTable.get(nativePrototype) === undefined);
-    constructorTable.set(nativePrototype, wrapperConstructor);
-    nativePrototypeTable.set(wrapperPrototype, nativePrototype);
-    addForwardingProperties(nativePrototype, wrapperPrototype);
-    if (opt_instance) registerInstanceProperties(wrapperPrototype, opt_instance);
-    defineNonEnumerableDataProperty(wrapperPrototype, "constructor", wrapperConstructor);
-    wrapperConstructor.prototype = wrapperPrototype;
-  }
-  function isWrapperFor(wrapperConstructor, nativeConstructor) {
-    return constructorTable.get(nativeConstructor.prototype) === wrapperConstructor;
-  }
-  function registerObject(object) {
-    var nativePrototype = Object.getPrototypeOf(object);
-    var superWrapperConstructor = getWrapperConstructor(nativePrototype);
-    var GeneratedWrapper = createWrapperConstructor(superWrapperConstructor);
-    registerInternal(nativePrototype, GeneratedWrapper, object);
-    return GeneratedWrapper;
-  }
-  function createWrapperConstructor(superWrapperConstructor) {
-    function GeneratedWrapper(node) {
-      superWrapperConstructor.call(this, node);
-    }
-    var p = Object.create(superWrapperConstructor.prototype);
-    p.constructor = GeneratedWrapper;
-    GeneratedWrapper.prototype = p;
-    return GeneratedWrapper;
-  }
-  function isWrapper(object) {
-    return object && object.__impl4cf1e782hg__;
-  }
-  function isNative(object) {
-    return !isWrapper(object);
-  }
-  function wrap(impl) {
-    if (impl === null) return null;
-    assert(isNative(impl));
-    return impl.__wrapper8e3dd93a60__ || (impl.__wrapper8e3dd93a60__ = new (getWrapperConstructor(impl))(impl));
-  }
-  function unwrap(wrapper) {
-    if (wrapper === null) return null;
-    assert(isWrapper(wrapper));
-    return wrapper.__impl4cf1e782hg__;
-  }
-  function unsafeUnwrap(wrapper) {
-    return wrapper.__impl4cf1e782hg__;
-  }
-  function setWrapper(impl, wrapper) {
-    wrapper.__impl4cf1e782hg__ = impl;
-    impl.__wrapper8e3dd93a60__ = wrapper;
-  }
-  function unwrapIfNeeded(object) {
-    return object && isWrapper(object) ? unwrap(object) : object;
-  }
-  function wrapIfNeeded(object) {
-    return object && !isWrapper(object) ? wrap(object) : object;
-  }
-  function rewrap(node, wrapper) {
-    if (wrapper === null) return;
-    assert(isNative(node));
-    assert(wrapper === undefined || isWrapper(wrapper));
-    node.__wrapper8e3dd93a60__ = wrapper;
-  }
-  var getterDescriptor = {
-    get: undefined,
-    configurable: true,
-    enumerable: true
-  };
-  function defineGetter(constructor, name, getter) {
-    getterDescriptor.get = getter;
-    defineProperty(constructor.prototype, name, getterDescriptor);
-  }
-  function defineWrapGetter(constructor, name) {
-    defineGetter(constructor, name, function() {
-      return wrap(this.__impl4cf1e782hg__[name]);
-    });
-  }
-  function forwardMethodsToWrapper(constructors, names) {
-    constructors.forEach(function(constructor) {
-      names.forEach(function(name) {
-        constructor.prototype[name] = function() {
-          var w = wrapIfNeeded(this);
-          return w[name].apply(w, arguments);
-        };
-      });
-    });
-  }
-  scope.assert = assert;
-  scope.constructorTable = constructorTable;
-  scope.defineGetter = defineGetter;
-  scope.defineWrapGetter = defineWrapGetter;
-  scope.forwardMethodsToWrapper = forwardMethodsToWrapper;
-  scope.isWrapper = isWrapper;
-  scope.isWrapperFor = isWrapperFor;
-  scope.mixin = mixin;
-  scope.nativePrototypeTable = nativePrototypeTable;
-  scope.oneOf = oneOf;
-  scope.registerObject = registerObject;
-  scope.registerWrapper = register;
-  scope.rewrap = rewrap;
-  scope.setWrapper = setWrapper;
-  scope.unsafeUnwrap = unsafeUnwrap;
-  scope.unwrap = unwrap;
-  scope.unwrapIfNeeded = unwrapIfNeeded;
-  scope.wrap = wrap;
-  scope.wrapIfNeeded = wrapIfNeeded;
-  scope.wrappers = wrappers;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  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;
-    }
-  };
-  scope.ArraySplice = ArraySplice;
-})(window.ShadowDOMPolyfill);
-
-(function(context) {
-  "use strict";
-  var OriginalMutationObserver = window.MutationObserver;
-  var callbacks = [];
-  var pending = false;
-  var timerFunc;
-  function handle() {
-    pending = false;
-    var copies = callbacks.slice(0);
-    callbacks = [];
-    for (var i = 0; i < copies.length; i++) {
-      (0, copies[i])();
-    }
-  }
-  if (OriginalMutationObserver) {
-    var counter = 1;
-    var observer = new OriginalMutationObserver(handle);
-    var textNode = document.createTextNode(counter);
-    observer.observe(textNode, {
-      characterData: true
-    });
-    timerFunc = function() {
-      counter = (counter + 1) % 2;
-      textNode.data = counter;
-    };
-  } else {
-    timerFunc = window.setTimeout;
-  }
-  function setEndOfMicrotask(func) {
-    callbacks.push(func);
-    if (pending) return;
-    pending = true;
-    timerFunc(handle, 0);
-  }
-  context.setEndOfMicrotask = setEndOfMicrotask;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var setEndOfMicrotask = scope.setEndOfMicrotask;
-  var wrapIfNeeded = scope.wrapIfNeeded;
-  var wrappers = scope.wrappers;
-  var registrationsTable = new WeakMap();
-  var globalMutationObservers = [];
-  var isScheduled = false;
-  function scheduleCallback(observer) {
-    if (observer.scheduled_) return;
-    observer.scheduled_ = true;
-    globalMutationObservers.push(observer);
-    if (isScheduled) return;
-    setEndOfMicrotask(notifyObservers);
-    isScheduled = true;
-  }
-  function notifyObservers() {
-    isScheduled = false;
-    while (globalMutationObservers.length) {
-      var notifyList = globalMutationObservers;
-      globalMutationObservers = [];
-      notifyList.sort(function(x, y) {
-        return x.uid_ - y.uid_;
-      });
-      for (var i = 0; i < notifyList.length; i++) {
-        var mo = notifyList[i];
-        mo.scheduled_ = false;
-        var queue = mo.takeRecords();
-        removeTransientObserversFor(mo);
-        if (queue.length) {
-          mo.callback_(queue, mo);
-        }
-      }
-    }
-  }
-  function MutationRecord(type, target) {
-    this.type = type;
-    this.target = target;
-    this.addedNodes = new wrappers.NodeList();
-    this.removedNodes = new wrappers.NodeList();
-    this.previousSibling = null;
-    this.nextSibling = null;
-    this.attributeName = null;
-    this.attributeNamespace = null;
-    this.oldValue = null;
-  }
-  function registerTransientObservers(ancestor, node) {
-    for (;ancestor; ancestor = ancestor.parentNode) {
-      var registrations = registrationsTable.get(ancestor);
-      if (!registrations) continue;
-      for (var i = 0; i < registrations.length; i++) {
-        var registration = registrations[i];
-        if (registration.options.subtree) registration.addTransientObserver(node);
-      }
-    }
-  }
-  function removeTransientObserversFor(observer) {
-    for (var i = 0; i < observer.nodes_.length; i++) {
-      var node = observer.nodes_[i];
-      var registrations = registrationsTable.get(node);
-      if (!registrations) return;
-      for (var j = 0; j < registrations.length; j++) {
-        var registration = registrations[j];
-        if (registration.observer === observer) registration.removeTransientObservers();
-      }
-    }
-  }
-  function enqueueMutation(target, type, data) {
-    var interestedObservers = Object.create(null);
-    var associatedStrings = Object.create(null);
-    for (var node = target; node; node = node.parentNode) {
-      var registrations = registrationsTable.get(node);
-      if (!registrations) continue;
-      for (var j = 0; j < registrations.length; j++) {
-        var registration = registrations[j];
-        var options = registration.options;
-        if (node !== target && !options.subtree) continue;
-        if (type === "attributes" && !options.attributes) continue;
-        if (type === "attributes" && options.attributeFilter && (data.namespace !== null || options.attributeFilter.indexOf(data.name) === -1)) {
-          continue;
-        }
-        if (type === "characterData" && !options.characterData) continue;
-        if (type === "childList" && !options.childList) continue;
-        var observer = registration.observer;
-        interestedObservers[observer.uid_] = observer;
-        if (type === "attributes" && options.attributeOldValue || type === "characterData" && options.characterDataOldValue) {
-          associatedStrings[observer.uid_] = data.oldValue;
-        }
-      }
-    }
-    for (var uid in interestedObservers) {
-      var observer = interestedObservers[uid];
-      var record = new MutationRecord(type, target);
-      if ("name" in data && "namespace" in data) {
-        record.attributeName = data.name;
-        record.attributeNamespace = data.namespace;
-      }
-      if (data.addedNodes) record.addedNodes = data.addedNodes;
-      if (data.removedNodes) record.removedNodes = data.removedNodes;
-      if (data.previousSibling) record.previousSibling = data.previousSibling;
-      if (data.nextSibling) record.nextSibling = data.nextSibling;
-      if (associatedStrings[uid] !== undefined) record.oldValue = associatedStrings[uid];
-      scheduleCallback(observer);
-      observer.records_.push(record);
-    }
-  }
-  var slice = Array.prototype.slice;
-  function MutationObserverOptions(options) {
-    this.childList = !!options.childList;
-    this.subtree = !!options.subtree;
-    if (!("attributes" in options) && ("attributeOldValue" in options || "attributeFilter" in options)) {
-      this.attributes = true;
-    } else {
-      this.attributes = !!options.attributes;
-    }
-    if ("characterDataOldValue" in options && !("characterData" in options)) this.characterData = true; else this.characterData = !!options.characterData;
-    if (!this.attributes && (options.attributeOldValue || "attributeFilter" in options) || !this.characterData && options.characterDataOldValue) {
-      throw new TypeError();
-    }
-    this.characterData = !!options.characterData;
-    this.attributeOldValue = !!options.attributeOldValue;
-    this.characterDataOldValue = !!options.characterDataOldValue;
-    if ("attributeFilter" in options) {
-      if (options.attributeFilter == null || typeof options.attributeFilter !== "object") {
-        throw new TypeError();
-      }
-      this.attributeFilter = slice.call(options.attributeFilter);
-    } else {
-      this.attributeFilter = null;
-    }
-  }
-  var uidCounter = 0;
-  function MutationObserver(callback) {
-    this.callback_ = callback;
-    this.nodes_ = [];
-    this.records_ = [];
-    this.uid_ = ++uidCounter;
-    this.scheduled_ = false;
-  }
-  MutationObserver.prototype = {
-    constructor: MutationObserver,
-    observe: function(target, options) {
-      target = wrapIfNeeded(target);
-      var newOptions = new MutationObserverOptions(options);
-      var registration;
-      var registrations = registrationsTable.get(target);
-      if (!registrations) registrationsTable.set(target, registrations = []);
-      for (var i = 0; i < registrations.length; i++) {
-        if (registrations[i].observer === this) {
-          registration = registrations[i];
-          registration.removeTransientObservers();
-          registration.options = newOptions;
-        }
-      }
-      if (!registration) {
-        registration = new Registration(this, target, newOptions);
-        registrations.push(registration);
-        this.nodes_.push(target);
-      }
-    },
-    disconnect: function() {
-      this.nodes_.forEach(function(node) {
-        var registrations = registrationsTable.get(node);
-        for (var i = 0; i < registrations.length; i++) {
-          var registration = registrations[i];
-          if (registration.observer === this) {
-            registrations.splice(i, 1);
-            break;
-          }
-        }
-      }, this);
-      this.records_ = [];
-    },
-    takeRecords: function() {
-      var copyOfRecords = this.records_;
-      this.records_ = [];
-      return copyOfRecords;
-    }
-  };
-  function Registration(observer, target, options) {
-    this.observer = observer;
-    this.target = target;
-    this.options = options;
-    this.transientObservedNodes = [];
-  }
-  Registration.prototype = {
-    addTransientObserver: function(node) {
-      if (node === this.target) return;
-      scheduleCallback(this.observer);
-      this.transientObservedNodes.push(node);
-      var registrations = registrationsTable.get(node);
-      if (!registrations) registrationsTable.set(node, registrations = []);
-      registrations.push(this);
-    },
-    removeTransientObservers: function() {
-      var transientObservedNodes = this.transientObservedNodes;
-      this.transientObservedNodes = [];
-      for (var i = 0; i < transientObservedNodes.length; i++) {
-        var node = transientObservedNodes[i];
-        var registrations = registrationsTable.get(node);
-        for (var j = 0; j < registrations.length; j++) {
-          if (registrations[j] === this) {
-            registrations.splice(j, 1);
-            break;
-          }
-        }
-      }
-    }
-  };
-  scope.enqueueMutation = enqueueMutation;
-  scope.registerTransientObservers = registerTransientObservers;
-  scope.wrappers.MutationObserver = MutationObserver;
-  scope.wrappers.MutationRecord = MutationRecord;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  function TreeScope(root, parent) {
-    this.root = root;
-    this.parent = parent;
-  }
-  TreeScope.prototype = {
-    get renderer() {
-      if (this.root instanceof scope.wrappers.ShadowRoot) {
-        return scope.getRendererForHost(this.root.host);
-      }
-      return null;
-    },
-    contains: function(treeScope) {
-      for (;treeScope; treeScope = treeScope.parent) {
-        if (treeScope === this) return true;
-      }
-      return false;
-    }
-  };
-  function setTreeScope(node, treeScope) {
-    if (node.treeScope_ !== treeScope) {
-      node.treeScope_ = treeScope;
-      for (var sr = node.shadowRoot; sr; sr = sr.olderShadowRoot) {
-        sr.treeScope_.parent = treeScope;
-      }
-      for (var child = node.firstChild; child; child = child.nextSibling) {
-        setTreeScope(child, treeScope);
-      }
-    }
-  }
-  function getTreeScope(node) {
-    if (node instanceof scope.wrappers.Window) {
-      debugger;
-    }
-    if (node.treeScope_) return node.treeScope_;
-    var parent = node.parentNode;
-    var treeScope;
-    if (parent) treeScope = getTreeScope(parent); else treeScope = new TreeScope(node, null);
-    return node.treeScope_ = treeScope;
-  }
-  scope.TreeScope = TreeScope;
-  scope.getTreeScope = getTreeScope;
-  scope.setTreeScope = setTreeScope;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
-  var getTreeScope = scope.getTreeScope;
-  var mixin = scope.mixin;
-  var registerWrapper = scope.registerWrapper;
-  var setWrapper = scope.setWrapper;
-  var unsafeUnwrap = scope.unsafeUnwrap;
-  var unwrap = scope.unwrap;
-  var wrap = scope.wrap;
-  var wrappers = scope.wrappers;
-  var wrappedFuns = new WeakMap();
-  var listenersTable = new WeakMap();
-  var handledEventsTable = new WeakMap();
-  var currentlyDispatchingEvents = new WeakMap();
-  var targetTable = new WeakMap();
-  var currentTargetTable = new WeakMap();
-  var relatedTargetTable = new WeakMap();
-  var eventPhaseTable = new WeakMap();
-  var stopPropagationTable = new WeakMap();
-  var stopImmediatePropagationTable = new WeakMap();
-  var eventHandlersTable = new WeakMap();
-  var eventPathTable = new WeakMap();
-  function isShadowRoot(node) {
-    return node instanceof wrappers.ShadowRoot;
-  }
-  function rootOfNode(node) {
-    return getTreeScope(node).root;
-  }
-  function getEventPath(node, event) {
-    var path = [];
-    var current = node;
-    path.push(current);
-    while (current) {
-      var destinationInsertionPoints = getDestinationInsertionPoints(current);
-      if (destinationInsertionPoints && destinationInsertionPoints.length > 0) {
-        for (var i = 0; i < destinationInsertionPoints.length; i++) {
-          var insertionPoint = destinationInsertionPoints[i];
-          if (isShadowInsertionPoint(insertionPoint)) {
-            var shadowRoot = rootOfNode(insertionPoint);
-            var olderShadowRoot = shadowRoot.olderShadowRoot;
-            if (olderShadowRoot) path.push(olderShadowRoot);
-          }
-          path.push(insertionPoint);
-        }
-        current = destinationInsertionPoints[destinationInsertionPoints.length - 1];
-      } else {
-        if (isShadowRoot(current)) {
-          if (inSameTree(node, current) && eventMustBeStopped(event)) {
-            break;
-          }
-          current = current.host;
-          path.push(current);
-        } else {
-          current = current.parentNode;
-          if (current) path.push(current);
-        }
-      }
-    }
-    return path;
-  }
-  function eventMustBeStopped(event) {
-    if (!event) return false;
-    switch (event.type) {
-     case "abort":
-     case "error":
-     case "select":
-     case "change":
-     case "load":
-     case "reset":
-     case "resize":
-     case "scroll":
-     case "selectstart":
-      return true;
-    }
-    return false;
-  }
-  function isShadowInsertionPoint(node) {
-    return node instanceof HTMLShadowElement;
-  }
-  function getDestinationInsertionPoints(node) {
-    return scope.getDestinationInsertionPoints(node);
-  }
-  function eventRetargetting(path, currentTarget) {
-    if (path.length === 0) return currentTarget;
-    if (currentTarget instanceof wrappers.Window) currentTarget = currentTarget.document;
-    var currentTargetTree = getTreeScope(currentTarget);
-    var originalTarget = path[0];
-    var originalTargetTree = getTreeScope(originalTarget);
-    var relativeTargetTree = lowestCommonInclusiveAncestor(currentTargetTree, originalTargetTree);
-    for (var i = 0; i < path.length; i++) {
-      var node = path[i];
-      if (getTreeScope(node) === relativeTargetTree) return node;
-    }
-    return path[path.length - 1];
-  }
-  function getTreeScopeAncestors(treeScope) {
-    var ancestors = [];
-    for (;treeScope; treeScope = treeScope.parent) {
-      ancestors.push(treeScope);
-    }
-    return ancestors;
-  }
-  function lowestCommonInclusiveAncestor(tsA, tsB) {
-    var ancestorsA = getTreeScopeAncestors(tsA);
-    var ancestorsB = getTreeScopeAncestors(tsB);
-    var result = null;
-    while (ancestorsA.length > 0 && ancestorsB.length > 0) {
-      var a = ancestorsA.pop();
-      var b = ancestorsB.pop();
-      if (a === b) result = a; else break;
-    }
-    return result;
-  }
-  function getTreeScopeRoot(ts) {
-    if (!ts.parent) return ts;
-    return getTreeScopeRoot(ts.parent);
-  }
-  function relatedTargetResolution(event, currentTarget, relatedTarget) {
-    if (currentTarget instanceof wrappers.Window) currentTarget = currentTarget.document;
-    var currentTargetTree = getTreeScope(currentTarget);
-    var relatedTargetTree = getTreeScope(relatedTarget);
-    var relatedTargetEventPath = getEventPath(relatedTarget, event);
-    var lowestCommonAncestorTree;
-    var lowestCommonAncestorTree = lowestCommonInclusiveAncestor(currentTargetTree, relatedTargetTree);
-    if (!lowestCommonAncestorTree) lowestCommonAncestorTree = relatedTargetTree.root;
-    for (var commonAncestorTree = lowestCommonAncestorTree; commonAncestorTree; commonAncestorTree = commonAncestorTree.parent) {
-      var adjustedRelatedTarget;
-      for (var i = 0; i < relatedTargetEventPath.length; i++) {
-        var node = relatedTargetEventPath[i];
-        if (getTreeScope(node) === commonAncestorTree) return node;
-      }
-    }
-    return null;
-  }
-  function inSameTree(a, b) {
-    return getTreeScope(a) === getTreeScope(b);
-  }
-  var NONE = 0;
-  var CAPTURING_PHASE = 1;
-  var AT_TARGET = 2;
-  var BUBBLING_PHASE = 3;
-  var pendingError;
-  function dispatchOriginalEvent(originalEvent) {
-    if (handledEventsTable.get(originalEvent)) return;
-    handledEventsTable.set(originalEvent, true);
-    dispatchEvent(wrap(originalEvent), wrap(originalEvent.target));
-    if (pendingError) {
-      var err = pendingError;
-      pendingError = null;
-      throw err;
-    }
-  }
-  function isLoadLikeEvent(event) {
-    switch (event.type) {
-     case "load":
-     case "beforeunload":
-     case "unload":
-      return true;
-    }
-    return false;
-  }
-  function dispatchEvent(event, originalWrapperTarget) {
-    if (currentlyDispatchingEvents.get(event)) throw new Error("InvalidStateError");
-    currentlyDispatchingEvents.set(event, true);
-    scope.renderAllPending();
-    var eventPath;
-    var overrideTarget;
-    var win;
-    if (isLoadLikeEvent(event) && !event.bubbles) {
-      var doc = originalWrapperTarget;
-      if (doc instanceof wrappers.Document && (win = doc.defaultView)) {
-        overrideTarget = doc;
-        eventPath = [];
-      }
-    }
-    if (!eventPath) {
-      if (originalWrapperTarget instanceof wrappers.Window) {
-        win = originalWrapperTarget;
-        eventPath = [];
-      } else {
-        eventPath = getEventPath(originalWrapperTarget, event);
-        if (!isLoadLikeEvent(event)) {
-          var doc = eventPath[eventPath.length - 1];
-          if (doc instanceof wrappers.Document) win = doc.defaultView;
-        }
-      }
-    }
-    eventPathTable.set(event, eventPath);
-    if (dispatchCapturing(event, eventPath, win, overrideTarget)) {
-      if (dispatchAtTarget(event, eventPath, win, overrideTarget)) {
-        dispatchBubbling(event, eventPath, win, overrideTarget);
-      }
-    }
-    eventPhaseTable.set(event, NONE);
-    currentTargetTable.delete(event, null);
-    currentlyDispatchingEvents.delete(event);
-    return event.defaultPrevented;
-  }
-  function dispatchCapturing(event, eventPath, win, overrideTarget) {
-    var phase = CAPTURING_PHASE;
-    if (win) {
-      if (!invoke(win, event, phase, eventPath, overrideTarget)) return false;
-    }
-    for (var i = eventPath.length - 1; i > 0; i--) {
-      if (!invoke(eventPath[i], event, phase, eventPath, overrideTarget)) return false;
-    }
-    return true;
-  }
-  function dispatchAtTarget(event, eventPath, win, overrideTarget) {
-    var phase = AT_TARGET;
-    var currentTarget = eventPath[0] || win;
-    return invoke(currentTarget, event, phase, eventPath, overrideTarget);
-  }
-  function dispatchBubbling(event, eventPath, win, overrideTarget) {
-    var phase = BUBBLING_PHASE;
-    for (var i = 1; i < eventPath.length; i++) {
-      if (!invoke(eventPath[i], event, phase, eventPath, overrideTarget)) return;
-    }
-    if (win && eventPath.length > 0) {
-      invoke(win, event, phase, eventPath, overrideTarget);
-    }
-  }
-  function invoke(currentTarget, event, phase, eventPath, overrideTarget) {
-    var listeners = listenersTable.get(currentTarget);
-    if (!listeners) return true;
-    var target = overrideTarget || eventRetargetting(eventPath, currentTarget);
-    if (target === currentTarget) {
-      if (phase === CAPTURING_PHASE) return true;
-      if (phase === BUBBLING_PHASE) phase = AT_TARGET;
-    } else if (phase === BUBBLING_PHASE && !event.bubbles) {
-      return true;
-    }
-    if ("relatedTarget" in event) {
-      var originalEvent = unwrap(event);
-      var unwrappedRelatedTarget = originalEvent.relatedTarget;
-      if (unwrappedRelatedTarget) {
-        if (unwrappedRelatedTarget instanceof Object && unwrappedRelatedTarget.addEventListener) {
-          var relatedTarget = wrap(unwrappedRelatedTarget);
-          var adjusted = relatedTargetResolution(event, currentTarget, relatedTarget);
-          if (adjusted === target) return true;
-        } else {
-          adjusted = null;
-        }
-        relatedTargetTable.set(event, adjusted);
-      }
-    }
-    eventPhaseTable.set(event, phase);
-    var type = event.type;
-    var anyRemoved = false;
-    targetTable.set(event, target);
-    currentTargetTable.set(event, currentTarget);
-    listeners.depth++;
-    for (var i = 0, len = listeners.length; i < len; i++) {
-      var listener = listeners[i];
-      if (listener.removed) {
-        anyRemoved = true;
-        continue;
-      }
-      if (listener.type !== type || !listener.capture && phase === CAPTURING_PHASE || listener.capture && phase === BUBBLING_PHASE) {
-        continue;
-      }
-      try {
-        if (typeof listener.handler === "function") listener.handler.call(currentTarget, event); else listener.handler.handleEvent(event);
-        if (stopImmediatePropagationTable.get(event)) return false;
-      } catch (ex) {
-        if (!pendingError) pendingError = ex;
-      }
-    }
-    listeners.depth--;
-    if (anyRemoved && listeners.depth === 0) {
-      var copy = listeners.slice();
-      listeners.length = 0;
-      for (var i = 0; i < copy.length; i++) {
-        if (!copy[i].removed) listeners.push(copy[i]);
-      }
-    }
-    return !stopPropagationTable.get(event);
-  }
-  function Listener(type, handler, capture) {
-    this.type = type;
-    this.handler = handler;
-    this.capture = Boolean(capture);
-  }
-  Listener.prototype = {
-    equals: function(that) {
-      return this.handler === that.handler && this.type === that.type && this.capture === that.capture;
-    },
-    get removed() {
-      return this.handler === null;
-    },
-    remove: function() {
-      this.handler = null;
-    }
-  };
-  var OriginalEvent = window.Event;
-  OriginalEvent.prototype.polymerBlackList_ = {
-    returnValue: true,
-    keyLocation: true
-  };
-  function Event(type, options) {
-    if (type instanceof OriginalEvent) {
-      var impl = type;
-      if (!OriginalBeforeUnloadEvent && impl.type === "beforeunload" && !(this instanceof BeforeUnloadEvent)) {
-        return new BeforeUnloadEvent(impl);
-      }
-      setWrapper(impl, this);
-    } else {
-      return wrap(constructEvent(OriginalEvent, "Event", type, options));
-    }
-  }
-  Event.prototype = {
-    get target() {
-      return targetTable.get(this);
-    },
-    get currentTarget() {
-      return currentTargetTable.get(this);
-    },
-    get eventPhase() {
-      return eventPhaseTable.get(this);
-    },
-    get path() {
-      var eventPath = eventPathTable.get(this);
-      if (!eventPath) return [];
-      return eventPath.slice();
-    },
-    stopPropagation: function() {
-      stopPropagationTable.set(this, true);
-    },
-    stopImmediatePropagation: function() {
-      stopPropagationTable.set(this, true);
-      stopImmediatePropagationTable.set(this, true);
-    }
-  };
-  registerWrapper(OriginalEvent, Event, document.createEvent("Event"));
-  function unwrapOptions(options) {
-    if (!options || !options.relatedTarget) return options;
-    return Object.create(options, {
-      relatedTarget: {
-        value: unwrap(options.relatedTarget)
-      }
-    });
-  }
-  function registerGenericEvent(name, SuperEvent, prototype) {
-    var OriginalEvent = window[name];
-    var GenericEvent = function(type, options) {
-      if (type instanceof OriginalEvent) setWrapper(type, this); else return wrap(constructEvent(OriginalEvent, name, type, options));
-    };
-    GenericEvent.prototype = Object.create(SuperEvent.prototype);
-    if (prototype) mixin(GenericEvent.prototype, prototype);
-    if (OriginalEvent) {
-      try {
-        registerWrapper(OriginalEvent, GenericEvent, new OriginalEvent("temp"));
-      } catch (ex) {
-        registerWrapper(OriginalEvent, GenericEvent, document.createEvent(name));
-      }
-    }
-    return GenericEvent;
-  }
-  var UIEvent = registerGenericEvent("UIEvent", Event);
-  var CustomEvent = registerGenericEvent("CustomEvent", Event);
-  var relatedTargetProto = {
-    get relatedTarget() {
-      var relatedTarget = relatedTargetTable.get(this);
-      if (relatedTarget !== undefined) return relatedTarget;
-      return wrap(unwrap(this).relatedTarget);
-    }
-  };
-  function getInitFunction(name, relatedTargetIndex) {
-    return function() {
-      arguments[relatedTargetIndex] = unwrap(arguments[relatedTargetIndex]);
-      var impl = unwrap(this);
-      impl[name].apply(impl, arguments);
-    };
-  }
-  var mouseEventProto = mixin({
-    initMouseEvent: getInitFunction("initMouseEvent", 14)
-  }, relatedTargetProto);
-  var focusEventProto = mixin({
-    initFocusEvent: getInitFunction("initFocusEvent", 5)
-  }, relatedTargetProto);
-  var MouseEvent = registerGenericEvent("MouseEvent", UIEvent, mouseEventProto);
-  var FocusEvent = registerGenericEvent("FocusEvent", UIEvent, focusEventProto);
-  var defaultInitDicts = Object.create(null);
-  var supportsEventConstructors = function() {
-    try {
-      new window.FocusEvent("focus");
-    } catch (ex) {
-      return false;
-    }
-    return true;
-  }();
-  function constructEvent(OriginalEvent, name, type, options) {
-    if (supportsEventConstructors) return new OriginalEvent(type, unwrapOptions(options));
-    var event = unwrap(document.createEvent(name));
-    var defaultDict = defaultInitDicts[name];
-    var args = [ type ];
-    Object.keys(defaultDict).forEach(function(key) {
-      var v = options != null && key in options ? options[key] : defaultDict[key];
-      if (key === "relatedTarget") v = unwrap(v);
-      args.push(v);
-    });
-    event["init" + name].apply(event, args);
-    return event;
-  }
-  if (!supportsEventConstructors) {
-    var configureEventConstructor = function(name, initDict, superName) {
-      if (superName) {
-        var superDict = defaultInitDicts[superName];
-        initDict = mixin(mixin({}, superDict), initDict);
-      }
-      defaultInitDicts[name] = initDict;
-    };
-    configureEventConstructor("Event", {
-      bubbles: false,
-      cancelable: false
-    });
-    configureEventConstructor("CustomEvent", {
-      detail: null
-    }, "Event");
-    configureEventConstructor("UIEvent", {
-      view: null,
-      detail: 0
-    }, "Event");
-    configureEventConstructor("MouseEvent", {
-      screenX: 0,
-      screenY: 0,
-      clientX: 0,
-      clientY: 0,
-      ctrlKey: false,
-      altKey: false,
-      shiftKey: false,
-      metaKey: false,
-      button: 0,
-      relatedTarget: null
-    }, "UIEvent");
-    configureEventConstructor("FocusEvent", {
-      relatedTarget: null
-    }, "UIEvent");
-  }
-  var OriginalBeforeUnloadEvent = window.BeforeUnloadEvent;
-  function BeforeUnloadEvent(impl) {
-    Event.call(this, impl);
-  }
-  BeforeUnloadEvent.prototype = Object.create(Event.prototype);
-  mixin(BeforeUnloadEvent.prototype, {
-    get returnValue() {
-      return unsafeUnwrap(this).returnValue;
-    },
-    set returnValue(v) {
-      unsafeUnwrap(this).returnValue = v;
-    }
-  });
-  if (OriginalBeforeUnloadEvent) registerWrapper(OriginalBeforeUnloadEvent, BeforeUnloadEvent);
-  function isValidListener(fun) {
-    if (typeof fun === "function") return true;
-    return fun && fun.handleEvent;
-  }
-  function isMutationEvent(type) {
-    switch (type) {
-     case "DOMAttrModified":
-     case "DOMAttributeNameChanged":
-     case "DOMCharacterDataModified":
-     case "DOMElementNameChanged":
-     case "DOMNodeInserted":
-     case "DOMNodeInsertedIntoDocument":
-     case "DOMNodeRemoved":
-     case "DOMNodeRemovedFromDocument":
-     case "DOMSubtreeModified":
-      return true;
-    }
-    return false;
-  }
-  var OriginalEventTarget = window.EventTarget;
-  function EventTarget(impl) {
-    setWrapper(impl, this);
-  }
-  var methodNames = [ "addEventListener", "removeEventListener", "dispatchEvent" ];
-  [ Node, Window ].forEach(function(constructor) {
-    var p = constructor.prototype;
-    methodNames.forEach(function(name) {
-      Object.defineProperty(p, name + "_", {
-        value: p[name]
-      });
-    });
-  });
-  function getTargetToListenAt(wrapper) {
-    if (wrapper instanceof wrappers.ShadowRoot) wrapper = wrapper.host;
-    return unwrap(wrapper);
-  }
-  EventTarget.prototype = {
-    addEventListener: function(type, fun, capture) {
-      if (!isValidListener(fun) || isMutationEvent(type)) return;
-      var listener = new Listener(type, fun, capture);
-      var listeners = listenersTable.get(this);
-      if (!listeners) {
-        listeners = [];
-        listeners.depth = 0;
-        listenersTable.set(this, listeners);
-      } else {
-        for (var i = 0; i < listeners.length; i++) {
-          if (listener.equals(listeners[i])) return;
-        }
-      }
-      listeners.push(listener);
-      var target = getTargetToListenAt(this);
-      target.addEventListener_(type, dispatchOriginalEvent, true);
-    },
-    removeEventListener: function(type, fun, capture) {
-      capture = Boolean(capture);
-      var listeners = listenersTable.get(this);
-      if (!listeners) return;
-      var count = 0, found = false;
-      for (var i = 0; i < listeners.length; i++) {
-        if (listeners[i].type === type && listeners[i].capture === capture) {
-          count++;
-          if (listeners[i].handler === fun) {
-            found = true;
-            listeners[i].remove();
-          }
-        }
-      }
-      if (found && count === 1) {
-        var target = getTargetToListenAt(this);
-        target.removeEventListener_(type, dispatchOriginalEvent, true);
-      }
-    },
-    dispatchEvent: function(event) {
-      var nativeEvent = unwrap(event);
-      var eventType = nativeEvent.type;
-      handledEventsTable.set(nativeEvent, false);
-      scope.renderAllPending();
-      var tempListener;
-      if (!hasListenerInAncestors(this, eventType)) {
-        tempListener = function() {};
-        this.addEventListener(eventType, tempListener, true);
-      }
-      try {
-        return unwrap(this).dispatchEvent_(nativeEvent);
-      } finally {
-        if (tempListener) this.removeEventListener(eventType, tempListener, true);
-      }
-    }
-  };
-  function hasListener(node, type) {
-    var listeners = listenersTable.get(node);
-    if (listeners) {
-      for (var i = 0; i < listeners.length; i++) {
-        if (!listeners[i].removed && listeners[i].type === type) return true;
-      }
-    }
-    return false;
-  }
-  function hasListenerInAncestors(target, type) {
-    for (var node = unwrap(target); node; node = node.parentNode) {
-      if (hasListener(wrap(node), type)) return true;
-    }
-    return false;
-  }
-  if (OriginalEventTarget) registerWrapper(OriginalEventTarget, EventTarget);
-  function wrapEventTargetMethods(constructors) {
-    forwardMethodsToWrapper(constructors, methodNames);
-  }
-  var originalElementFromPoint = document.elementFromPoint;
-  function elementFromPoint(self, document, x, y) {
-    scope.renderAllPending();
-    var element = wrap(originalElementFromPoint.call(unsafeUnwrap(document), x, y));
-    if (!element) return null;
-    var path = getEventPath(element, null);
-    var idx = path.lastIndexOf(self);
-    if (idx == -1) return null; else path = path.slice(0, idx);
-    return eventRetargetting(path, self);
-  }
-  function getEventHandlerGetter(name) {
-    return function() {
-      var inlineEventHandlers = eventHandlersTable.get(this);
-      return inlineEventHandlers && inlineEventHandlers[name] && inlineEventHandlers[name].value || null;
-    };
-  }
-  function getEventHandlerSetter(name) {
-    var eventType = name.slice(2);
-    return function(value) {
-      var inlineEventHandlers = eventHandlersTable.get(this);
-      if (!inlineEventHandlers) {
-        inlineEventHandlers = Object.create(null);
-        eventHandlersTable.set(this, inlineEventHandlers);
-      }
-      var old = inlineEventHandlers[name];
-      if (old) this.removeEventListener(eventType, old.wrapped, false);
-      if (typeof value === "function") {
-        var wrapped = function(e) {
-          var rv = value.call(this, e);
-          if (rv === false) e.preventDefault(); else if (name === "onbeforeunload" && typeof rv === "string") e.returnValue = rv;
-        };
-        this.addEventListener(eventType, wrapped, false);
-        inlineEventHandlers[name] = {
-          value: value,
-          wrapped: wrapped
-        };
-      }
-    };
-  }
-  scope.elementFromPoint = elementFromPoint;
-  scope.getEventHandlerGetter = getEventHandlerGetter;
-  scope.getEventHandlerSetter = getEventHandlerSetter;
-  scope.wrapEventTargetMethods = wrapEventTargetMethods;
-  scope.wrappers.BeforeUnloadEvent = BeforeUnloadEvent;
-  scope.wrappers.CustomEvent = CustomEvent;
-  scope.wrappers.Event = Event;
-  scope.wrappers.EventTarget = EventTarget;
-  scope.wrappers.FocusEvent = FocusEvent;
-  scope.wrappers.MouseEvent = MouseEvent;
-  scope.wrappers.UIEvent = UIEvent;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var UIEvent = scope.wrappers.UIEvent;
-  var mixin = scope.mixin;
-  var registerWrapper = scope.registerWrapper;
-  var setWrapper = scope.setWrapper;
-  var unsafeUnwrap = scope.unsafeUnwrap;
-  var wrap = scope.wrap;
-  var OriginalTouchEvent = window.TouchEvent;
-  if (!OriginalTouchEvent) return;
-  var nativeEvent;
-  try {
-    nativeEvent = document.createEvent("TouchEvent");
-  } catch (ex) {
-    return;
-  }
-  var nonEnumDescriptor = {
-    enumerable: false
-  };
-  function nonEnum(obj, prop) {
-    Object.defineProperty(obj, prop, nonEnumDescriptor);
-  }
-  function Touch(impl) {
-    setWrapper(impl, this);
-  }
-  Touch.prototype = {
-    get target() {
-      return wrap(unsafeUnwrap(this).target);
-    }
-  };
-  var descr = {
-    configurable: true,
-    enumerable: true,
-    get: null
-  };
-  [ "clientX", "clientY", "screenX", "screenY", "pageX", "pageY", "identifier", "webkitRadiusX", "webkitRadiusY", "webkitRotationAngle", "webkitForce" ].forEach(function(name) {
-    descr.get = function() {
-      return unsafeUnwrap(this)[name];
-    };
-    Object.defineProperty(Touch.prototype, name, descr);
-  });
-  function TouchList() {
-    this.length = 0;
-    nonEnum(this, "length");
-  }
-  TouchList.prototype = {
-    item: function(index) {
-      return this[index];
-    }
-  };
-  function wrapTouchList(nativeTouchList) {
-    var list = new TouchList();
-    for (var i = 0; i < nativeTouchList.length; i++) {
-      list[i] = new Touch(nativeTouchList[i]);
-    }
-    list.length = i;
-    return list;
-  }
-  function TouchEvent(impl) {
-    UIEvent.call(this, impl);
-  }
-  TouchEvent.prototype = Object.create(UIEvent.prototype);
-  mixin(TouchEvent.prototype, {
-    get touches() {
-      return wrapTouchList(unsafeUnwrap(this).touches);
-    },
-    get targetTouches() {
-      return wrapTouchList(unsafeUnwrap(this).targetTouches);
-    },
-    get changedTouches() {
-      return wrapTouchList(unsafeUnwrap(this).changedTouches);
-    },
-    initTouchEvent: function() {
-      throw new Error("Not implemented");
-    }
-  });
-  registerWrapper(OriginalTouchEvent, TouchEvent, nativeEvent);
-  scope.wrappers.Touch = Touch;
-  scope.wrappers.TouchEvent = TouchEvent;
-  scope.wrappers.TouchList = TouchList;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var unsafeUnwrap = scope.unsafeUnwrap;
-  var wrap = scope.wrap;
-  var nonEnumDescriptor = {
-    enumerable: false
-  };
-  function nonEnum(obj, prop) {
-    Object.defineProperty(obj, prop, nonEnumDescriptor);
-  }
-  function NodeList() {
-    this.length = 0;
-    nonEnum(this, "length");
-  }
-  NodeList.prototype = {
-    item: function(index) {
-      return this[index];
-    }
-  };
-  nonEnum(NodeList.prototype, "item");
-  function wrapNodeList(list) {
-    if (list == null) return list;
-    var wrapperList = new NodeList();
-    for (var i = 0, length = list.length; i < length; i++) {
-      wrapperList[i] = wrap(list[i]);
-    }
-    wrapperList.length = length;
-    return wrapperList;
-  }
-  function addWrapNodeListMethod(wrapperConstructor, name) {
-    wrapperConstructor.prototype[name] = function() {
-      return wrapNodeList(unsafeUnwrap(this)[name].apply(unsafeUnwrap(this), arguments));
-    };
-  }
-  scope.wrappers.NodeList = NodeList;
-  scope.addWrapNodeListMethod = addWrapNodeListMethod;
-  scope.wrapNodeList = wrapNodeList;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  scope.wrapHTMLCollection = scope.wrapNodeList;
-  scope.wrappers.HTMLCollection = scope.wrappers.NodeList;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var EventTarget = scope.wrappers.EventTarget;
-  var NodeList = scope.wrappers.NodeList;
-  var TreeScope = scope.TreeScope;
-  var assert = scope.assert;
-  var defineWrapGetter = scope.defineWrapGetter;
-  var enqueueMutation = scope.enqueueMutation;
-  var getTreeScope = scope.getTreeScope;
-  var isWrapper = scope.isWrapper;
-  var mixin = scope.mixin;
-  var registerTransientObservers = scope.registerTransientObservers;
-  var registerWrapper = scope.registerWrapper;
-  var setTreeScope = scope.setTreeScope;
-  var unsafeUnwrap = scope.unsafeUnwrap;
-  var unwrap = scope.unwrap;
-  var unwrapIfNeeded = scope.unwrapIfNeeded;
-  var wrap = scope.wrap;
-  var wrapIfNeeded = scope.wrapIfNeeded;
-  var wrappers = scope.wrappers;
-  function assertIsNodeWrapper(node) {
-    assert(node instanceof Node);
-  }
-  function createOneElementNodeList(node) {
-    var nodes = new NodeList();
-    nodes[0] = node;
-    nodes.length = 1;
-    return nodes;
-  }
-  var surpressMutations = false;
-  function enqueueRemovalForInsertedNodes(node, parent, nodes) {
-    enqueueMutation(parent, "childList", {
-      removedNodes: nodes,
-      previousSibling: node.previousSibling,
-      nextSibling: node.nextSibling
-    });
-  }
-  function enqueueRemovalForInsertedDocumentFragment(df, nodes) {
-    enqueueMutation(df, "childList", {
-      removedNodes: nodes
-    });
-  }
-  function collectNodes(node, parentNode, previousNode, nextNode) {
-    if (node instanceof DocumentFragment) {
-      var nodes = collectNodesForDocumentFragment(node);
-      surpressMutations = true;
-      for (var i = nodes.length - 1; i >= 0; i--) {
-        node.removeChild(nodes[i]);
-        nodes[i].parentNode_ = parentNode;
-      }
-      surpressMutations = false;
-      for (var i = 0; i < nodes.length; i++) {
-        nodes[i].previousSibling_ = nodes[i - 1] || previousNode;
-        nodes[i].nextSibling_ = nodes[i + 1] || nextNode;
-      }
-      if (previousNode) previousNode.nextSibling_ = nodes[0];
-      if (nextNode) nextNode.previousSibling_ = nodes[nodes.length - 1];
-      return nodes;
-    }
-    var nodes = createOneElementNodeList(node);
-    var oldParent = node.parentNode;
-    if (oldParent) {
-      oldParent.removeChild(node);
-    }
-    node.parentNode_ = parentNode;
-    node.previousSibling_ = previousNode;
-    node.nextSibling_ = nextNode;
-    if (previousNode) previousNode.nextSibling_ = node;
-    if (nextNode) nextNode.previousSibling_ = node;
-    return nodes;
-  }
-  function collectNodesNative(node) {
-    if (node instanceof DocumentFragment) return collectNodesForDocumentFragment(node);
-    var nodes = createOneElementNodeList(node);
-    var oldParent = node.parentNode;
-    if (oldParent) enqueueRemovalForInsertedNodes(node, oldParent, nodes);
-    return nodes;
-  }
-  function collectNodesForDocumentFragment(node) {
-    var nodes = new NodeList();
-    var i = 0;
-    for (var child = node.firstChild; child; child = child.nextSibling) {
-      nodes[i++] = child;
-    }
-    nodes.length = i;
-    enqueueRemovalForInsertedDocumentFragment(node, nodes);
-    return nodes;
-  }
-  function snapshotNodeList(nodeList) {
-    return nodeList;
-  }
-  function nodeWasAdded(node, treeScope) {
-    setTreeScope(node, treeScope);
-    node.nodeIsInserted_();
-  }
-  function nodesWereAdded(nodes, parent) {
-    var treeScope = getTreeScope(parent);
-    for (var i = 0; i < nodes.length; i++) {
-      nodeWasAdded(nodes[i], treeScope);
-    }
-  }
-  function nodeWasRemoved(node) {
-    setTreeScope(node, new TreeScope(node, null));
-  }
-  function nodesWereRemoved(nodes) {
-    for (var i = 0; i < nodes.length; i++) {
-      nodeWasRemoved(nodes[i]);
-    }
-  }
-  function ensureSameOwnerDocument(parent, child) {
-    var ownerDoc = parent.nodeType === Node.DOCUMENT_NODE ? parent : parent.ownerDocument;
-    if (ownerDoc !== child.ownerDocument) ownerDoc.adoptNode(child);
-  }
-  function adoptNodesIfNeeded(owner, nodes) {
-    if (!nodes.length) return;
-    var ownerDoc = owner.ownerDocument;
-    if (ownerDoc === nodes[0].ownerDocument) return;
-    for (var i = 0; i < nodes.length; i++) {
-      scope.adoptNodeNoRemove(nodes[i], ownerDoc);
-    }
-  }
-  function unwrapNodesForInsertion(owner, nodes) {
-    adoptNodesIfNeeded(owner, nodes);
-    var length = nodes.length;
-    if (length === 1) return unwrap(nodes[0]);
-    var df = unwrap(owner.ownerDocument.createDocumentFragment());
-    for (var i = 0; i < length; i++) {
-      df.appendChild(unwrap(nodes[i]));
-    }
-    return df;
-  }
-  function clearChildNodes(wrapper) {
-    if (wrapper.firstChild_ !== undefined) {
-      var child = wrapper.firstChild_;
-      while (child) {
-        var tmp = child;
-        child = child.nextSibling_;
-        tmp.parentNode_ = tmp.previousSibling_ = tmp.nextSibling_ = undefined;
-      }
-    }
-    wrapper.firstChild_ = wrapper.lastChild_ = undefined;
-  }
-  function removeAllChildNodes(wrapper) {
-    if (wrapper.invalidateShadowRenderer()) {
-      var childWrapper = wrapper.firstChild;
-      while (childWrapper) {
-        assert(childWrapper.parentNode === wrapper);
-        var nextSibling = childWrapper.nextSibling;
-        var childNode = unwrap(childWrapper);
-        var parentNode = childNode.parentNode;
-        if (parentNode) originalRemoveChild.call(parentNode, childNode);
-        childWrapper.previousSibling_ = childWrapper.nextSibling_ = childWrapper.parentNode_ = null;
-        childWrapper = nextSibling;
-      }
-      wrapper.firstChild_ = wrapper.lastChild_ = null;
-    } else {
-      var node = unwrap(wrapper);
-      var child = node.firstChild;
-      var nextSibling;
-      while (child) {
-        nextSibling = child.nextSibling;
-        originalRemoveChild.call(node, child);
-        child = nextSibling;
-      }
-    }
-  }
-  function invalidateParent(node) {
-    var p = node.parentNode;
-    return p && p.invalidateShadowRenderer();
-  }
-  function cleanupNodes(nodes) {
-    for (var i = 0, n; i < nodes.length; i++) {
-      n = nodes[i];
-      n.parentNode.removeChild(n);
-    }
-  }
-  var originalImportNode = document.importNode;
-  var originalCloneNode = window.Node.prototype.cloneNode;
-  function cloneNode(node, deep, opt_doc) {
-    var clone;
-    if (opt_doc) clone = wrap(originalImportNode.call(opt_doc, unsafeUnwrap(node), false)); else clone = wrap(originalCloneNode.call(unsafeUnwrap(node), false));
-    if (deep) {
-      for (var child = node.firstChild; child; child = child.nextSibling) {
-        clone.appendChild(cloneNode(child, true, opt_doc));
-      }
-      if (node instanceof wrappers.HTMLTemplateElement) {
-        var cloneContent = clone.content;
-        for (var child = node.content.firstChild; child; child = child.nextSibling) {
-          cloneContent.appendChild(cloneNode(child, true, opt_doc));
-        }
-      }
-    }
-    return clone;
-  }
-  function contains(self, child) {
-    if (!child || getTreeScope(self) !== getTreeScope(child)) return false;
-    for (var node = child; node; node = node.parentNode) {
-      if (node === self) return true;
-    }
-    return false;
-  }
-  var OriginalNode = window.Node;
-  function Node(original) {
-    assert(original instanceof OriginalNode);
-    EventTarget.call(this, original);
-    this.parentNode_ = undefined;
-    this.firstChild_ = undefined;
-    this.lastChild_ = undefined;
-    this.nextSibling_ = undefined;
-    this.previousSibling_ = undefined;
-    this.treeScope_ = undefined;
-  }
-  var OriginalDocumentFragment = window.DocumentFragment;
-  var originalAppendChild = OriginalNode.prototype.appendChild;
-  var originalCompareDocumentPosition = OriginalNode.prototype.compareDocumentPosition;
-  var originalInsertBefore = OriginalNode.prototype.insertBefore;
-  var originalRemoveChild = OriginalNode.prototype.removeChild;
-  var originalReplaceChild = OriginalNode.prototype.replaceChild;
-  var isIe = /Trident|Edge/.test(navigator.userAgent);
-  var removeChildOriginalHelper = isIe ? function(parent, child) {
-    try {
-      originalRemoveChild.call(parent, child);
-    } catch (ex) {
-      if (!(parent instanceof OriginalDocumentFragment)) throw ex;
-    }
-  } : function(parent, child) {
-    originalRemoveChild.call(parent, child);
-  };
-  Node.prototype = Object.create(EventTarget.prototype);
-  mixin(Node.prototype, {
-    appendChild: function(childWrapper) {
-      return this.insertBefore(childWrapper, null);
-    },
-    insertBefore: function(childWrapper, refWrapper) {
-      assertIsNodeWrapper(childWrapper);
-      var refNode;
-      if (refWrapper) {
-        if (isWrapper(refWrapper)) {
-          refNode = unwrap(refWrapper);
-        } else {
-          refNode = refWrapper;
-          refWrapper = wrap(refNode);
-        }
-      } else {
-        refWrapper = null;
-        refNode = null;
-      }
-      refWrapper && assert(refWrapper.parentNode === this);
-      var nodes;
-      var previousNode = refWrapper ? refWrapper.previousSibling : this.lastChild;
-      var useNative = !this.invalidateShadowRenderer() && !invalidateParent(childWrapper);
-      if (useNative) nodes = collectNodesNative(childWrapper); else nodes = collectNodes(childWrapper, this, previousNode, refWrapper);
-      if (useNative) {
-        ensureSameOwnerDocument(this, childWrapper);
-        clearChildNodes(this);
-        originalInsertBefore.call(unsafeUnwrap(this), unwrap(childWrapper), refNode);
-      } else {
-        if (!previousNode) this.firstChild_ = nodes[0];
-        if (!refWrapper) {
-          this.lastChild_ = nodes[nodes.length - 1];
-          if (this.firstChild_ === undefined) this.firstChild_ = this.firstChild;
-        }
-        var parentNode = refNode ? refNode.parentNode : unsafeUnwrap(this);
-        if (parentNode) {
-          originalInsertBefore.call(parentNode, unwrapNodesForInsertion(this, nodes), refNode);
-        } else {
-          adoptNodesIfNeeded(this, nodes);
-        }
-      }
-      enqueueMutation(this, "childList", {
-        addedNodes: nodes,
-        nextSibling: refWrapper,
-        previousSibling: previousNode
-      });
-      nodesWereAdded(nodes, this);
-      return childWrapper;
-    },
-    removeChild: function(childWrapper) {
-      assertIsNodeWrapper(childWrapper);
-      if (childWrapper.parentNode !== this) {
-        var found = false;
-        var childNodes = this.childNodes;
-        for (var ieChild = this.firstChild; ieChild; ieChild = ieChild.nextSibling) {
-          if (ieChild === childWrapper) {
-            found = true;
-            break;
-          }
-        }
-        if (!found) {
-          throw new Error("NotFoundError");
-        }
-      }
-      var childNode = unwrap(childWrapper);
-      var childWrapperNextSibling = childWrapper.nextSibling;
-      var childWrapperPreviousSibling = childWrapper.previousSibling;
-      if (this.invalidateShadowRenderer()) {
-        var thisFirstChild = this.firstChild;
-        var thisLastChild = this.lastChild;
-        var parentNode = childNode.parentNode;
-        if (parentNode) removeChildOriginalHelper(parentNode, childNode);
-        if (thisFirstChild === childWrapper) this.firstChild_ = childWrapperNextSibling;
-        if (thisLastChild === childWrapper) this.lastChild_ = childWrapperPreviousSibling;
-        if (childWrapperPreviousSibling) childWrapperPreviousSibling.nextSibling_ = childWrapperNextSibling;
-        if (childWrapperNextSibling) {
-          childWrapperNextSibling.previousSibling_ = childWrapperPreviousSibling;
-        }
-        childWrapper.previousSibling_ = childWrapper.nextSibling_ = childWrapper.parentNode_ = undefined;
-      } else {
-        clearChildNodes(this);
-        removeChildOriginalHelper(unsafeUnwrap(this), childNode);
-      }
-      if (!surpressMutations) {
-        enqueueMutation(this, "childList", {
-          removedNodes: createOneElementNodeList(childWrapper),
-          nextSibling: childWrapperNextSibling,
-          previousSibling: childWrapperPreviousSibling
-        });
-      }
-      registerTransientObservers(this, childWrapper);
-      return childWrapper;
-    },
-    replaceChild: function(newChildWrapper, oldChildWrapper) {
-      assertIsNodeWrapper(newChildWrapper);
-      var oldChildNode;
-      if (isWrapper(oldChildWrapper)) {
-        oldChildNode = unwrap(oldChildWrapper);
-      } else {
-        oldChildNode = oldChildWrapper;
-        oldChildWrapper = wrap(oldChildNode);
-      }
-      if (oldChildWrapper.parentNode !== this) {
-        throw new Error("NotFoundError");
-      }
-      var nextNode = oldChildWrapper.nextSibling;
-      var previousNode = oldChildWrapper.previousSibling;
-      var nodes;
-      var useNative = !this.invalidateShadowRenderer() && !invalidateParent(newChildWrapper);
-      if (useNative) {
-        nodes = collectNodesNative(newChildWrapper);
-      } else {
-        if (nextNode === newChildWrapper) nextNode = newChildWrapper.nextSibling;
-        nodes = collectNodes(newChildWrapper, this, previousNode, nextNode);
-      }
-      if (!useNative) {
-        if (this.firstChild === oldChildWrapper) this.firstChild_ = nodes[0];
-        if (this.lastChild === oldChildWrapper) this.lastChild_ = nodes[nodes.length - 1];
-        oldChildWrapper.previousSibling_ = oldChildWrapper.nextSibling_ = oldChildWrapper.parentNode_ = undefined;
-        if (oldChildNode.parentNode) {
-          originalReplaceChild.call(oldChildNode.parentNode, unwrapNodesForInsertion(this, nodes), oldChildNode);
-        }
-      } else {
-        ensureSameOwnerDocument(this, newChildWrapper);
-        clearChildNodes(this);
-        originalReplaceChild.call(unsafeUnwrap(this), unwrap(newChildWrapper), oldChildNode);
-      }
-      enqueueMutation(this, "childList", {
-        addedNodes: nodes,
-        removedNodes: createOneElementNodeList(oldChildWrapper),
-        nextSibling: nextNode,
-        previousSibling: previousNode
-      });
-      nodeWasRemoved(oldChildWrapper);
-      nodesWereAdded(nodes, this);
-      return oldChildWrapper;
-    },
-    nodeIsInserted_: function() {
-      for (var child = this.firstChild; child; child = child.nextSibling) {
-        child.nodeIsInserted_();
-      }
-    },
-    hasChildNodes: function() {
-      return this.firstChild !== null;
-    },
-    get parentNode() {
-      return this.parentNode_ !== undefined ? this.parentNode_ : wrap(unsafeUnwrap(this).parentNode);
-    },
-    get firstChild() {
-      return this.firstChild_ !== undefined ? this.firstChild_ : wrap(unsafeUnwrap(this).firstChild);
-    },
-    get lastChild() {
-      return this.lastChild_ !== undefined ? this.lastChild_ : wrap(unsafeUnwrap(this).lastChild);
-    },
-    get nextSibling() {
-      return this.nextSibling_ !== undefined ? this.nextSibling_ : wrap(unsafeUnwrap(this).nextSibling);
-    },
-    get previousSibling() {
-      return this.previousSibling_ !== undefined ? this.previousSibling_ : wrap(unsafeUnwrap(this).previousSibling);
-    },
-    get parentElement() {
-      var p = this.parentNode;
-      while (p && p.nodeType !== Node.ELEMENT_NODE) {
-        p = p.parentNode;
-      }
-      return p;
-    },
-    get textContent() {
-      var s = "";
-      for (var child = this.firstChild; child; child = child.nextSibling) {
-        if (child.nodeType != Node.COMMENT_NODE) {
-          s += child.textContent;
-        }
-      }
-      return s;
-    },
-    set textContent(textContent) {
-      if (textContent == null) textContent = "";
-      var removedNodes = snapshotNodeList(this.childNodes);
-      if (this.invalidateShadowRenderer()) {
-        removeAllChildNodes(this);
-        if (textContent !== "") {
-          var textNode = unsafeUnwrap(this).ownerDocument.createTextNode(textContent);
-          this.appendChild(textNode);
-        }
-      } else {
-        clearChildNodes(this);
-        unsafeUnwrap(this).textContent = textContent;
-      }
-      var addedNodes = snapshotNodeList(this.childNodes);
-      enqueueMutation(this, "childList", {
-        addedNodes: addedNodes,
-        removedNodes: removedNodes
-      });
-      nodesWereRemoved(removedNodes);
-      nodesWereAdded(addedNodes, this);
-    },
-    get childNodes() {
-      var wrapperList = new NodeList();
-      var i = 0;
-      for (var child = this.firstChild; child; child = child.nextSibling) {
-        wrapperList[i++] = child;
-      }
-      wrapperList.length = i;
-      return wrapperList;
-    },
-    cloneNode: function(deep) {
-      return cloneNode(this, deep);
-    },
-    contains: function(child) {
-      return contains(this, wrapIfNeeded(child));
-    },
-    compareDocumentPosition: function(otherNode) {
-      return originalCompareDocumentPosition.call(unsafeUnwrap(this), unwrapIfNeeded(otherNode));
-    },
-    normalize: function() {
-      var nodes = snapshotNodeList(this.childNodes);
-      var remNodes = [];
-      var s = "";
-      var modNode;
-      for (var i = 0, n; i < nodes.length; i++) {
-        n = nodes[i];
-        if (n.nodeType === Node.TEXT_NODE) {
-          if (!modNode && !n.data.length) this.removeChild(n); else if (!modNode) modNode = n; else {
-            s += n.data;
-            remNodes.push(n);
-          }
-        } else {
-          if (modNode && remNodes.length) {
-            modNode.data += s;
-            cleanupNodes(remNodes);
-          }
-          remNodes = [];
-          s = "";
-          modNode = null;
-          if (n.childNodes.length) n.normalize();
-        }
-      }
-      if (modNode && remNodes.length) {
-        modNode.data += s;
-        cleanupNodes(remNodes);
-      }
-    }
-  });
-  defineWrapGetter(Node, "ownerDocument");
-  registerWrapper(OriginalNode, Node, document.createDocumentFragment());
-  delete Node.prototype.querySelector;
-  delete Node.prototype.querySelectorAll;
-  Node.prototype = mixin(Object.create(EventTarget.prototype), Node.prototype);
-  scope.cloneNode = cloneNode;
-  scope.nodeWasAdded = nodeWasAdded;
-  scope.nodeWasRemoved = nodeWasRemoved;
-  scope.nodesWereAdded = nodesWereAdded;
-  scope.nodesWereRemoved = nodesWereRemoved;
-  scope.originalInsertBefore = originalInsertBefore;
-  scope.originalRemoveChild = originalRemoveChild;
-  scope.snapshotNodeList = snapshotNodeList;
-  scope.wrappers.Node = Node;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var HTMLCollection = scope.wrappers.HTMLCollection;
-  var NodeList = scope.wrappers.NodeList;
-  var getTreeScope = scope.getTreeScope;
-  var unsafeUnwrap = scope.unsafeUnwrap;
-  var wrap = scope.wrap;
-  var originalDocumentQuerySelector = document.querySelector;
-  var originalElementQuerySelector = document.documentElement.querySelector;
-  var originalDocumentQuerySelectorAll = document.querySelectorAll;
-  var originalElementQuerySelectorAll = document.documentElement.querySelectorAll;
-  var originalDocumentGetElementsByTagName = document.getElementsByTagName;
-  var originalElementGetElementsByTagName = document.documentElement.getElementsByTagName;
-  var originalDocumentGetElementsByTagNameNS = document.getElementsByTagNameNS;
-  var originalElementGetElementsByTagNameNS = document.documentElement.getElementsByTagNameNS;
-  var OriginalElement = window.Element;
-  var OriginalDocument = window.HTMLDocument || window.Document;
-  function filterNodeList(list, index, result, deep) {
-    var wrappedItem = null;
-    var root = null;
-    for (var i = 0, length = list.length; i < length; i++) {
-      wrappedItem = wrap(list[i]);
-      if (!deep && (root = getTreeScope(wrappedItem).root)) {
-        if (root instanceof scope.wrappers.ShadowRoot) {
-          continue;
-        }
-      }
-      result[index++] = wrappedItem;
-    }
-    return index;
-  }
-  function shimSelector(selector) {
-    return String(selector).replace(/\/deep\/|::shadow/g, " ");
-  }
-  function shimMatchesSelector(selector) {
-    return String(selector).replace(/:host\(([^\s]+)\)/g, "$1").replace(/([^\s]):host/g, "$1").replace(":host", "*").replace(/\^|\/shadow\/|\/shadow-deep\/|::shadow|\/deep\/|::content/g, " ");
-  }
-  function findOne(node, selector) {
-    var m, el = node.firstElementChild;
-    while (el) {
-      if (el.matches(selector)) return el;
-      m = findOne(el, selector);
-      if (m) return m;
-      el = el.nextElementSibling;
-    }
-    return null;
-  }
-  function matchesSelector(el, selector) {
-    return el.matches(selector);
-  }
-  var XHTML_NS = "http://www.w3.org/1999/xhtml";
-  function matchesTagName(el, localName, localNameLowerCase) {
-    var ln = el.localName;
-    return ln === localName || ln === localNameLowerCase && el.namespaceURI === XHTML_NS;
-  }
-  function matchesEveryThing() {
-    return true;
-  }
-  function matchesLocalNameOnly(el, ns, localName) {
-    return el.localName === localName;
-  }
-  function matchesNameSpace(el, ns) {
-    return el.namespaceURI === ns;
-  }
-  function matchesLocalNameNS(el, ns, localName) {
-    return el.namespaceURI === ns && el.localName === localName;
-  }
-  function findElements(node, index, result, p, arg0, arg1) {
-    var el = node.firstElementChild;
-    while (el) {
-      if (p(el, arg0, arg1)) result[index++] = el;
-      index = findElements(el, index, result, p, arg0, arg1);
-      el = el.nextElementSibling;
-    }
-    return index;
-  }
-  function querySelectorAllFiltered(p, index, result, selector, deep) {
-    var target = unsafeUnwrap(this);
-    var list;
-    var root = getTreeScope(this).root;
-    if (root instanceof scope.wrappers.ShadowRoot) {
-      return findElements(this, index, result, p, selector, null);
-    } else if (target instanceof OriginalElement) {
-      list = originalElementQuerySelectorAll.call(target, selector);
-    } else if (target instanceof OriginalDocument) {
-      list = originalDocumentQuerySelectorAll.call(target, selector);
-    } else {
-      return findElements(this, index, result, p, selector, null);
-    }
-    return filterNodeList(list, index, result, deep);
-  }
-  var SelectorsInterface = {
-    querySelector: function(selector) {
-      var shimmed = shimSelector(selector);
-      var deep = shimmed !== selector;
-      selector = shimmed;
-      var target = unsafeUnwrap(this);
-      var wrappedItem;
-      var root = getTreeScope(this).root;
-      if (root instanceof scope.wrappers.ShadowRoot) {
-        return findOne(this, selector);
-      } else if (target instanceof OriginalElement) {
-        wrappedItem = wrap(originalElementQuerySelector.call(target, selector));
-      } else if (target instanceof OriginalDocument) {
-        wrappedItem = wrap(originalDocumentQuerySelector.call(target, selector));
-      } else {
-        return findOne(this, selector);
-      }
-      if (!wrappedItem) {
-        return wrappedItem;
-      } else if (!deep && (root = getTreeScope(wrappedItem).root)) {
-        if (root instanceof scope.wrappers.ShadowRoot) {
-          return findOne(this, selector);
-        }
-      }
-      return wrappedItem;
-    },
-    querySelectorAll: function(selector) {
-      var shimmed = shimSelector(selector);
-      var deep = shimmed !== selector;
-      selector = shimmed;
-      var result = new NodeList();
-      result.length = querySelectorAllFiltered.call(this, matchesSelector, 0, result, selector, deep);
-      return result;
-    }
-  };
-  var MatchesInterface = {
-    matches: function(selector) {
-      selector = shimMatchesSelector(selector);
-      return scope.originalMatches.call(unsafeUnwrap(this), selector);
-    }
-  };
-  function getElementsByTagNameFiltered(p, index, result, localName, lowercase) {
-    var target = unsafeUnwrap(this);
-    var list;
-    var root = getTreeScope(this).root;
-    if (root instanceof scope.wrappers.ShadowRoot) {
-      return findElements(this, index, result, p, localName, lowercase);
-    } else if (target instanceof OriginalElement) {
-      list = originalElementGetElementsByTagName.call(target, localName, lowercase);
-    } else if (target instanceof OriginalDocument) {
-      list = originalDocumentGetElementsByTagName.call(target, localName, lowercase);
-    } else {
-      return findElements(this, index, result, p, localName, lowercase);
-    }
-    return filterNodeList(list, index, result, false);
-  }
-  function getElementsByTagNameNSFiltered(p, index, result, ns, localName) {
-    var target = unsafeUnwrap(this);
-    var list;
-    var root = getTreeScope(this).root;
-    if (root instanceof scope.wrappers.ShadowRoot) {
-      return findElements(this, index, result, p, ns, localName);
-    } else if (target instanceof OriginalElement) {
-      list = originalElementGetElementsByTagNameNS.call(target, ns, localName);
-    } else if (target instanceof OriginalDocument) {
-      list = originalDocumentGetElementsByTagNameNS.call(target, ns, localName);
-    } else {
-      return findElements(this, index, result, p, ns, localName);
-    }
-    return filterNodeList(list, index, result, false);
-  }
-  var GetElementsByInterface = {
-    getElementsByTagName: function(localName) {
-      var result = new HTMLCollection();
-      var match = localName === "*" ? matchesEveryThing : matchesTagName;
-      result.length = getElementsByTagNameFiltered.call(this, match, 0, result, localName, localName.toLowerCase());
-      return result;
-    },
-    getElementsByClassName: function(className) {
-      return this.querySelectorAll("." + className);
-    },
-    getElementsByTagNameNS: function(ns, localName) {
-      var result = new HTMLCollection();
-      var match = null;
-      if (ns === "*") {
-        match = localName === "*" ? matchesEveryThing : matchesLocalNameOnly;
-      } else {
-        match = localName === "*" ? matchesNameSpace : matchesLocalNameNS;
-      }
-      result.length = getElementsByTagNameNSFiltered.call(this, match, 0, result, ns || null, localName);
-      return result;
-    }
-  };
-  scope.GetElementsByInterface = GetElementsByInterface;
-  scope.SelectorsInterface = SelectorsInterface;
-  scope.MatchesInterface = MatchesInterface;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var NodeList = scope.wrappers.NodeList;
-  function forwardElement(node) {
-    while (node && node.nodeType !== Node.ELEMENT_NODE) {
-      node = node.nextSibling;
-    }
-    return node;
-  }
-  function backwardsElement(node) {
-    while (node && node.nodeType !== Node.ELEMENT_NODE) {
-      node = node.previousSibling;
-    }
-    return node;
-  }
-  var ParentNodeInterface = {
-    get firstElementChild() {
-      return forwardElement(this.firstChild);
-    },
-    get lastElementChild() {
-      return backwardsElement(this.lastChild);
-    },
-    get childElementCount() {
-      var count = 0;
-      for (var child = this.firstElementChild; child; child = child.nextElementSibling) {
-        count++;
-      }
-      return count;
-    },
-    get children() {
-      var wrapperList = new NodeList();
-      var i = 0;
-      for (var child = this.firstElementChild; child; child = child.nextElementSibling) {
-        wrapperList[i++] = child;
-      }
-      wrapperList.length = i;
-      return wrapperList;
-    },
-    remove: function() {
-      var p = this.parentNode;
-      if (p) p.removeChild(this);
-    }
-  };
-  var ChildNodeInterface = {
-    get nextElementSibling() {
-      return forwardElement(this.nextSibling);
-    },
-    get previousElementSibling() {
-      return backwardsElement(this.previousSibling);
-    }
-  };
-  scope.ChildNodeInterface = ChildNodeInterface;
-  scope.ParentNodeInterface = ParentNodeInterface;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var ChildNodeInterface = scope.ChildNodeInterface;
-  var Node = scope.wrappers.Node;
-  var enqueueMutation = scope.enqueueMutation;
-  var mixin = scope.mixin;
-  var registerWrapper = scope.registerWrapper;
-  var unsafeUnwrap = scope.unsafeUnwrap;
-  var OriginalCharacterData = window.CharacterData;
-  function CharacterData(node) {
-    Node.call(this, node);
-  }
-  CharacterData.prototype = Object.create(Node.prototype);
-  mixin(CharacterData.prototype, {
-    get textContent() {
-      return this.data;
-    },
-    set textContent(value) {
-      this.data = value;
-    },
-    get data() {
-      return unsafeUnwrap(this).data;
-    },
-    set data(value) {
-      var oldValue = unsafeUnwrap(this).data;
-      enqueueMutation(this, "characterData", {
-        oldValue: oldValue
-      });
-      unsafeUnwrap(this).data = value;
-    }
-  });
-  mixin(CharacterData.prototype, ChildNodeInterface);
-  registerWrapper(OriginalCharacterData, CharacterData, document.createTextNode(""));
-  scope.wrappers.CharacterData = CharacterData;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var CharacterData = scope.wrappers.CharacterData;
-  var enqueueMutation = scope.enqueueMutation;
-  var mixin = scope.mixin;
-  var registerWrapper = scope.registerWrapper;
-  function toUInt32(x) {
-    return x >>> 0;
-  }
-  var OriginalText = window.Text;
-  function Text(node) {
-    CharacterData.call(this, node);
-  }
-  Text.prototype = Object.create(CharacterData.prototype);
-  mixin(Text.prototype, {
-    splitText: function(offset) {
-      offset = toUInt32(offset);
-      var s = this.data;
-      if (offset > s.length) throw new Error("IndexSizeError");
-      var head = s.slice(0, offset);
-      var tail = s.slice(offset);
-      this.data = head;
-      var newTextNode = this.ownerDocument.createTextNode(tail);
-      if (this.parentNode) this.parentNode.insertBefore(newTextNode, this.nextSibling);
-      return newTextNode;
-    }
-  });
-  registerWrapper(OriginalText, Text, document.createTextNode(""));
-  scope.wrappers.Text = Text;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  if (!window.DOMTokenList) {
-    console.warn("Missing DOMTokenList prototype, please include a " + "compatible classList polyfill such as http://goo.gl/uTcepH.");
-    return;
-  }
-  var unsafeUnwrap = scope.unsafeUnwrap;
-  var enqueueMutation = scope.enqueueMutation;
-  function getClass(el) {
-    return unsafeUnwrap(el).getAttribute("class");
-  }
-  function enqueueClassAttributeChange(el, oldValue) {
-    enqueueMutation(el, "attributes", {
-      name: "class",
-      namespace: null,
-      oldValue: oldValue
-    });
-  }
-  function invalidateClass(el) {
-    scope.invalidateRendererBasedOnAttribute(el, "class");
-  }
-  function changeClass(tokenList, method, args) {
-    var ownerElement = tokenList.ownerElement_;
-    if (ownerElement == null) {
-      return method.apply(tokenList, args);
-    }
-    var oldValue = getClass(ownerElement);
-    var retv = method.apply(tokenList, args);
-    if (getClass(ownerElement) !== oldValue) {
-      enqueueClassAttributeChange(ownerElement, oldValue);
-      invalidateClass(ownerElement);
-    }
-    return retv;
-  }
-  var oldAdd = DOMTokenList.prototype.add;
-  DOMTokenList.prototype.add = function() {
-    changeClass(this, oldAdd, arguments);
-  };
-  var oldRemove = DOMTokenList.prototype.remove;
-  DOMTokenList.prototype.remove = function() {
-    changeClass(this, oldRemove, arguments);
-  };
-  var oldToggle = DOMTokenList.prototype.toggle;
-  DOMTokenList.prototype.toggle = function() {
-    return changeClass(this, oldToggle, arguments);
-  };
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var ChildNodeInterface = scope.ChildNodeInterface;
-  var GetElementsByInterface = scope.GetElementsByInterface;
-  var Node = scope.wrappers.Node;
-  var ParentNodeInterface = scope.ParentNodeInterface;
-  var SelectorsInterface = scope.SelectorsInterface;
-  var MatchesInterface = scope.MatchesInterface;
-  var addWrapNodeListMethod = scope.addWrapNodeListMethod;
-  var enqueueMutation = scope.enqueueMutation;
-  var mixin = scope.mixin;
-  var oneOf = scope.oneOf;
-  var registerWrapper = scope.registerWrapper;
-  var unsafeUnwrap = scope.unsafeUnwrap;
-  var wrappers = scope.wrappers;
-  var OriginalElement = window.Element;
-  var matchesNames = [ "matches", "mozMatchesSelector", "msMatchesSelector", "webkitMatchesSelector" ].filter(function(name) {
-    return OriginalElement.prototype[name];
-  });
-  var matchesName = matchesNames[0];
-  var originalMatches = OriginalElement.prototype[matchesName];
-  function invalidateRendererBasedOnAttribute(element, name) {
-    var p = element.parentNode;
-    if (!p || !p.shadowRoot) return;
-    var renderer = scope.getRendererForHost(p);
-    if (renderer.dependsOnAttribute(name)) renderer.invalidate();
-  }
-  function enqueAttributeChange(element, name, oldValue) {
-    enqueueMutation(element, "attributes", {
-      name: name,
-      namespace: null,
-      oldValue: oldValue
-    });
-  }
-  var classListTable = new WeakMap();
-  function Element(node) {
-    Node.call(this, node);
-  }
-  Element.prototype = Object.create(Node.prototype);
-  mixin(Element.prototype, {
-    createShadowRoot: function() {
-      var newShadowRoot = new wrappers.ShadowRoot(this);
-      unsafeUnwrap(this).polymerShadowRoot_ = newShadowRoot;
-      var renderer = scope.getRendererForHost(this);
-      renderer.invalidate();
-      return newShadowRoot;
-    },
-    get shadowRoot() {
-      return unsafeUnwrap(this).polymerShadowRoot_ || null;
-    },
-    setAttribute: function(name, value) {
-      var oldValue = unsafeUnwrap(this).getAttribute(name);
-      unsafeUnwrap(this).setAttribute(name, value);
-      enqueAttributeChange(this, name, oldValue);
-      invalidateRendererBasedOnAttribute(this, name);
-    },
-    removeAttribute: function(name) {
-      var oldValue = unsafeUnwrap(this).getAttribute(name);
-      unsafeUnwrap(this).removeAttribute(name);
-      enqueAttributeChange(this, name, oldValue);
-      invalidateRendererBasedOnAttribute(this, name);
-    },
-    get classList() {
-      var list = classListTable.get(this);
-      if (!list) {
-        list = unsafeUnwrap(this).classList;
-        if (!list) return;
-        list.ownerElement_ = this;
-        classListTable.set(this, list);
-      }
-      return list;
-    },
-    get className() {
-      return unsafeUnwrap(this).className;
-    },
-    set className(v) {
-      this.setAttribute("class", v);
-    },
-    get id() {
-      return unsafeUnwrap(this).id;
-    },
-    set id(v) {
-      this.setAttribute("id", v);
-    }
-  });
-  matchesNames.forEach(function(name) {
-    if (name !== "matches") {
-      Element.prototype[name] = function(selector) {
-        return this.matches(selector);
-      };
-    }
-  });
-  if (OriginalElement.prototype.webkitCreateShadowRoot) {
-    Element.prototype.webkitCreateShadowRoot = Element.prototype.createShadowRoot;
-  }
-  mixin(Element.prototype, ChildNodeInterface);
-  mixin(Element.prototype, GetElementsByInterface);
-  mixin(Element.prototype, ParentNodeInterface);
-  mixin(Element.prototype, SelectorsInterface);
-  mixin(Element.prototype, MatchesInterface);
-  registerWrapper(OriginalElement, Element, document.createElementNS(null, "x"));
-  scope.invalidateRendererBasedOnAttribute = invalidateRendererBasedOnAttribute;
-  scope.matchesNames = matchesNames;
-  scope.originalMatches = originalMatches;
-  scope.wrappers.Element = Element;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var Element = scope.wrappers.Element;
-  var defineGetter = scope.defineGetter;
-  var enqueueMutation = scope.enqueueMutation;
-  var mixin = scope.mixin;
-  var nodesWereAdded = scope.nodesWereAdded;
-  var nodesWereRemoved = scope.nodesWereRemoved;
-  var registerWrapper = scope.registerWrapper;
-  var snapshotNodeList = scope.snapshotNodeList;
-  var unsafeUnwrap = scope.unsafeUnwrap;
-  var unwrap = scope.unwrap;
-  var wrap = scope.wrap;
-  var wrappers = scope.wrappers;
-  var escapeAttrRegExp = /[&\u00A0"]/g;
-  var escapeDataRegExp = /[&\u00A0<>]/g;
-  function escapeReplace(c) {
-    switch (c) {
-     case "&":
-      return "&";
-
-     case "<":
-      return "<";
-
-     case ">":
-      return ">";
-
-     case '"':
-      return """;
-
-     case " ":
-      return " ";
-    }
-  }
-  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) {
-    switch (node.nodeType) {
-     case Node.ELEMENT_NODE:
-      var tagName = node.tagName.toLowerCase();
-      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) + "";
-
-     case Node.TEXT_NODE:
-      var data = node.data;
-      if (parentNode && plaintextParents[parentNode.localName]) return data;
-      return escapeData(data);
-
-     case Node.COMMENT_NODE:
-      return "";
-
-     default:
-      console.error(node);
-      throw new Error("not implemented");
-    }
-  }
-  function getInnerHTML(node) {
-    if (node instanceof wrappers.HTMLTemplateElement) node = node.content;
-    var s = "";
-    for (var child = node.firstChild; child; child = child.nextSibling) {
-      s += getOuterHTML(child, node);
-    }
-    return s;
-  }
-  function setInnerHTML(node, value, opt_tagName) {
-    var tagName = opt_tagName || "div";
-    node.textContent = "";
-    var tempElement = unwrap(node.ownerDocument.createElement(tagName));
-    tempElement.innerHTML = value;
-    var firstChild;
-    while (firstChild = tempElement.firstChild) {
-      node.appendChild(wrap(firstChild));
-    }
-  }
-  var oldIe = /MSIE/.test(navigator.userAgent);
-  var OriginalHTMLElement = window.HTMLElement;
-  var OriginalHTMLTemplateElement = window.HTMLTemplateElement;
-  function HTMLElement(node) {
-    Element.call(this, node);
-  }
-  HTMLElement.prototype = Object.create(Element.prototype);
-  mixin(HTMLElement.prototype, {
-    get innerHTML() {
-      return getInnerHTML(this);
-    },
-    set innerHTML(value) {
-      if (oldIe && plaintextParents[this.localName]) {
-        this.textContent = value;
-        return;
-      }
-      var removedNodes = snapshotNodeList(this.childNodes);
-      if (this.invalidateShadowRenderer()) {
-        if (this instanceof wrappers.HTMLTemplateElement) setInnerHTML(this.content, value); else setInnerHTML(this, value, this.tagName);
-      } else if (!OriginalHTMLTemplateElement && this instanceof wrappers.HTMLTemplateElement) {
-        setInnerHTML(this.content, value);
-      } else {
-        unsafeUnwrap(this).innerHTML = value;
-      }
-      var addedNodes = snapshotNodeList(this.childNodes);
-      enqueueMutation(this, "childList", {
-        addedNodes: addedNodes,
-        removedNodes: removedNodes
-      });
-      nodesWereRemoved(removedNodes);
-      nodesWereAdded(addedNodes, this);
-    },
-    get outerHTML() {
-      return getOuterHTML(this, this.parentNode);
-    },
-    set outerHTML(value) {
-      var p = this.parentNode;
-      if (p) {
-        p.invalidateShadowRenderer();
-        var df = frag(p, value);
-        p.replaceChild(df, this);
-      }
-    },
-    insertAdjacentHTML: function(position, text) {
-      var contextElement, refNode;
-      switch (String(position).toLowerCase()) {
-       case "beforebegin":
-        contextElement = this.parentNode;
-        refNode = this;
-        break;
-
-       case "afterend":
-        contextElement = this.parentNode;
-        refNode = this.nextSibling;
-        break;
-
-       case "afterbegin":
-        contextElement = this;
-        refNode = this.firstChild;
-        break;
-
-       case "beforeend":
-        contextElement = this;
-        refNode = null;
-        break;
-
-       default:
-        return;
-      }
-      var df = frag(contextElement, text);
-      contextElement.insertBefore(df, refNode);
-    },
-    get hidden() {
-      return this.hasAttribute("hidden");
-    },
-    set hidden(v) {
-      if (v) {
-        this.setAttribute("hidden", "");
-      } else {
-        this.removeAttribute("hidden");
-      }
-    }
-  });
-  function frag(contextElement, html) {
-    var p = unwrap(contextElement.cloneNode(false));
-    p.innerHTML = html;
-    var df = unwrap(document.createDocumentFragment());
-    var c;
-    while (c = p.firstChild) {
-      df.appendChild(c);
-    }
-    return wrap(df);
-  }
-  function getter(name) {
-    return function() {
-      scope.renderAllPending();
-      return unsafeUnwrap(this)[name];
-    };
-  }
-  function getterRequiresRendering(name) {
-    defineGetter(HTMLElement, name, getter(name));
-  }
-  [ "clientHeight", "clientLeft", "clientTop", "clientWidth", "offsetHeight", "offsetLeft", "offsetTop", "offsetWidth", "scrollHeight", "scrollWidth" ].forEach(getterRequiresRendering);
-  function getterAndSetterRequiresRendering(name) {
-    Object.defineProperty(HTMLElement.prototype, name, {
-      get: getter(name),
-      set: function(v) {
-        scope.renderAllPending();
-        unsafeUnwrap(this)[name] = v;
-      },
-      configurable: true,
-      enumerable: true
-    });
-  }
-  [ "scrollLeft", "scrollTop" ].forEach(getterAndSetterRequiresRendering);
-  function methodRequiresRendering(name) {
-    Object.defineProperty(HTMLElement.prototype, name, {
-      value: function() {
-        scope.renderAllPending();
-        return unsafeUnwrap(this)[name].apply(unsafeUnwrap(this), arguments);
-      },
-      configurable: true,
-      enumerable: true
-    });
-  }
-  [ "getBoundingClientRect", "getClientRects", "scrollIntoView" ].forEach(methodRequiresRendering);
-  registerWrapper(OriginalHTMLElement, HTMLElement, document.createElement("b"));
-  scope.wrappers.HTMLElement = HTMLElement;
-  scope.getInnerHTML = getInnerHTML;
-  scope.setInnerHTML = setInnerHTML;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var HTMLElement = scope.wrappers.HTMLElement;
-  var mixin = scope.mixin;
-  var registerWrapper = scope.registerWrapper;
-  var unsafeUnwrap = scope.unsafeUnwrap;
-  var wrap = scope.wrap;
-  var OriginalHTMLCanvasElement = window.HTMLCanvasElement;
-  function HTMLCanvasElement(node) {
-    HTMLElement.call(this, node);
-  }
-  HTMLCanvasElement.prototype = Object.create(HTMLElement.prototype);
-  mixin(HTMLCanvasElement.prototype, {
-    getContext: function() {
-      var context = unsafeUnwrap(this).getContext.apply(unsafeUnwrap(this), arguments);
-      return context && wrap(context);
-    }
-  });
-  registerWrapper(OriginalHTMLCanvasElement, HTMLCanvasElement, document.createElement("canvas"));
-  scope.wrappers.HTMLCanvasElement = HTMLCanvasElement;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var HTMLElement = scope.wrappers.HTMLElement;
-  var mixin = scope.mixin;
-  var registerWrapper = scope.registerWrapper;
-  var OriginalHTMLContentElement = window.HTMLContentElement;
-  function HTMLContentElement(node) {
-    HTMLElement.call(this, node);
-  }
-  HTMLContentElement.prototype = Object.create(HTMLElement.prototype);
-  mixin(HTMLContentElement.prototype, {
-    constructor: HTMLContentElement,
-    get select() {
-      return this.getAttribute("select");
-    },
-    set select(value) {
-      this.setAttribute("select", value);
-    },
-    setAttribute: function(n, v) {
-      HTMLElement.prototype.setAttribute.call(this, n, v);
-      if (String(n).toLowerCase() === "select") this.invalidateShadowRenderer(true);
-    }
-  });
-  if (OriginalHTMLContentElement) registerWrapper(OriginalHTMLContentElement, HTMLContentElement);
-  scope.wrappers.HTMLContentElement = HTMLContentElement;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var HTMLElement = scope.wrappers.HTMLElement;
-  var mixin = scope.mixin;
-  var registerWrapper = scope.registerWrapper;
-  var wrapHTMLCollection = scope.wrapHTMLCollection;
-  var unwrap = scope.unwrap;
-  var OriginalHTMLFormElement = window.HTMLFormElement;
-  function HTMLFormElement(node) {
-    HTMLElement.call(this, node);
-  }
-  HTMLFormElement.prototype = Object.create(HTMLElement.prototype);
-  mixin(HTMLFormElement.prototype, {
-    get elements() {
-      return wrapHTMLCollection(unwrap(this).elements);
-    }
-  });
-  registerWrapper(OriginalHTMLFormElement, HTMLFormElement, document.createElement("form"));
-  scope.wrappers.HTMLFormElement = HTMLFormElement;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var HTMLElement = scope.wrappers.HTMLElement;
-  var registerWrapper = scope.registerWrapper;
-  var unwrap = scope.unwrap;
-  var rewrap = scope.rewrap;
-  var OriginalHTMLImageElement = window.HTMLImageElement;
-  function HTMLImageElement(node) {
-    HTMLElement.call(this, node);
-  }
-  HTMLImageElement.prototype = Object.create(HTMLElement.prototype);
-  registerWrapper(OriginalHTMLImageElement, HTMLImageElement, document.createElement("img"));
-  function Image(width, height) {
-    if (!(this instanceof Image)) {
-      throw new TypeError("DOM object constructor cannot be called as a function.");
-    }
-    var node = unwrap(document.createElement("img"));
-    HTMLElement.call(this, node);
-    rewrap(node, this);
-    if (width !== undefined) node.width = width;
-    if (height !== undefined) node.height = height;
-  }
-  Image.prototype = HTMLImageElement.prototype;
-  scope.wrappers.HTMLImageElement = HTMLImageElement;
-  scope.wrappers.Image = Image;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var HTMLElement = scope.wrappers.HTMLElement;
-  var mixin = scope.mixin;
-  var NodeList = scope.wrappers.NodeList;
-  var registerWrapper = scope.registerWrapper;
-  var OriginalHTMLShadowElement = window.HTMLShadowElement;
-  function HTMLShadowElement(node) {
-    HTMLElement.call(this, node);
-  }
-  HTMLShadowElement.prototype = Object.create(HTMLElement.prototype);
-  HTMLShadowElement.prototype.constructor = HTMLShadowElement;
-  if (OriginalHTMLShadowElement) registerWrapper(OriginalHTMLShadowElement, HTMLShadowElement);
-  scope.wrappers.HTMLShadowElement = HTMLShadowElement;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var HTMLElement = scope.wrappers.HTMLElement;
-  var mixin = scope.mixin;
-  var registerWrapper = scope.registerWrapper;
-  var unsafeUnwrap = scope.unsafeUnwrap;
-  var unwrap = scope.unwrap;
-  var wrap = scope.wrap;
-  var contentTable = new WeakMap();
-  var templateContentsOwnerTable = new WeakMap();
-  function getTemplateContentsOwner(doc) {
-    if (!doc.defaultView) return doc;
-    var d = templateContentsOwnerTable.get(doc);
-    if (!d) {
-      d = doc.implementation.createHTMLDocument("");
-      while (d.lastChild) {
-        d.removeChild(d.lastChild);
-      }
-      templateContentsOwnerTable.set(doc, d);
-    }
-    return d;
-  }
-  function extractContent(templateElement) {
-    var doc = getTemplateContentsOwner(templateElement.ownerDocument);
-    var df = unwrap(doc.createDocumentFragment());
-    var child;
-    while (child = templateElement.firstChild) {
-      df.appendChild(child);
-    }
-    return df;
-  }
-  var OriginalHTMLTemplateElement = window.HTMLTemplateElement;
-  function HTMLTemplateElement(node) {
-    HTMLElement.call(this, node);
-    if (!OriginalHTMLTemplateElement) {
-      var content = extractContent(node);
-      contentTable.set(this, wrap(content));
-    }
-  }
-  HTMLTemplateElement.prototype = Object.create(HTMLElement.prototype);
-  mixin(HTMLTemplateElement.prototype, {
-    constructor: HTMLTemplateElement,
-    get content() {
-      if (OriginalHTMLTemplateElement) return wrap(unsafeUnwrap(this).content);
-      return contentTable.get(this);
-    }
-  });
-  if (OriginalHTMLTemplateElement) registerWrapper(OriginalHTMLTemplateElement, HTMLTemplateElement);
-  scope.wrappers.HTMLTemplateElement = HTMLTemplateElement;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var HTMLElement = scope.wrappers.HTMLElement;
-  var registerWrapper = scope.registerWrapper;
-  var OriginalHTMLMediaElement = window.HTMLMediaElement;
-  if (!OriginalHTMLMediaElement) return;
-  function HTMLMediaElement(node) {
-    HTMLElement.call(this, node);
-  }
-  HTMLMediaElement.prototype = Object.create(HTMLElement.prototype);
-  registerWrapper(OriginalHTMLMediaElement, HTMLMediaElement, document.createElement("audio"));
-  scope.wrappers.HTMLMediaElement = HTMLMediaElement;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var HTMLMediaElement = scope.wrappers.HTMLMediaElement;
-  var registerWrapper = scope.registerWrapper;
-  var unwrap = scope.unwrap;
-  var rewrap = scope.rewrap;
-  var OriginalHTMLAudioElement = window.HTMLAudioElement;
-  if (!OriginalHTMLAudioElement) return;
-  function HTMLAudioElement(node) {
-    HTMLMediaElement.call(this, node);
-  }
-  HTMLAudioElement.prototype = Object.create(HTMLMediaElement.prototype);
-  registerWrapper(OriginalHTMLAudioElement, HTMLAudioElement, document.createElement("audio"));
-  function Audio(src) {
-    if (!(this instanceof Audio)) {
-      throw new TypeError("DOM object constructor cannot be called as a function.");
-    }
-    var node = unwrap(document.createElement("audio"));
-    HTMLMediaElement.call(this, node);
-    rewrap(node, this);
-    node.setAttribute("preload", "auto");
-    if (src !== undefined) node.setAttribute("src", src);
-  }
-  Audio.prototype = HTMLAudioElement.prototype;
-  scope.wrappers.HTMLAudioElement = HTMLAudioElement;
-  scope.wrappers.Audio = Audio;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var HTMLElement = scope.wrappers.HTMLElement;
-  var mixin = scope.mixin;
-  var registerWrapper = scope.registerWrapper;
-  var rewrap = scope.rewrap;
-  var unwrap = scope.unwrap;
-  var wrap = scope.wrap;
-  var OriginalHTMLOptionElement = window.HTMLOptionElement;
-  function trimText(s) {
-    return s.replace(/\s+/g, " ").trim();
-  }
-  function HTMLOptionElement(node) {
-    HTMLElement.call(this, node);
-  }
-  HTMLOptionElement.prototype = Object.create(HTMLElement.prototype);
-  mixin(HTMLOptionElement.prototype, {
-    get text() {
-      return trimText(this.textContent);
-    },
-    set text(value) {
-      this.textContent = trimText(String(value));
-    },
-    get form() {
-      return wrap(unwrap(this).form);
-    }
-  });
-  registerWrapper(OriginalHTMLOptionElement, HTMLOptionElement, document.createElement("option"));
-  function Option(text, value, defaultSelected, selected) {
-    if (!(this instanceof Option)) {
-      throw new TypeError("DOM object constructor cannot be called as a function.");
-    }
-    var node = unwrap(document.createElement("option"));
-    HTMLElement.call(this, node);
-    rewrap(node, this);
-    if (text !== undefined) node.text = text;
-    if (value !== undefined) node.setAttribute("value", value);
-    if (defaultSelected === true) node.setAttribute("selected", "");
-    node.selected = selected === true;
-  }
-  Option.prototype = HTMLOptionElement.prototype;
-  scope.wrappers.HTMLOptionElement = HTMLOptionElement;
-  scope.wrappers.Option = Option;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var HTMLElement = scope.wrappers.HTMLElement;
-  var mixin = scope.mixin;
-  var registerWrapper = scope.registerWrapper;
-  var unwrap = scope.unwrap;
-  var wrap = scope.wrap;
-  var OriginalHTMLSelectElement = window.HTMLSelectElement;
-  function HTMLSelectElement(node) {
-    HTMLElement.call(this, node);
-  }
-  HTMLSelectElement.prototype = Object.create(HTMLElement.prototype);
-  mixin(HTMLSelectElement.prototype, {
-    add: function(element, before) {
-      if (typeof before === "object") before = unwrap(before);
-      unwrap(this).add(unwrap(element), before);
-    },
-    remove: function(indexOrNode) {
-      if (indexOrNode === undefined) {
-        HTMLElement.prototype.remove.call(this);
-        return;
-      }
-      if (typeof indexOrNode === "object") indexOrNode = unwrap(indexOrNode);
-      unwrap(this).remove(indexOrNode);
-    },
-    get form() {
-      return wrap(unwrap(this).form);
-    }
-  });
-  registerWrapper(OriginalHTMLSelectElement, HTMLSelectElement, document.createElement("select"));
-  scope.wrappers.HTMLSelectElement = HTMLSelectElement;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var HTMLElement = scope.wrappers.HTMLElement;
-  var mixin = scope.mixin;
-  var registerWrapper = scope.registerWrapper;
-  var unwrap = scope.unwrap;
-  var wrap = scope.wrap;
-  var wrapHTMLCollection = scope.wrapHTMLCollection;
-  var OriginalHTMLTableElement = window.HTMLTableElement;
-  function HTMLTableElement(node) {
-    HTMLElement.call(this, node);
-  }
-  HTMLTableElement.prototype = Object.create(HTMLElement.prototype);
-  mixin(HTMLTableElement.prototype, {
-    get caption() {
-      return wrap(unwrap(this).caption);
-    },
-    createCaption: function() {
-      return wrap(unwrap(this).createCaption());
-    },
-    get tHead() {
-      return wrap(unwrap(this).tHead);
-    },
-    createTHead: function() {
-      return wrap(unwrap(this).createTHead());
-    },
-    createTFoot: function() {
-      return wrap(unwrap(this).createTFoot());
-    },
-    get tFoot() {
-      return wrap(unwrap(this).tFoot);
-    },
-    get tBodies() {
-      return wrapHTMLCollection(unwrap(this).tBodies);
-    },
-    createTBody: function() {
-      return wrap(unwrap(this).createTBody());
-    },
-    get rows() {
-      return wrapHTMLCollection(unwrap(this).rows);
-    },
-    insertRow: function(index) {
-      return wrap(unwrap(this).insertRow(index));
-    }
-  });
-  registerWrapper(OriginalHTMLTableElement, HTMLTableElement, document.createElement("table"));
-  scope.wrappers.HTMLTableElement = HTMLTableElement;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var HTMLElement = scope.wrappers.HTMLElement;
-  var mixin = scope.mixin;
-  var registerWrapper = scope.registerWrapper;
-  var wrapHTMLCollection = scope.wrapHTMLCollection;
-  var unwrap = scope.unwrap;
-  var wrap = scope.wrap;
-  var OriginalHTMLTableSectionElement = window.HTMLTableSectionElement;
-  function HTMLTableSectionElement(node) {
-    HTMLElement.call(this, node);
-  }
-  HTMLTableSectionElement.prototype = Object.create(HTMLElement.prototype);
-  mixin(HTMLTableSectionElement.prototype, {
-    constructor: HTMLTableSectionElement,
-    get rows() {
-      return wrapHTMLCollection(unwrap(this).rows);
-    },
-    insertRow: function(index) {
-      return wrap(unwrap(this).insertRow(index));
-    }
-  });
-  registerWrapper(OriginalHTMLTableSectionElement, HTMLTableSectionElement, document.createElement("thead"));
-  scope.wrappers.HTMLTableSectionElement = HTMLTableSectionElement;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var HTMLElement = scope.wrappers.HTMLElement;
-  var mixin = scope.mixin;
-  var registerWrapper = scope.registerWrapper;
-  var wrapHTMLCollection = scope.wrapHTMLCollection;
-  var unwrap = scope.unwrap;
-  var wrap = scope.wrap;
-  var OriginalHTMLTableRowElement = window.HTMLTableRowElement;
-  function HTMLTableRowElement(node) {
-    HTMLElement.call(this, node);
-  }
-  HTMLTableRowElement.prototype = Object.create(HTMLElement.prototype);
-  mixin(HTMLTableRowElement.prototype, {
-    get cells() {
-      return wrapHTMLCollection(unwrap(this).cells);
-    },
-    insertCell: function(index) {
-      return wrap(unwrap(this).insertCell(index));
-    }
-  });
-  registerWrapper(OriginalHTMLTableRowElement, HTMLTableRowElement, document.createElement("tr"));
-  scope.wrappers.HTMLTableRowElement = HTMLTableRowElement;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var HTMLContentElement = scope.wrappers.HTMLContentElement;
-  var HTMLElement = scope.wrappers.HTMLElement;
-  var HTMLShadowElement = scope.wrappers.HTMLShadowElement;
-  var HTMLTemplateElement = scope.wrappers.HTMLTemplateElement;
-  var mixin = scope.mixin;
-  var registerWrapper = scope.registerWrapper;
-  var OriginalHTMLUnknownElement = window.HTMLUnknownElement;
-  function HTMLUnknownElement(node) {
-    switch (node.localName) {
-     case "content":
-      return new HTMLContentElement(node);
-
-     case "shadow":
-      return new HTMLShadowElement(node);
-
-     case "template":
-      return new HTMLTemplateElement(node);
-    }
-    HTMLElement.call(this, node);
-  }
-  HTMLUnknownElement.prototype = Object.create(HTMLElement.prototype);
-  registerWrapper(OriginalHTMLUnknownElement, HTMLUnknownElement);
-  scope.wrappers.HTMLUnknownElement = HTMLUnknownElement;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var Element = scope.wrappers.Element;
-  var HTMLElement = scope.wrappers.HTMLElement;
-  var registerObject = scope.registerObject;
-  var defineWrapGetter = scope.defineWrapGetter;
-  var SVG_NS = "http://www.w3.org/2000/svg";
-  var svgTitleElement = document.createElementNS(SVG_NS, "title");
-  var SVGTitleElement = registerObject(svgTitleElement);
-  var SVGElement = Object.getPrototypeOf(SVGTitleElement.prototype).constructor;
-  if (!("classList" in svgTitleElement)) {
-    var descr = Object.getOwnPropertyDescriptor(Element.prototype, "classList");
-    Object.defineProperty(HTMLElement.prototype, "classList", descr);
-    delete Element.prototype.classList;
-  }
-  defineWrapGetter(SVGElement, "ownerSVGElement");
-  scope.wrappers.SVGElement = SVGElement;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var mixin = scope.mixin;
-  var registerWrapper = scope.registerWrapper;
-  var unwrap = scope.unwrap;
-  var wrap = scope.wrap;
-  var OriginalSVGUseElement = window.SVGUseElement;
-  var SVG_NS = "http://www.w3.org/2000/svg";
-  var gWrapper = wrap(document.createElementNS(SVG_NS, "g"));
-  var useElement = document.createElementNS(SVG_NS, "use");
-  var SVGGElement = gWrapper.constructor;
-  var parentInterfacePrototype = Object.getPrototypeOf(SVGGElement.prototype);
-  var parentInterface = parentInterfacePrototype.constructor;
-  function SVGUseElement(impl) {
-    parentInterface.call(this, impl);
-  }
-  SVGUseElement.prototype = Object.create(parentInterfacePrototype);
-  if ("instanceRoot" in useElement) {
-    mixin(SVGUseElement.prototype, {
-      get instanceRoot() {
-        return wrap(unwrap(this).instanceRoot);
-      },
-      get animatedInstanceRoot() {
-        return wrap(unwrap(this).animatedInstanceRoot);
-      }
-    });
-  }
-  registerWrapper(OriginalSVGUseElement, SVGUseElement, useElement);
-  scope.wrappers.SVGUseElement = SVGUseElement;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var EventTarget = scope.wrappers.EventTarget;
-  var mixin = scope.mixin;
-  var registerWrapper = scope.registerWrapper;
-  var unsafeUnwrap = scope.unsafeUnwrap;
-  var wrap = scope.wrap;
-  var OriginalSVGElementInstance = window.SVGElementInstance;
-  if (!OriginalSVGElementInstance) return;
-  function SVGElementInstance(impl) {
-    EventTarget.call(this, impl);
-  }
-  SVGElementInstance.prototype = Object.create(EventTarget.prototype);
-  mixin(SVGElementInstance.prototype, {
-    get correspondingElement() {
-      return wrap(unsafeUnwrap(this).correspondingElement);
-    },
-    get correspondingUseElement() {
-      return wrap(unsafeUnwrap(this).correspondingUseElement);
-    },
-    get parentNode() {
-      return wrap(unsafeUnwrap(this).parentNode);
-    },
-    get childNodes() {
-      throw new Error("Not implemented");
-    },
-    get firstChild() {
-      return wrap(unsafeUnwrap(this).firstChild);
-    },
-    get lastChild() {
-      return wrap(unsafeUnwrap(this).lastChild);
-    },
-    get previousSibling() {
-      return wrap(unsafeUnwrap(this).previousSibling);
-    },
-    get nextSibling() {
-      return wrap(unsafeUnwrap(this).nextSibling);
-    }
-  });
-  registerWrapper(OriginalSVGElementInstance, SVGElementInstance);
-  scope.wrappers.SVGElementInstance = SVGElementInstance;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var mixin = scope.mixin;
-  var registerWrapper = scope.registerWrapper;
-  var setWrapper = scope.setWrapper;
-  var unsafeUnwrap = scope.unsafeUnwrap;
-  var unwrap = scope.unwrap;
-  var unwrapIfNeeded = scope.unwrapIfNeeded;
-  var wrap = scope.wrap;
-  var OriginalCanvasRenderingContext2D = window.CanvasRenderingContext2D;
-  function CanvasRenderingContext2D(impl) {
-    setWrapper(impl, this);
-  }
-  mixin(CanvasRenderingContext2D.prototype, {
-    get canvas() {
-      return wrap(unsafeUnwrap(this).canvas);
-    },
-    drawImage: function() {
-      arguments[0] = unwrapIfNeeded(arguments[0]);
-      unsafeUnwrap(this).drawImage.apply(unsafeUnwrap(this), arguments);
-    },
-    createPattern: function() {
-      arguments[0] = unwrap(arguments[0]);
-      return unsafeUnwrap(this).createPattern.apply(unsafeUnwrap(this), arguments);
-    }
-  });
-  registerWrapper(OriginalCanvasRenderingContext2D, CanvasRenderingContext2D, document.createElement("canvas").getContext("2d"));
-  scope.wrappers.CanvasRenderingContext2D = CanvasRenderingContext2D;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var mixin = scope.mixin;
-  var registerWrapper = scope.registerWrapper;
-  var setWrapper = scope.setWrapper;
-  var unsafeUnwrap = scope.unsafeUnwrap;
-  var unwrapIfNeeded = scope.unwrapIfNeeded;
-  var wrap = scope.wrap;
-  var OriginalWebGLRenderingContext = window.WebGLRenderingContext;
-  if (!OriginalWebGLRenderingContext) return;
-  function WebGLRenderingContext(impl) {
-    setWrapper(impl, this);
-  }
-  mixin(WebGLRenderingContext.prototype, {
-    get canvas() {
-      return wrap(unsafeUnwrap(this).canvas);
-    },
-    texImage2D: function() {
-      arguments[5] = unwrapIfNeeded(arguments[5]);
-      unsafeUnwrap(this).texImage2D.apply(unsafeUnwrap(this), arguments);
-    },
-    texSubImage2D: function() {
-      arguments[6] = unwrapIfNeeded(arguments[6]);
-      unsafeUnwrap(this).texSubImage2D.apply(unsafeUnwrap(this), arguments);
-    }
-  });
-  var instanceProperties = /WebKit/.test(navigator.userAgent) ? {
-    drawingBufferHeight: null,
-    drawingBufferWidth: null
-  } : {};
-  registerWrapper(OriginalWebGLRenderingContext, WebGLRenderingContext, instanceProperties);
-  scope.wrappers.WebGLRenderingContext = WebGLRenderingContext;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var registerWrapper = scope.registerWrapper;
-  var setWrapper = scope.setWrapper;
-  var unsafeUnwrap = scope.unsafeUnwrap;
-  var unwrap = scope.unwrap;
-  var unwrapIfNeeded = scope.unwrapIfNeeded;
-  var wrap = scope.wrap;
-  var OriginalRange = window.Range;
-  function Range(impl) {
-    setWrapper(impl, this);
-  }
-  Range.prototype = {
-    get startContainer() {
-      return wrap(unsafeUnwrap(this).startContainer);
-    },
-    get endContainer() {
-      return wrap(unsafeUnwrap(this).endContainer);
-    },
-    get commonAncestorContainer() {
-      return wrap(unsafeUnwrap(this).commonAncestorContainer);
-    },
-    setStart: function(refNode, offset) {
-      unsafeUnwrap(this).setStart(unwrapIfNeeded(refNode), offset);
-    },
-    setEnd: function(refNode, offset) {
-      unsafeUnwrap(this).setEnd(unwrapIfNeeded(refNode), offset);
-    },
-    setStartBefore: function(refNode) {
-      unsafeUnwrap(this).setStartBefore(unwrapIfNeeded(refNode));
-    },
-    setStartAfter: function(refNode) {
-      unsafeUnwrap(this).setStartAfter(unwrapIfNeeded(refNode));
-    },
-    setEndBefore: function(refNode) {
-      unsafeUnwrap(this).setEndBefore(unwrapIfNeeded(refNode));
-    },
-    setEndAfter: function(refNode) {
-      unsafeUnwrap(this).setEndAfter(unwrapIfNeeded(refNode));
-    },
-    selectNode: function(refNode) {
-      unsafeUnwrap(this).selectNode(unwrapIfNeeded(refNode));
-    },
-    selectNodeContents: function(refNode) {
-      unsafeUnwrap(this).selectNodeContents(unwrapIfNeeded(refNode));
-    },
-    compareBoundaryPoints: function(how, sourceRange) {
-      return unsafeUnwrap(this).compareBoundaryPoints(how, unwrap(sourceRange));
-    },
-    extractContents: function() {
-      return wrap(unsafeUnwrap(this).extractContents());
-    },
-    cloneContents: function() {
-      return wrap(unsafeUnwrap(this).cloneContents());
-    },
-    insertNode: function(node) {
-      unsafeUnwrap(this).insertNode(unwrapIfNeeded(node));
-    },
-    surroundContents: function(newParent) {
-      unsafeUnwrap(this).surroundContents(unwrapIfNeeded(newParent));
-    },
-    cloneRange: function() {
-      return wrap(unsafeUnwrap(this).cloneRange());
-    },
-    isPointInRange: function(node, offset) {
-      return unsafeUnwrap(this).isPointInRange(unwrapIfNeeded(node), offset);
-    },
-    comparePoint: function(node, offset) {
-      return unsafeUnwrap(this).comparePoint(unwrapIfNeeded(node), offset);
-    },
-    intersectsNode: function(node) {
-      return unsafeUnwrap(this).intersectsNode(unwrapIfNeeded(node));
-    },
-    toString: function() {
-      return unsafeUnwrap(this).toString();
-    }
-  };
-  if (OriginalRange.prototype.createContextualFragment) {
-    Range.prototype.createContextualFragment = function(html) {
-      return wrap(unsafeUnwrap(this).createContextualFragment(html));
-    };
-  }
-  registerWrapper(window.Range, Range, document.createRange());
-  scope.wrappers.Range = Range;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var GetElementsByInterface = scope.GetElementsByInterface;
-  var ParentNodeInterface = scope.ParentNodeInterface;
-  var SelectorsInterface = scope.SelectorsInterface;
-  var mixin = scope.mixin;
-  var registerObject = scope.registerObject;
-  var DocumentFragment = registerObject(document.createDocumentFragment());
-  mixin(DocumentFragment.prototype, ParentNodeInterface);
-  mixin(DocumentFragment.prototype, SelectorsInterface);
-  mixin(DocumentFragment.prototype, GetElementsByInterface);
-  var Comment = registerObject(document.createComment(""));
-  scope.wrappers.Comment = Comment;
-  scope.wrappers.DocumentFragment = DocumentFragment;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var DocumentFragment = scope.wrappers.DocumentFragment;
-  var TreeScope = scope.TreeScope;
-  var elementFromPoint = scope.elementFromPoint;
-  var getInnerHTML = scope.getInnerHTML;
-  var getTreeScope = scope.getTreeScope;
-  var mixin = scope.mixin;
-  var rewrap = scope.rewrap;
-  var setInnerHTML = scope.setInnerHTML;
-  var unsafeUnwrap = scope.unsafeUnwrap;
-  var unwrap = scope.unwrap;
-  var shadowHostTable = new WeakMap();
-  var nextOlderShadowTreeTable = new WeakMap();
-  var spaceCharRe = /[ \t\n\r\f]/;
-  function ShadowRoot(hostWrapper) {
-    var node = unwrap(unsafeUnwrap(hostWrapper).ownerDocument.createDocumentFragment());
-    DocumentFragment.call(this, node);
-    rewrap(node, this);
-    var oldShadowRoot = hostWrapper.shadowRoot;
-    nextOlderShadowTreeTable.set(this, oldShadowRoot);
-    this.treeScope_ = new TreeScope(this, getTreeScope(oldShadowRoot || hostWrapper));
-    shadowHostTable.set(this, hostWrapper);
-  }
-  ShadowRoot.prototype = Object.create(DocumentFragment.prototype);
-  mixin(ShadowRoot.prototype, {
-    constructor: ShadowRoot,
-    get innerHTML() {
-      return getInnerHTML(this);
-    },
-    set innerHTML(value) {
-      setInnerHTML(this, value);
-      this.invalidateShadowRenderer();
-    },
-    get olderShadowRoot() {
-      return nextOlderShadowTreeTable.get(this) || null;
-    },
-    get host() {
-      return shadowHostTable.get(this) || null;
-    },
-    invalidateShadowRenderer: function() {
-      return shadowHostTable.get(this).invalidateShadowRenderer();
-    },
-    elementFromPoint: function(x, y) {
-      return elementFromPoint(this, this.ownerDocument, x, y);
-    },
-    getElementById: function(id) {
-      if (spaceCharRe.test(id)) return null;
-      return this.querySelector('[id="' + id + '"]');
-    }
-  });
-  scope.wrappers.ShadowRoot = ShadowRoot;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var Element = scope.wrappers.Element;
-  var HTMLContentElement = scope.wrappers.HTMLContentElement;
-  var HTMLShadowElement = scope.wrappers.HTMLShadowElement;
-  var Node = scope.wrappers.Node;
-  var ShadowRoot = scope.wrappers.ShadowRoot;
-  var assert = scope.assert;
-  var getTreeScope = scope.getTreeScope;
-  var mixin = scope.mixin;
-  var oneOf = scope.oneOf;
-  var unsafeUnwrap = scope.unsafeUnwrap;
-  var unwrap = scope.unwrap;
-  var wrap = scope.wrap;
-  var ArraySplice = scope.ArraySplice;
-  function updateWrapperUpAndSideways(wrapper) {
-    wrapper.previousSibling_ = wrapper.previousSibling;
-    wrapper.nextSibling_ = wrapper.nextSibling;
-    wrapper.parentNode_ = wrapper.parentNode;
-  }
-  function updateWrapperDown(wrapper) {
-    wrapper.firstChild_ = wrapper.firstChild;
-    wrapper.lastChild_ = wrapper.lastChild;
-  }
-  function updateAllChildNodes(parentNodeWrapper) {
-    assert(parentNodeWrapper instanceof Node);
-    for (var childWrapper = parentNodeWrapper.firstChild; childWrapper; childWrapper = childWrapper.nextSibling) {
-      updateWrapperUpAndSideways(childWrapper);
-    }
-    updateWrapperDown(parentNodeWrapper);
-  }
-  function insertBefore(parentNodeWrapper, newChildWrapper, refChildWrapper) {
-    var parentNode = unwrap(parentNodeWrapper);
-    var newChild = unwrap(newChildWrapper);
-    var refChild = refChildWrapper ? unwrap(refChildWrapper) : null;
-    remove(newChildWrapper);
-    updateWrapperUpAndSideways(newChildWrapper);
-    if (!refChildWrapper) {
-      parentNodeWrapper.lastChild_ = parentNodeWrapper.lastChild;
-      if (parentNodeWrapper.lastChild === parentNodeWrapper.firstChild) parentNodeWrapper.firstChild_ = parentNodeWrapper.firstChild;
-      var lastChildWrapper = wrap(parentNode.lastChild);
-      if (lastChildWrapper) lastChildWrapper.nextSibling_ = lastChildWrapper.nextSibling;
-    } else {
-      if (parentNodeWrapper.firstChild === refChildWrapper) parentNodeWrapper.firstChild_ = refChildWrapper;
-      refChildWrapper.previousSibling_ = refChildWrapper.previousSibling;
-    }
-    scope.originalInsertBefore.call(parentNode, newChild, refChild);
-  }
-  function remove(nodeWrapper) {
-    var node = unwrap(nodeWrapper);
-    var parentNode = node.parentNode;
-    if (!parentNode) return;
-    var parentNodeWrapper = wrap(parentNode);
-    updateWrapperUpAndSideways(nodeWrapper);
-    if (nodeWrapper.previousSibling) nodeWrapper.previousSibling.nextSibling_ = nodeWrapper;
-    if (nodeWrapper.nextSibling) nodeWrapper.nextSibling.previousSibling_ = nodeWrapper;
-    if (parentNodeWrapper.lastChild === nodeWrapper) parentNodeWrapper.lastChild_ = nodeWrapper;
-    if (parentNodeWrapper.firstChild === nodeWrapper) parentNodeWrapper.firstChild_ = nodeWrapper;
-    scope.originalRemoveChild.call(parentNode, node);
-  }
-  var distributedNodesTable = new WeakMap();
-  var destinationInsertionPointsTable = new WeakMap();
-  var rendererForHostTable = new WeakMap();
-  function resetDistributedNodes(insertionPoint) {
-    distributedNodesTable.set(insertionPoint, []);
-  }
-  function getDistributedNodes(insertionPoint) {
-    var rv = distributedNodesTable.get(insertionPoint);
-    if (!rv) distributedNodesTable.set(insertionPoint, rv = []);
-    return rv;
-  }
-  function getChildNodesSnapshot(node) {
-    var result = [], i = 0;
-    for (var child = node.firstChild; child; child = child.nextSibling) {
-      result[i++] = child;
-    }
-    return result;
-  }
-  var request = oneOf(window, [ "requestAnimationFrame", "mozRequestAnimationFrame", "webkitRequestAnimationFrame", "setTimeout" ]);
-  var pendingDirtyRenderers = [];
-  var renderTimer;
-  function renderAllPending() {
-    for (var i = 0; i < pendingDirtyRenderers.length; i++) {
-      var renderer = pendingDirtyRenderers[i];
-      var parentRenderer = renderer.parentRenderer;
-      if (parentRenderer && parentRenderer.dirty) continue;
-      renderer.render();
-    }
-    pendingDirtyRenderers = [];
-  }
-  function handleRequestAnimationFrame() {
-    renderTimer = null;
-    renderAllPending();
-  }
-  function getRendererForHost(host) {
-    var renderer = rendererForHostTable.get(host);
-    if (!renderer) {
-      renderer = new ShadowRenderer(host);
-      rendererForHostTable.set(host, renderer);
-    }
-    return renderer;
-  }
-  function getShadowRootAncestor(node) {
-    var root = getTreeScope(node).root;
-    if (root instanceof ShadowRoot) return root;
-    return null;
-  }
-  function getRendererForShadowRoot(shadowRoot) {
-    return getRendererForHost(shadowRoot.host);
-  }
-  var spliceDiff = new ArraySplice();
-  spliceDiff.equals = function(renderNode, rawNode) {
-    return unwrap(renderNode.node) === rawNode;
-  };
-  function RenderNode(node) {
-    this.skip = false;
-    this.node = node;
-    this.childNodes = [];
-  }
-  RenderNode.prototype = {
-    append: function(node) {
-      var rv = new RenderNode(node);
-      this.childNodes.push(rv);
-      return rv;
-    },
-    sync: function(opt_added) {
-      if (this.skip) return;
-      var nodeWrapper = this.node;
-      var newChildren = this.childNodes;
-      var oldChildren = getChildNodesSnapshot(unwrap(nodeWrapper));
-      var added = opt_added || new WeakMap();
-      var splices = spliceDiff.calculateSplices(newChildren, oldChildren);
-      var newIndex = 0, oldIndex = 0;
-      var lastIndex = 0;
-      for (var i = 0; i < splices.length; i++) {
-        var splice = splices[i];
-        for (;lastIndex < splice.index; lastIndex++) {
-          oldIndex++;
-          newChildren[newIndex++].sync(added);
-        }
-        var removedCount = splice.removed.length;
-        for (var j = 0; j < removedCount; j++) {
-          var wrapper = wrap(oldChildren[oldIndex++]);
-          if (!added.get(wrapper)) remove(wrapper);
-        }
-        var addedCount = splice.addedCount;
-        var refNode = oldChildren[oldIndex] && wrap(oldChildren[oldIndex]);
-        for (var j = 0; j < addedCount; j++) {
-          var newChildRenderNode = newChildren[newIndex++];
-          var newChildWrapper = newChildRenderNode.node;
-          insertBefore(nodeWrapper, newChildWrapper, refNode);
-          added.set(newChildWrapper, true);
-          newChildRenderNode.sync(added);
-        }
-        lastIndex += addedCount;
-      }
-      for (var i = lastIndex; i < newChildren.length; i++) {
-        newChildren[i].sync(added);
-      }
-    }
-  };
-  function ShadowRenderer(host) {
-    this.host = host;
-    this.dirty = false;
-    this.invalidateAttributes();
-    this.associateNode(host);
-  }
-  ShadowRenderer.prototype = {
-    render: function(opt_renderNode) {
-      if (!this.dirty) return;
-      this.invalidateAttributes();
-      var host = this.host;
-      this.distribution(host);
-      var renderNode = opt_renderNode || new RenderNode(host);
-      this.buildRenderTree(renderNode, host);
-      var topMostRenderer = !opt_renderNode;
-      if (topMostRenderer) renderNode.sync();
-      this.dirty = false;
-    },
-    get parentRenderer() {
-      return getTreeScope(this.host).renderer;
-    },
-    invalidate: function() {
-      if (!this.dirty) {
-        this.dirty = true;
-        var parentRenderer = this.parentRenderer;
-        if (parentRenderer) parentRenderer.invalidate();
-        pendingDirtyRenderers.push(this);
-        if (renderTimer) return;
-        renderTimer = window[request](handleRequestAnimationFrame, 0);
-      }
-    },
-    distribution: function(root) {
-      this.resetAllSubtrees(root);
-      this.distributionResolution(root);
-    },
-    resetAll: function(node) {
-      if (isInsertionPoint(node)) resetDistributedNodes(node); else resetDestinationInsertionPoints(node);
-      this.resetAllSubtrees(node);
-    },
-    resetAllSubtrees: function(node) {
-      for (var child = node.firstChild; child; child = child.nextSibling) {
-        this.resetAll(child);
-      }
-      if (node.shadowRoot) this.resetAll(node.shadowRoot);
-      if (node.olderShadowRoot) this.resetAll(node.olderShadowRoot);
-    },
-    distributionResolution: function(node) {
-      if (isShadowHost(node)) {
-        var shadowHost = node;
-        var pool = poolPopulation(shadowHost);
-        var shadowTrees = getShadowTrees(shadowHost);
-        for (var i = 0; i < shadowTrees.length; i++) {
-          this.poolDistribution(shadowTrees[i], pool);
-        }
-        for (var i = shadowTrees.length - 1; i >= 0; i--) {
-          var shadowTree = shadowTrees[i];
-          var shadow = getShadowInsertionPoint(shadowTree);
-          if (shadow) {
-            var olderShadowRoot = shadowTree.olderShadowRoot;
-            if (olderShadowRoot) {
-              pool = poolPopulation(olderShadowRoot);
-            }
-            for (var j = 0; j < pool.length; j++) {
-              destributeNodeInto(pool[j], shadow);
-            }
-          }
-          this.distributionResolution(shadowTree);
-        }
-      }
-      for (var child = node.firstChild; child; child = child.nextSibling) {
-        this.distributionResolution(child);
-      }
-    },
-    poolDistribution: function(node, pool) {
-      if (node instanceof HTMLShadowElement) return;
-      if (node instanceof HTMLContentElement) {
-        var content = node;
-        this.updateDependentAttributes(content.getAttribute("select"));
-        var anyDistributed = false;
-        for (var i = 0; i < pool.length; i++) {
-          var node = pool[i];
-          if (!node) continue;
-          if (matches(node, content)) {
-            destributeNodeInto(node, content);
-            pool[i] = undefined;
-            anyDistributed = true;
-          }
-        }
-        if (!anyDistributed) {
-          for (var child = content.firstChild; child; child = child.nextSibling) {
-            destributeNodeInto(child, content);
-          }
-        }
-        return;
-      }
-      for (var child = node.firstChild; child; child = child.nextSibling) {
-        this.poolDistribution(child, pool);
-      }
-    },
-    buildRenderTree: function(renderNode, node) {
-      var children = this.compose(node);
-      for (var i = 0; i < children.length; i++) {
-        var child = children[i];
-        var childRenderNode = renderNode.append(child);
-        this.buildRenderTree(childRenderNode, child);
-      }
-      if (isShadowHost(node)) {
-        var renderer = getRendererForHost(node);
-        renderer.dirty = false;
-      }
-    },
-    compose: function(node) {
-      var children = [];
-      var p = node.shadowRoot || node;
-      for (var child = p.firstChild; child; child = child.nextSibling) {
-        if (isInsertionPoint(child)) {
-          this.associateNode(p);
-          var distributedNodes = getDistributedNodes(child);
-          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;
-    },
-    invalidateAttributes: function() {
-      this.attributes = Object.create(null);
-    },
-    updateDependentAttributes: function(selector) {
-      if (!selector) return;
-      var attributes = this.attributes;
-      if (/\.\w+/.test(selector)) attributes["class"] = true;
-      if (/#\w+/.test(selector)) attributes["id"] = true;
-      selector.replace(/\[\s*([^\s=\|~\]]+)/g, function(_, name) {
-        attributes[name] = true;
-      });
-    },
-    dependsOnAttribute: function(name) {
-      return this.attributes[name];
-    },
-    associateNode: function(node) {
-      unsafeUnwrap(node).polymerShadowRenderer_ = this;
-    }
-  };
-  function poolPopulation(node) {
-    var pool = [];
-    for (var child = node.firstChild; child; child = child.nextSibling) {
-      if (isInsertionPoint(child)) {
-        pool.push.apply(pool, getDistributedNodes(child));
-      } else {
-        pool.push(child);
-      }
-    }
-    return pool;
-  }
-  function getShadowInsertionPoint(node) {
-    if (node instanceof HTMLShadowElement) return node;
-    if (node instanceof HTMLContentElement) return null;
-    for (var child = node.firstChild; child; child = child.nextSibling) {
-      var res = getShadowInsertionPoint(child);
-      if (res) return res;
-    }
-    return null;
-  }
-  function destributeNodeInto(child, insertionPoint) {
-    getDistributedNodes(insertionPoint).push(child);
-    var points = destinationInsertionPointsTable.get(child);
-    if (!points) destinationInsertionPointsTable.set(child, [ insertionPoint ]); else points.push(insertionPoint);
-  }
-  function getDestinationInsertionPoints(node) {
-    return destinationInsertionPointsTable.get(node);
-  }
-  function resetDestinationInsertionPoints(node) {
-    destinationInsertionPointsTable.set(node, undefined);
-  }
-  var selectorStartCharRe = /^(:not\()?[*.#[a-zA-Z_|]/;
-  function matches(node, contentElement) {
-    var select = contentElement.getAttribute("select");
-    if (!select) return true;
-    select = select.trim();
-    if (!select) return true;
-    if (!(node instanceof Element)) return false;
-    if (!selectorStartCharRe.test(select)) return false;
-    try {
-      return node.matches(select);
-    } catch (ex) {
-      return false;
-    }
-  }
-  function isFinalDestination(insertionPoint, node) {
-    var points = getDestinationInsertionPoints(node);
-    return points && points[points.length - 1] === insertionPoint;
-  }
-  function isInsertionPoint(node) {
-    return node instanceof HTMLContentElement || node instanceof HTMLShadowElement;
-  }
-  function isShadowHost(shadowHost) {
-    return shadowHost.shadowRoot;
-  }
-  function getShadowTrees(host) {
-    var trees = [];
-    for (var tree = host.shadowRoot; tree; tree = tree.olderShadowRoot) {
-      trees.push(tree);
-    }
-    return trees;
-  }
-  function render(host) {
-    new ShadowRenderer(host).render();
-  }
-  Node.prototype.invalidateShadowRenderer = function(force) {
-    var renderer = unsafeUnwrap(this).polymerShadowRenderer_;
-    if (renderer) {
-      renderer.invalidate();
-      return true;
-    }
-    return false;
-  };
-  HTMLContentElement.prototype.getDistributedNodes = HTMLShadowElement.prototype.getDistributedNodes = function() {
-    renderAllPending();
-    return getDistributedNodes(this);
-  };
-  Element.prototype.getDestinationInsertionPoints = function() {
-    renderAllPending();
-    return getDestinationInsertionPoints(this) || [];
-  };
-  HTMLContentElement.prototype.nodeIsInserted_ = HTMLShadowElement.prototype.nodeIsInserted_ = function() {
-    this.invalidateShadowRenderer();
-    var shadowRoot = getShadowRootAncestor(this);
-    var renderer;
-    if (shadowRoot) renderer = getRendererForShadowRoot(shadowRoot);
-    unsafeUnwrap(this).polymerShadowRenderer_ = renderer;
-    if (renderer) renderer.invalidate();
-  };
-  scope.getRendererForHost = getRendererForHost;
-  scope.getShadowTrees = getShadowTrees;
-  scope.renderAllPending = renderAllPending;
-  scope.getDestinationInsertionPoints = getDestinationInsertionPoints;
-  scope.visual = {
-    insertBefore: insertBefore,
-    remove: remove
-  };
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var HTMLElement = scope.wrappers.HTMLElement;
-  var assert = scope.assert;
-  var mixin = scope.mixin;
-  var registerWrapper = scope.registerWrapper;
-  var unwrap = scope.unwrap;
-  var wrap = scope.wrap;
-  var elementsWithFormProperty = [ "HTMLButtonElement", "HTMLFieldSetElement", "HTMLInputElement", "HTMLKeygenElement", "HTMLLabelElement", "HTMLLegendElement", "HTMLObjectElement", "HTMLOutputElement", "HTMLTextAreaElement" ];
-  function createWrapperConstructor(name) {
-    if (!window[name]) return;
-    assert(!scope.wrappers[name]);
-    var GeneratedWrapper = function(node) {
-      HTMLElement.call(this, node);
-    };
-    GeneratedWrapper.prototype = Object.create(HTMLElement.prototype);
-    mixin(GeneratedWrapper.prototype, {
-      get form() {
-        return wrap(unwrap(this).form);
-      }
-    });
-    registerWrapper(window[name], GeneratedWrapper, document.createElement(name.slice(4, -7)));
-    scope.wrappers[name] = GeneratedWrapper;
-  }
-  elementsWithFormProperty.forEach(createWrapperConstructor);
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var registerWrapper = scope.registerWrapper;
-  var setWrapper = scope.setWrapper;
-  var unsafeUnwrap = scope.unsafeUnwrap;
-  var unwrap = scope.unwrap;
-  var unwrapIfNeeded = scope.unwrapIfNeeded;
-  var wrap = scope.wrap;
-  var OriginalSelection = window.Selection;
-  function Selection(impl) {
-    setWrapper(impl, this);
-  }
-  Selection.prototype = {
-    get anchorNode() {
-      return wrap(unsafeUnwrap(this).anchorNode);
-    },
-    get focusNode() {
-      return wrap(unsafeUnwrap(this).focusNode);
-    },
-    addRange: function(range) {
-      unsafeUnwrap(this).addRange(unwrap(range));
-    },
-    collapse: function(node, index) {
-      unsafeUnwrap(this).collapse(unwrapIfNeeded(node), index);
-    },
-    containsNode: function(node, allowPartial) {
-      return unsafeUnwrap(this).containsNode(unwrapIfNeeded(node), allowPartial);
-    },
-    extend: function(node, offset) {
-      unsafeUnwrap(this).extend(unwrapIfNeeded(node), offset);
-    },
-    getRangeAt: function(index) {
-      return wrap(unsafeUnwrap(this).getRangeAt(index));
-    },
-    removeRange: function(range) {
-      unsafeUnwrap(this).removeRange(unwrap(range));
-    },
-    selectAllChildren: function(node) {
-      unsafeUnwrap(this).selectAllChildren(unwrapIfNeeded(node));
-    },
-    toString: function() {
-      return unsafeUnwrap(this).toString();
-    }
-  };
-  registerWrapper(window.Selection, Selection, window.getSelection());
-  scope.wrappers.Selection = Selection;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var GetElementsByInterface = scope.GetElementsByInterface;
-  var Node = scope.wrappers.Node;
-  var ParentNodeInterface = scope.ParentNodeInterface;
-  var Selection = scope.wrappers.Selection;
-  var SelectorsInterface = scope.SelectorsInterface;
-  var ShadowRoot = scope.wrappers.ShadowRoot;
-  var TreeScope = scope.TreeScope;
-  var cloneNode = scope.cloneNode;
-  var defineWrapGetter = scope.defineWrapGetter;
-  var elementFromPoint = scope.elementFromPoint;
-  var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
-  var matchesNames = scope.matchesNames;
-  var mixin = scope.mixin;
-  var registerWrapper = scope.registerWrapper;
-  var renderAllPending = scope.renderAllPending;
-  var rewrap = scope.rewrap;
-  var setWrapper = scope.setWrapper;
-  var unsafeUnwrap = scope.unsafeUnwrap;
-  var unwrap = scope.unwrap;
-  var wrap = scope.wrap;
-  var wrapEventTargetMethods = scope.wrapEventTargetMethods;
-  var wrapNodeList = scope.wrapNodeList;
-  var implementationTable = new WeakMap();
-  function Document(node) {
-    Node.call(this, node);
-    this.treeScope_ = new TreeScope(this, null);
-  }
-  Document.prototype = Object.create(Node.prototype);
-  defineWrapGetter(Document, "documentElement");
-  defineWrapGetter(Document, "body");
-  defineWrapGetter(Document, "head");
-  function wrapMethod(name) {
-    var original = document[name];
-    Document.prototype[name] = function() {
-      return wrap(original.apply(unsafeUnwrap(this), arguments));
-    };
-  }
-  [ "createComment", "createDocumentFragment", "createElement", "createElementNS", "createEvent", "createEventNS", "createRange", "createTextNode", "getElementById" ].forEach(wrapMethod);
-  var originalAdoptNode = document.adoptNode;
-  function adoptNodeNoRemove(node, doc) {
-    originalAdoptNode.call(unsafeUnwrap(doc), unwrap(node));
-    adoptSubtree(node, doc);
-  }
-  function adoptSubtree(node, doc) {
-    if (node.shadowRoot) doc.adoptNode(node.shadowRoot);
-    if (node instanceof ShadowRoot) adoptOlderShadowRoots(node, doc);
-    for (var child = node.firstChild; child; child = child.nextSibling) {
-      adoptSubtree(child, doc);
-    }
-  }
-  function adoptOlderShadowRoots(shadowRoot, doc) {
-    var oldShadowRoot = shadowRoot.olderShadowRoot;
-    if (oldShadowRoot) doc.adoptNode(oldShadowRoot);
-  }
-  var originalGetSelection = document.getSelection;
-  mixin(Document.prototype, {
-    adoptNode: function(node) {
-      if (node.parentNode) node.parentNode.removeChild(node);
-      adoptNodeNoRemove(node, this);
-      return node;
-    },
-    elementFromPoint: function(x, y) {
-      return elementFromPoint(this, this, x, y);
-    },
-    importNode: function(node, deep) {
-      return cloneNode(node, deep, unsafeUnwrap(this));
-    },
-    getSelection: function() {
-      renderAllPending();
-      return new Selection(originalGetSelection.call(unwrap(this)));
-    },
-    getElementsByName: function(name) {
-      return SelectorsInterface.querySelectorAll.call(this, "[name=" + JSON.stringify(String(name)) + "]");
-    }
-  });
-  if (document.registerElement) {
-    var originalRegisterElement = document.registerElement;
-    Document.prototype.registerElement = function(tagName, object) {
-      var prototype, extendsOption;
-      if (object !== undefined) {
-        prototype = object.prototype;
-        extendsOption = object.extends;
-      }
-      if (!prototype) prototype = Object.create(HTMLElement.prototype);
-      if (scope.nativePrototypeTable.get(prototype)) {
-        throw new Error("NotSupportedError");
-      }
-      var proto = Object.getPrototypeOf(prototype);
-      var nativePrototype;
-      var prototypes = [];
-      while (proto) {
-        nativePrototype = scope.nativePrototypeTable.get(proto);
-        if (nativePrototype) break;
-        prototypes.push(proto);
-        proto = Object.getPrototypeOf(proto);
-      }
-      if (!nativePrototype) {
-        throw new Error("NotSupportedError");
-      }
-      var newPrototype = Object.create(nativePrototype);
-      for (var i = prototypes.length - 1; i >= 0; i--) {
-        newPrototype = Object.create(newPrototype);
-      }
-      [ "createdCallback", "attachedCallback", "detachedCallback", "attributeChangedCallback" ].forEach(function(name) {
-        var f = prototype[name];
-        if (!f) return;
-        newPrototype[name] = function() {
-          if (!(wrap(this) instanceof CustomElementConstructor)) {
-            rewrap(this);
-          }
-          f.apply(wrap(this), arguments);
-        };
-      });
-      var p = {
-        prototype: newPrototype
-      };
-      if (extendsOption) p.extends = extendsOption;
-      function CustomElementConstructor(node) {
-        if (!node) {
-          if (extendsOption) {
-            return document.createElement(extendsOption, tagName);
-          } else {
-            return document.createElement(tagName);
-          }
-        }
-        setWrapper(node, this);
-      }
-      CustomElementConstructor.prototype = prototype;
-      CustomElementConstructor.prototype.constructor = CustomElementConstructor;
-      scope.constructorTable.set(newPrototype, CustomElementConstructor);
-      scope.nativePrototypeTable.set(prototype, newPrototype);
-      var nativeConstructor = originalRegisterElement.call(unwrap(this), tagName, p);
-      return CustomElementConstructor;
-    };
-    forwardMethodsToWrapper([ window.HTMLDocument || window.Document ], [ "registerElement" ]);
-  }
-  forwardMethodsToWrapper([ window.HTMLBodyElement, window.HTMLDocument || window.Document, window.HTMLHeadElement, window.HTMLHtmlElement ], [ "appendChild", "compareDocumentPosition", "contains", "getElementsByClassName", "getElementsByTagName", "getElementsByTagNameNS", "insertBefore", "querySelector", "querySelectorAll", "removeChild", "replaceChild" ]);
-  forwardMethodsToWrapper([ window.HTMLBodyElement, window.HTMLHeadElement, window.HTMLHtmlElement ], matchesNames);
-  forwardMethodsToWrapper([ window.HTMLDocument || window.Document ], [ "adoptNode", "importNode", "contains", "createComment", "createDocumentFragment", "createElement", "createElementNS", "createEvent", "createEventNS", "createRange", "createTextNode", "elementFromPoint", "getElementById", "getElementsByName", "getSelection" ]);
-  mixin(Document.prototype, GetElementsByInterface);
-  mixin(Document.prototype, ParentNodeInterface);
-  mixin(Document.prototype, SelectorsInterface);
-  mixin(Document.prototype, {
-    get implementation() {
-      var implementation = implementationTable.get(this);
-      if (implementation) return implementation;
-      implementation = new DOMImplementation(unwrap(this).implementation);
-      implementationTable.set(this, implementation);
-      return implementation;
-    },
-    get defaultView() {
-      return wrap(unwrap(this).defaultView);
-    }
-  });
-  registerWrapper(window.Document, Document, document.implementation.createHTMLDocument(""));
-  if (window.HTMLDocument) registerWrapper(window.HTMLDocument, Document);
-  wrapEventTargetMethods([ window.HTMLBodyElement, window.HTMLDocument || window.Document, window.HTMLHeadElement ]);
-  function DOMImplementation(impl) {
-    setWrapper(impl, this);
-  }
-  function wrapImplMethod(constructor, name) {
-    var original = document.implementation[name];
-    constructor.prototype[name] = function() {
-      return wrap(original.apply(unsafeUnwrap(this), arguments));
-    };
-  }
-  function forwardImplMethod(constructor, name) {
-    var original = document.implementation[name];
-    constructor.prototype[name] = function() {
-      return original.apply(unsafeUnwrap(this), arguments);
-    };
-  }
-  wrapImplMethod(DOMImplementation, "createDocumentType");
-  wrapImplMethod(DOMImplementation, "createDocument");
-  wrapImplMethod(DOMImplementation, "createHTMLDocument");
-  forwardImplMethod(DOMImplementation, "hasFeature");
-  registerWrapper(window.DOMImplementation, DOMImplementation);
-  forwardMethodsToWrapper([ window.DOMImplementation ], [ "createDocumentType", "createDocument", "createHTMLDocument", "hasFeature" ]);
-  scope.adoptNodeNoRemove = adoptNodeNoRemove;
-  scope.wrappers.DOMImplementation = DOMImplementation;
-  scope.wrappers.Document = Document;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var EventTarget = scope.wrappers.EventTarget;
-  var Selection = scope.wrappers.Selection;
-  var mixin = scope.mixin;
-  var registerWrapper = scope.registerWrapper;
-  var renderAllPending = scope.renderAllPending;
-  var unwrap = scope.unwrap;
-  var unwrapIfNeeded = scope.unwrapIfNeeded;
-  var wrap = scope.wrap;
-  var OriginalWindow = window.Window;
-  var originalGetComputedStyle = window.getComputedStyle;
-  var originalGetDefaultComputedStyle = window.getDefaultComputedStyle;
-  var originalGetSelection = window.getSelection;
-  function Window(impl) {
-    EventTarget.call(this, impl);
-  }
-  Window.prototype = Object.create(EventTarget.prototype);
-  OriginalWindow.prototype.getComputedStyle = function(el, pseudo) {
-    return wrap(this || window).getComputedStyle(unwrapIfNeeded(el), pseudo);
-  };
-  if (originalGetDefaultComputedStyle) {
-    OriginalWindow.prototype.getDefaultComputedStyle = function(el, pseudo) {
-      return wrap(this || window).getDefaultComputedStyle(unwrapIfNeeded(el), pseudo);
-    };
-  }
-  OriginalWindow.prototype.getSelection = function() {
-    return wrap(this || window).getSelection();
-  };
-  delete window.getComputedStyle;
-  delete window.getDefaultComputedStyle;
-  delete window.getSelection;
-  [ "addEventListener", "removeEventListener", "dispatchEvent" ].forEach(function(name) {
-    OriginalWindow.prototype[name] = function() {
-      var w = wrap(this || window);
-      return w[name].apply(w, arguments);
-    };
-    delete window[name];
-  });
-  mixin(Window.prototype, {
-    getComputedStyle: function(el, pseudo) {
-      renderAllPending();
-      return originalGetComputedStyle.call(unwrap(this), unwrapIfNeeded(el), pseudo);
-    },
-    getSelection: function() {
-      renderAllPending();
-      return new Selection(originalGetSelection.call(unwrap(this)));
-    },
-    get document() {
-      return wrap(unwrap(this).document);
-    }
-  });
-  if (originalGetDefaultComputedStyle) {
-    Window.prototype.getDefaultComputedStyle = function(el, pseudo) {
-      renderAllPending();
-      return originalGetDefaultComputedStyle.call(unwrap(this), unwrapIfNeeded(el), pseudo);
-    };
-  }
-  registerWrapper(OriginalWindow, Window, window);
-  scope.wrappers.Window = Window;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var unwrap = scope.unwrap;
-  var OriginalDataTransfer = window.DataTransfer || window.Clipboard;
-  var OriginalDataTransferSetDragImage = OriginalDataTransfer.prototype.setDragImage;
-  if (OriginalDataTransferSetDragImage) {
-    OriginalDataTransfer.prototype.setDragImage = function(image, x, y) {
-      OriginalDataTransferSetDragImage.call(this, unwrap(image), x, y);
-    };
-  }
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var registerWrapper = scope.registerWrapper;
-  var setWrapper = scope.setWrapper;
-  var unwrap = scope.unwrap;
-  var OriginalFormData = window.FormData;
-  if (!OriginalFormData) return;
-  function FormData(formElement) {
-    var impl;
-    if (formElement instanceof OriginalFormData) {
-      impl = formElement;
-    } else {
-      impl = new OriginalFormData(formElement && unwrap(formElement));
-    }
-    setWrapper(impl, this);
-  }
-  registerWrapper(OriginalFormData, FormData, new OriginalFormData());
-  scope.wrappers.FormData = FormData;
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var unwrapIfNeeded = scope.unwrapIfNeeded;
-  var originalSend = XMLHttpRequest.prototype.send;
-  XMLHttpRequest.prototype.send = function(obj) {
-    return originalSend.call(this, unwrapIfNeeded(obj));
-  };
-})(window.ShadowDOMPolyfill);
-
-(function(scope) {
-  "use strict";
-  var isWrapperFor = scope.isWrapperFor;
-  var elements = {
-    a: "HTMLAnchorElement",
-    area: "HTMLAreaElement",
-    audio: "HTMLAudioElement",
-    base: "HTMLBaseElement",
-    body: "HTMLBodyElement",
-    br: "HTMLBRElement",
-    button: "HTMLButtonElement",
-    canvas: "HTMLCanvasElement",
-    caption: "HTMLTableCaptionElement",
-    col: "HTMLTableColElement",
-    content: "HTMLContentElement",
-    data: "HTMLDataElement",
-    datalist: "HTMLDataListElement",
-    del: "HTMLModElement",
-    dir: "HTMLDirectoryElement",
-    div: "HTMLDivElement",
-    dl: "HTMLDListElement",
-    embed: "HTMLEmbedElement",
-    fieldset: "HTMLFieldSetElement",
-    font: "HTMLFontElement",
-    form: "HTMLFormElement",
-    frame: "HTMLFrameElement",
-    frameset: "HTMLFrameSetElement",
-    h1: "HTMLHeadingElement",
-    head: "HTMLHeadElement",
-    hr: "HTMLHRElement",
-    html: "HTMLHtmlElement",
-    iframe: "HTMLIFrameElement",
-    img: "HTMLImageElement",
-    input: "HTMLInputElement",
-    keygen: "HTMLKeygenElement",
-    label: "HTMLLabelElement",
-    legend: "HTMLLegendElement",
-    li: "HTMLLIElement",
-    link: "HTMLLinkElement",
-    map: "HTMLMapElement",
-    marquee: "HTMLMarqueeElement",
-    menu: "HTMLMenuElement",
-    menuitem: "HTMLMenuItemElement",
-    meta: "HTMLMetaElement",
-    meter: "HTMLMeterElement",
-    object: "HTMLObjectElement",
-    ol: "HTMLOListElement",
-    optgroup: "HTMLOptGroupElement",
-    option: "HTMLOptionElement",
-    output: "HTMLOutputElement",
-    p: "HTMLParagraphElement",
-    param: "HTMLParamElement",
-    pre: "HTMLPreElement",
-    progress: "HTMLProgressElement",
-    q: "HTMLQuoteElement",
-    script: "HTMLScriptElement",
-    select: "HTMLSelectElement",
-    shadow: "HTMLShadowElement",
-    source: "HTMLSourceElement",
-    span: "HTMLSpanElement",
-    style: "HTMLStyleElement",
-    table: "HTMLTableElement",
-    tbody: "HTMLTableSectionElement",
-    template: "HTMLTemplateElement",
-    textarea: "HTMLTextAreaElement",
-    thead: "HTMLTableSectionElement",
-    time: "HTMLTimeElement",
-    title: "HTMLTitleElement",
-    tr: "HTMLTableRowElement",
-    track: "HTMLTrackElement",
-    ul: "HTMLUListElement",
-    video: "HTMLVideoElement"
-  };
-  function overrideConstructor(tagName) {
-    var nativeConstructorName = elements[tagName];
-    var nativeConstructor = window[nativeConstructorName];
-    if (!nativeConstructor) return;
-    var element = document.createElement(tagName);
-    var wrapperConstructor = element.constructor;
-    window[nativeConstructorName] = wrapperConstructor;
-  }
-  Object.keys(elements).forEach(overrideConstructor);
-  Object.getOwnPropertyNames(scope.wrappers).forEach(function(name) {
-    window[name] = scope.wrappers[name];
-  });
-})(window.ShadowDOMPolyfill);
\ No newline at end of file
diff --git a/example/bower_components/webcomponentsjs/ShadowDOM.min.js b/example/bower_components/webcomponentsjs/ShadowDOM.min.js
deleted file mode 100644
index 72faf74ca..000000000
--- a/example/bower_components/webcomponentsjs/ShadowDOM.min.js
+++ /dev/null
@@ -1,13 +0,0 @@
-/**
- * @license
- * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
- * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
- * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
- * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
- * Code distributed by Google as part of the polymer project is also
- * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
- */
-// @version 0.5.5
-"undefined"==typeof WeakMap&&!function(){var e=Object.defineProperty,t=Date.now()%1e9,n=function(){this.name="__st"+(1e9*Math.random()>>>0)+(t++ +"__")};n.prototype={set:function(t,n){var r=t[this.name];return r&&r[0]===t?r[1]=n:e(t,this.name,{value:[t,n],writable:!0}),this},get:function(e){var t;return(t=e[this.name])&&t[0]===e?t[1]:void 0},"delete":function(e){var t=e[this.name];return t&&t[0]===e?(t[0]=t[1]=void 0,!0):!1},has:function(e){var t=e[this.name];return t?t[0]===e:!1}},window.WeakMap=n}(),window.ShadowDOMPolyfill={},function(e){"use strict";function t(){if("undefined"!=typeof chrome&&chrome.app&&chrome.app.runtime)return!1;if(navigator.getDeviceStorage)return!1;try{var e=new Function("return true;");return e()}catch(t){return!1}}function n(e){if(!e)throw new Error("Assertion failed")}function r(e,t){for(var n=k(t),r=0;ru;u++)c[u]=new Array(s),c[u][0]=u;for(var l=0;s>l;l++)c[0][l]=l;for(var u=1;a>u;u++)for(var l=1;s>l;l++)if(this.equals(e[t+l-1],r[o+u-1]))c[u][l]=c[u-1][l-1];else{var p=c[u-1][l]+1,d=c[u][l-1]+1;c[u][l]=d>p?p:d}return c},spliceOperationsFromEditDistances:function(e){for(var t=e.length-1,n=e[0].length-1,s=e[t][n],c=[];t>0||n>0;)if(0!=t)if(0!=n){var u,l=e[t-1][n-1],p=e[t-1][n],d=e[t][n-1];u=d>p?l>p?p:l:l>d?d:l,u==l?(l==s?c.push(r):(c.push(o),s=l),t--,n--):u==p?(c.push(a),t--,s=p):(c.push(i),n--,s=d)}else c.push(a),t--;else c.push(i),n--;return c.reverse(),c},calcSplices:function(e,n,s,c,u,l){var p=0,d=0,f=Math.min(s-n,l-u);if(0==n&&0==u&&(p=this.sharedPrefix(e,c,f)),s==e.length&&l==c.length&&(d=this.sharedSuffix(e,c,f-p)),n+=p,u+=p,s-=d,l-=d,s-n==0&&l-u==0)return[];if(n==s){for(var h=t(n,[],0);l>u;)h.removed.push(c[u++]);return[h]}if(u==l)return[t(n,[],s-n)];for(var w=this.spliceOperationsFromEditDistances(this.calcEditDistances(e,n,s,c,u,l)),h=void 0,m=[],g=n,v=u,b=0;br;r++)if(!this.equals(e[r],t[r]))return r;return n},sharedSuffix:function(e,t,n){for(var r=e.length,o=t.length,i=0;n>i&&this.equals(e[--r],t[--o]);)i++;return i},calculateSplices:function(e,t){return this.calcSplices(e,0,e.length,t,0,t.length)},equals:function(e,t){return e===t}},e.ArraySplice=n}(window.ShadowDOMPolyfill),function(e){"use strict";function t(){a=!1;var e=i.slice(0);i=[];for(var t=0;t0){for(var l=0;l0&&r.length>0;){var i=n.pop(),a=r.pop();if(i!==a)break;o=i}return o}function l(e,t,n){t instanceof G.Window&&(t=t.document);var o,i=I(t),a=I(n),s=r(n,e),o=u(i,a);o||(o=a.root);for(var c=o;c;c=c.parent)for(var l=0;l0;i--)if(!v(t[i],e,o,t,r))return!1;return!0}function m(e,t,n,r){var o=it,i=t[0]||n;return v(i,e,o,t,r)}function g(e,t,n,r){for(var o=at,i=1;i0&&v(n,e,o,t,r)}function v(e,t,n,r,o){var i=X.get(e);if(!i)return!0;var a=o||s(r,e);if(a===e){if(n===ot)return!0;n===at&&(n=it)}else if(n===at&&!t.bubbles)return!0;if("relatedTarget"in t){var c=q(t),u=c.relatedTarget;if(u){if(u instanceof Object&&u.addEventListener){var p=V(u),d=l(t,e,p);if(d===a)return!0}else d=null;Z.set(t,d)}}J.set(t,n);var f=t.type,h=!1;Y.set(t,a),$.set(t,e),i.depth++;for(var w=0,m=i.length;m>w;w++){var g=i[w];if(g.removed)h=!0;else if(!(g.type!==f||!g.capture&&n===ot||g.capture&&n===at))try{if("function"==typeof g.handler?g.handler.call(e,t):g.handler.handleEvent(t),et.get(t))return!1}catch(v){W||(W=v)}}if(i.depth--,h&&0===i.depth){var b=i.slice();i.length=0;for(var w=0;wr;r++)t[r]=a(e[r]);return t.length=o,t}function o(e,t){e.prototype[t]=function(){return r(i(this)[t].apply(i(this),arguments))}}var i=e.unsafeUnwrap,a=e.wrap,s={enumerable:!1};n.prototype={item:function(e){return this[e]}},t(n.prototype,"item"),e.wrappers.NodeList=n,e.addWrapNodeListMethod=o,e.wrapNodeList=r}(window.ShadowDOMPolyfill),function(e){"use strict";e.wrapHTMLCollection=e.wrapNodeList,e.wrappers.HTMLCollection=e.wrappers.NodeList}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){L(e instanceof S)}function n(e){var t=new T;return t[0]=e,t.length=1,t}function r(e,t,n){N(t,"childList",{removedNodes:n,previousSibling:e.previousSibling,nextSibling:e.nextSibling})}function o(e,t){N(e,"childList",{removedNodes:t})}function i(e,t,r,o){if(e instanceof DocumentFragment){var i=s(e);B=!0;for(var a=i.length-1;a>=0;a--)e.removeChild(i[a]),i[a].parentNode_=t;B=!1;for(var a=0;ao;o++)r.appendChild(W(t[o]));return r}function m(e){if(void 0!==e.firstChild_)for(var t=e.firstChild_;t;){var n=t;t=t.nextSibling_,n.parentNode_=n.previousSibling_=n.nextSibling_=void 0}e.firstChild_=e.lastChild_=void 0}function g(e){if(e.invalidateShadowRenderer()){for(var t=e.firstChild;t;){L(t.parentNode===e);var n=t.nextSibling,r=W(t),o=r.parentNode;o&&K.call(o,r),t.previousSibling_=t.nextSibling_=t.parentNode_=null,t=n}e.firstChild_=e.lastChild_=null}else for(var n,i=W(e),a=i.firstChild;a;)n=a.nextSibling,K.call(i,a),a=n}function v(e){var t=e.parentNode;return t&&t.invalidateShadowRenderer()}function b(e){for(var t,n=0;ns;s++)i=b(t[s]),!o&&(a=g(i).root)&&a instanceof e.wrappers.ShadowRoot||(r[n++]=i);return n}function n(e){return String(e).replace(/\/deep\/|::shadow/g," ")}function r(e){return String(e).replace(/:host\(([^\s]+)\)/g,"$1").replace(/([^\s]):host/g,"$1").replace(":host","*").replace(/\^|\/shadow\/|\/shadow-deep\/|::shadow|\/deep\/|::content/g," ")}function o(e,t){for(var n,r=e.firstElementChild;r;){if(r.matches(t))return r;if(n=o(r,t))return n;r=r.nextElementSibling}return null}function i(e,t){return e.matches(t)}function a(e,t,n){var r=e.localName;return r===t||r===n&&e.namespaceURI===C}function s(){return!0}function c(e,t,n){return e.localName===n}function u(e,t){return e.namespaceURI===t}function l(e,t,n){return e.namespaceURI===t&&e.localName===n}function p(e,t,n,r,o,i){for(var a=e.firstElementChild;a;)r(a,o,i)&&(n[t++]=a),t=p(a,t,n,r,o,i),a=a.nextElementSibling;return t}function d(n,r,o,i,a){var s,c=v(this),u=g(this).root;if(u instanceof e.wrappers.ShadowRoot)return p(this,r,o,n,i,null);if(c instanceof N)s=M.call(c,i);else{if(!(c instanceof _))return p(this,r,o,n,i,null);s=S.call(c,i)}return t(s,r,o,a)}function f(n,r,o,i,a){var s,c=v(this),u=g(this).root;if(u instanceof e.wrappers.ShadowRoot)return p(this,r,o,n,i,a);if(c instanceof N)s=O.call(c,i,a);else{if(!(c instanceof _))return p(this,r,o,n,i,a);s=T.call(c,i,a)}return t(s,r,o,!1)}function h(n,r,o,i,a){var s,c=v(this),u=g(this).root;if(u instanceof e.wrappers.ShadowRoot)return p(this,r,o,n,i,a);if(c instanceof N)s=j.call(c,i,a);else{if(!(c instanceof _))return p(this,r,o,n,i,a);s=L.call(c,i,a)}return t(s,r,o,!1)}var w=e.wrappers.HTMLCollection,m=e.wrappers.NodeList,g=e.getTreeScope,v=e.unsafeUnwrap,b=e.wrap,y=document.querySelector,E=document.documentElement.querySelector,S=document.querySelectorAll,M=document.documentElement.querySelectorAll,T=document.getElementsByTagName,O=document.documentElement.getElementsByTagName,L=document.getElementsByTagNameNS,j=document.documentElement.getElementsByTagNameNS,N=window.Element,_=window.HTMLDocument||window.Document,C="http://www.w3.org/1999/xhtml",D={querySelector:function(t){var r=n(t),i=r!==t;t=r;var a,s=v(this),c=g(this).root;if(c instanceof e.wrappers.ShadowRoot)return o(this,t);if(s instanceof N)a=b(E.call(s,t));else{if(!(s instanceof _))return o(this,t);a=b(y.call(s,t))}return a&&!i&&(c=g(a).root)&&c instanceof e.wrappers.ShadowRoot?o(this,t):a},querySelectorAll:function(e){var t=n(e),r=t!==e;e=t;var o=new m;return o.length=d.call(this,i,0,o,e,r),o}},H={matches:function(t){return t=r(t),e.originalMatches.call(v(this),t)}},x={getElementsByTagName:function(e){var t=new w,n="*"===e?s:a;return t.length=f.call(this,n,0,t,e,e.toLowerCase()),t},getElementsByClassName:function(e){return this.querySelectorAll("."+e)},getElementsByTagNameNS:function(e,t){var n=new w,r=null;return r="*"===e?"*"===t?s:c:"*"===t?u:l,n.length=h.call(this,r,0,n,e||null,t),n}};e.GetElementsByInterface=x,e.SelectorsInterface=D,e.MatchesInterface=H}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){for(;e&&e.nodeType!==Node.ELEMENT_NODE;)e=e.nextSibling;return e}function n(e){for(;e&&e.nodeType!==Node.ELEMENT_NODE;)e=e.previousSibling;return e}var r=e.wrappers.NodeList,o={get firstElementChild(){return t(this.firstChild)
-},get lastElementChild(){return n(this.lastChild)},get childElementCount(){for(var e=0,t=this.firstElementChild;t;t=t.nextElementSibling)e++;return e},get children(){for(var e=new r,t=0,n=this.firstElementChild;n;n=n.nextElementSibling)e[t++]=n;return e.length=t,e},remove:function(){var e=this.parentNode;e&&e.removeChild(this)}},i={get nextElementSibling(){return t(this.nextSibling)},get previousElementSibling(){return n(this.previousSibling)}};e.ChildNodeInterface=i,e.ParentNodeInterface=o}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){r.call(this,e)}var n=e.ChildNodeInterface,r=e.wrappers.Node,o=e.enqueueMutation,i=e.mixin,a=e.registerWrapper,s=e.unsafeUnwrap,c=window.CharacterData;t.prototype=Object.create(r.prototype),i(t.prototype,{get textContent(){return this.data},set textContent(e){this.data=e},get data(){return s(this).data},set data(e){var t=s(this).data;o(this,"characterData",{oldValue:t}),s(this).data=e}}),i(t.prototype,n),a(c,t,document.createTextNode("")),e.wrappers.CharacterData=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){return e>>>0}function n(e){r.call(this,e)}var r=e.wrappers.CharacterData,o=(e.enqueueMutation,e.mixin),i=e.registerWrapper,a=window.Text;n.prototype=Object.create(r.prototype),o(n.prototype,{splitText:function(e){e=t(e);var n=this.data;if(e>n.length)throw new Error("IndexSizeError");var r=n.slice(0,e),o=n.slice(e);this.data=r;var i=this.ownerDocument.createTextNode(o);return this.parentNode&&this.parentNode.insertBefore(i,this.nextSibling),i}}),i(a,n,document.createTextNode("")),e.wrappers.Text=n}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){return i(e).getAttribute("class")}function n(e,t){a(e,"attributes",{name:"class",namespace:null,oldValue:t})}function r(t){e.invalidateRendererBasedOnAttribute(t,"class")}function o(e,o,i){var a=e.ownerElement_;if(null==a)return o.apply(e,i);var s=t(a),c=o.apply(e,i);return t(a)!==s&&(n(a,s),r(a)),c}if(!window.DOMTokenList)return void console.warn("Missing DOMTokenList prototype, please include a compatible classList polyfill such as http://goo.gl/uTcepH.");var i=e.unsafeUnwrap,a=e.enqueueMutation,s=DOMTokenList.prototype.add;DOMTokenList.prototype.add=function(){o(this,s,arguments)};var c=DOMTokenList.prototype.remove;DOMTokenList.prototype.remove=function(){o(this,c,arguments)};var u=DOMTokenList.prototype.toggle;DOMTokenList.prototype.toggle=function(){return o(this,u,arguments)}}(window.ShadowDOMPolyfill),function(e){"use strict";function t(t,n){var r=t.parentNode;if(r&&r.shadowRoot){var o=e.getRendererForHost(r);o.dependsOnAttribute(n)&&o.invalidate()}}function n(e,t,n){l(e,"attributes",{name:t,namespace:null,oldValue:n})}function r(e){a.call(this,e)}var o=e.ChildNodeInterface,i=e.GetElementsByInterface,a=e.wrappers.Node,s=e.ParentNodeInterface,c=e.SelectorsInterface,u=e.MatchesInterface,l=(e.addWrapNodeListMethod,e.enqueueMutation),p=e.mixin,d=(e.oneOf,e.registerWrapper),f=e.unsafeUnwrap,h=e.wrappers,w=window.Element,m=["matches","mozMatchesSelector","msMatchesSelector","webkitMatchesSelector"].filter(function(e){return w.prototype[e]}),g=m[0],v=w.prototype[g],b=new WeakMap;r.prototype=Object.create(a.prototype),p(r.prototype,{createShadowRoot:function(){var t=new h.ShadowRoot(this);f(this).polymerShadowRoot_=t;var n=e.getRendererForHost(this);return n.invalidate(),t},get shadowRoot(){return f(this).polymerShadowRoot_||null},setAttribute:function(e,r){var o=f(this).getAttribute(e);f(this).setAttribute(e,r),n(this,e,o),t(this,e)},removeAttribute:function(e){var r=f(this).getAttribute(e);f(this).removeAttribute(e),n(this,e,r),t(this,e)},get classList(){var e=b.get(this);if(!e){if(e=f(this).classList,!e)return;e.ownerElement_=this,b.set(this,e)}return e},get className(){return f(this).className},set className(e){this.setAttribute("class",e)},get id(){return f(this).id},set id(e){this.setAttribute("id",e)}}),m.forEach(function(e){"matches"!==e&&(r.prototype[e]=function(e){return this.matches(e)})}),w.prototype.webkitCreateShadowRoot&&(r.prototype.webkitCreateShadowRoot=r.prototype.createShadowRoot),p(r.prototype,o),p(r.prototype,i),p(r.prototype,s),p(r.prototype,c),p(r.prototype,u),d(w,r,document.createElementNS(null,"x")),e.invalidateRendererBasedOnAttribute=t,e.matchesNames=m,e.originalMatches=v,e.wrappers.Element=r}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){switch(e){case"&":return"&";case"<":return"<";case">":return">";case'"':return""";case" ":return" "}}function n(e){return e.replace(L,t)}function r(e){return e.replace(j,t)}function o(e){for(var t={},n=0;n";case Node.TEXT_NODE:var l=e.data;return t&&_[t.localName]?l:r(l);case Node.COMMENT_NODE:return"";default:throw console.error(e),new Error("not implemented")}}function a(e){e instanceof O.HTMLTemplateElement&&(e=e.content);for(var t="",n=e.firstChild;n;n=n.nextSibling)t+=i(n,e);return t}function s(e,t,n){var r=n||"div";e.textContent="";var o=M(e.ownerDocument.createElement(r));o.innerHTML=t;for(var i;i=o.firstChild;)e.appendChild(T(i))}function c(e){h.call(this,e)}function u(e,t){var n=M(e.cloneNode(!1));n.innerHTML=t;for(var r,o=M(document.createDocumentFragment());r=n.firstChild;)o.appendChild(r);return T(o)}function l(t){return function(){return e.renderAllPending(),S(this)[t]}}function p(e){w(c,e,l(e))}function d(t){Object.defineProperty(c.prototype,t,{get:l(t),set:function(n){e.renderAllPending(),S(this)[t]=n},configurable:!0,enumerable:!0})}function f(t){Object.defineProperty(c.prototype,t,{value:function(){return e.renderAllPending(),S(this)[t].apply(S(this),arguments)},configurable:!0,enumerable:!0})}var h=e.wrappers.Element,w=e.defineGetter,m=e.enqueueMutation,g=e.mixin,v=e.nodesWereAdded,b=e.nodesWereRemoved,y=e.registerWrapper,E=e.snapshotNodeList,S=e.unsafeUnwrap,M=e.unwrap,T=e.wrap,O=e.wrappers,L=/[&\u00A0"]/g,j=/[&\u00A0<>]/g,N=o(["area","base","br","col","command","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"]),_=o(["style","script","xmp","iframe","noembed","noframes","plaintext","noscript"]),C=/MSIE/.test(navigator.userAgent),D=window.HTMLElement,H=window.HTMLTemplateElement;c.prototype=Object.create(h.prototype),g(c.prototype,{get innerHTML(){return a(this)},set innerHTML(e){if(C&&_[this.localName])return void(this.textContent=e);var t=E(this.childNodes);this.invalidateShadowRenderer()?this instanceof O.HTMLTemplateElement?s(this.content,e):s(this,e,this.tagName):!H&&this instanceof O.HTMLTemplateElement?s(this.content,e):S(this).innerHTML=e;var n=E(this.childNodes);m(this,"childList",{addedNodes:n,removedNodes:t}),b(t),v(n,this)},get outerHTML(){return i(this,this.parentNode)},set outerHTML(e){var t=this.parentNode;if(t){t.invalidateShadowRenderer();var n=u(t,e);t.replaceChild(n,this)}},insertAdjacentHTML:function(e,t){var n,r;switch(String(e).toLowerCase()){case"beforebegin":n=this.parentNode,r=this;break;case"afterend":n=this.parentNode,r=this.nextSibling;break;case"afterbegin":n=this,r=this.firstChild;break;case"beforeend":n=this,r=null;break;default:return}var o=u(n,t);n.insertBefore(o,r)},get hidden(){return this.hasAttribute("hidden")},set hidden(e){e?this.setAttribute("hidden",""):this.removeAttribute("hidden")}}),["clientHeight","clientLeft","clientTop","clientWidth","offsetHeight","offsetLeft","offsetTop","offsetWidth","scrollHeight","scrollWidth"].forEach(p),["scrollLeft","scrollTop"].forEach(d),["getBoundingClientRect","getClientRects","scrollIntoView"].forEach(f),y(D,c,document.createElement("b")),e.wrappers.HTMLElement=c,e.getInnerHTML=a,e.setInnerHTML=s}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.unsafeUnwrap,a=e.wrap,s=window.HTMLCanvasElement;t.prototype=Object.create(n.prototype),r(t.prototype,{getContext:function(){var e=i(this).getContext.apply(i(this),arguments);return e&&a(e)}}),o(s,t,document.createElement("canvas")),e.wrappers.HTMLCanvasElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=window.HTMLContentElement;t.prototype=Object.create(n.prototype),r(t.prototype,{constructor:t,get select(){return this.getAttribute("select")},set select(e){this.setAttribute("select",e)},setAttribute:function(e,t){n.prototype.setAttribute.call(this,e,t),"select"===String(e).toLowerCase()&&this.invalidateShadowRenderer(!0)}}),i&&o(i,t),e.wrappers.HTMLContentElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.wrapHTMLCollection,a=e.unwrap,s=window.HTMLFormElement;t.prototype=Object.create(n.prototype),r(t.prototype,{get elements(){return i(a(this).elements)}}),o(s,t,document.createElement("form")),e.wrappers.HTMLFormElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){r.call(this,e)}function n(e,t){if(!(this instanceof n))throw new TypeError("DOM object constructor cannot be called as a function.");var o=i(document.createElement("img"));r.call(this,o),a(o,this),void 0!==e&&(o.width=e),void 0!==t&&(o.height=t)}var r=e.wrappers.HTMLElement,o=e.registerWrapper,i=e.unwrap,a=e.rewrap,s=window.HTMLImageElement;t.prototype=Object.create(r.prototype),o(s,t,document.createElement("img")),n.prototype=t.prototype,e.wrappers.HTMLImageElement=t,e.wrappers.Image=n}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=(e.mixin,e.wrappers.NodeList,e.registerWrapper),o=window.HTMLShadowElement;t.prototype=Object.create(n.prototype),t.prototype.constructor=t,o&&r(o,t),e.wrappers.HTMLShadowElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){if(!e.defaultView)return e;var t=p.get(e);if(!t){for(t=e.implementation.createHTMLDocument("");t.lastChild;)t.removeChild(t.lastChild);p.set(e,t)}return t}function n(e){for(var n,r=t(e.ownerDocument),o=c(r.createDocumentFragment());n=e.firstChild;)o.appendChild(n);return o}function r(e){if(o.call(this,e),!d){var t=n(e);l.set(this,u(t))}}var o=e.wrappers.HTMLElement,i=e.mixin,a=e.registerWrapper,s=e.unsafeUnwrap,c=e.unwrap,u=e.wrap,l=new WeakMap,p=new WeakMap,d=window.HTMLTemplateElement;r.prototype=Object.create(o.prototype),i(r.prototype,{constructor:r,get content(){return d?u(s(this).content):l.get(this)}}),d&&a(d,r),e.wrappers.HTMLTemplateElement=r}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.registerWrapper,o=window.HTMLMediaElement;o&&(t.prototype=Object.create(n.prototype),r(o,t,document.createElement("audio")),e.wrappers.HTMLMediaElement=t)}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){r.call(this,e)}function n(e){if(!(this instanceof n))throw new TypeError("DOM object constructor cannot be called as a function.");var t=i(document.createElement("audio"));r.call(this,t),a(t,this),t.setAttribute("preload","auto"),void 0!==e&&t.setAttribute("src",e)}var r=e.wrappers.HTMLMediaElement,o=e.registerWrapper,i=e.unwrap,a=e.rewrap,s=window.HTMLAudioElement;s&&(t.prototype=Object.create(r.prototype),o(s,t,document.createElement("audio")),n.prototype=t.prototype,e.wrappers.HTMLAudioElement=t,e.wrappers.Audio=n)}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){return e.replace(/\s+/g," ").trim()}function n(e){o.call(this,e)}function r(e,t,n,i){if(!(this instanceof r))throw new TypeError("DOM object constructor cannot be called as a function.");var a=c(document.createElement("option"));o.call(this,a),s(a,this),void 0!==e&&(a.text=e),void 0!==t&&a.setAttribute("value",t),n===!0&&a.setAttribute("selected",""),a.selected=i===!0}var o=e.wrappers.HTMLElement,i=e.mixin,a=e.registerWrapper,s=e.rewrap,c=e.unwrap,u=e.wrap,l=window.HTMLOptionElement;n.prototype=Object.create(o.prototype),i(n.prototype,{get text(){return t(this.textContent)},set text(e){this.textContent=t(String(e))},get form(){return u(c(this).form)}}),a(l,n,document.createElement("option")),r.prototype=n.prototype,e.wrappers.HTMLOptionElement=n,e.wrappers.Option=r}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.unwrap,a=e.wrap,s=window.HTMLSelectElement;t.prototype=Object.create(n.prototype),r(t.prototype,{add:function(e,t){"object"==typeof t&&(t=i(t)),i(this).add(i(e),t)},remove:function(e){return void 0===e?void n.prototype.remove.call(this):("object"==typeof e&&(e=i(e)),void i(this).remove(e))},get form(){return a(i(this).form)}}),o(s,t,document.createElement("select")),e.wrappers.HTMLSelectElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.unwrap,a=e.wrap,s=e.wrapHTMLCollection,c=window.HTMLTableElement;t.prototype=Object.create(n.prototype),r(t.prototype,{get caption(){return a(i(this).caption)},createCaption:function(){return a(i(this).createCaption())},get tHead(){return a(i(this).tHead)},createTHead:function(){return a(i(this).createTHead())},createTFoot:function(){return a(i(this).createTFoot())},get tFoot(){return a(i(this).tFoot)},get tBodies(){return s(i(this).tBodies)},createTBody:function(){return a(i(this).createTBody())},get rows(){return s(i(this).rows)},insertRow:function(e){return a(i(this).insertRow(e))}}),o(c,t,document.createElement("table")),e.wrappers.HTMLTableElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.wrapHTMLCollection,a=e.unwrap,s=e.wrap,c=window.HTMLTableSectionElement;t.prototype=Object.create(n.prototype),r(t.prototype,{constructor:t,get rows(){return i(a(this).rows)},insertRow:function(e){return s(a(this).insertRow(e))}}),o(c,t,document.createElement("thead")),e.wrappers.HTMLTableSectionElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.wrapHTMLCollection,a=e.unwrap,s=e.wrap,c=window.HTMLTableRowElement;t.prototype=Object.create(n.prototype),r(t.prototype,{get cells(){return i(a(this).cells)},insertCell:function(e){return s(a(this).insertCell(e))}}),o(c,t,document.createElement("tr")),e.wrappers.HTMLTableRowElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){switch(e.localName){case"content":return new n(e);case"shadow":return new o(e);case"template":return new i(e)}r.call(this,e)}var n=e.wrappers.HTMLContentElement,r=e.wrappers.HTMLElement,o=e.wrappers.HTMLShadowElement,i=e.wrappers.HTMLTemplateElement,a=(e.mixin,e.registerWrapper),s=window.HTMLUnknownElement;t.prototype=Object.create(r.prototype),a(s,t),e.wrappers.HTMLUnknownElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";var t=e.wrappers.Element,n=e.wrappers.HTMLElement,r=e.registerObject,o=e.defineWrapGetter,i="http://www.w3.org/2000/svg",a=document.createElementNS(i,"title"),s=r(a),c=Object.getPrototypeOf(s.prototype).constructor;if(!("classList"in a)){var u=Object.getOwnPropertyDescriptor(t.prototype,"classList");Object.defineProperty(n.prototype,"classList",u),delete t.prototype.classList}o(c,"ownerSVGElement"),e.wrappers.SVGElement=c}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){d.call(this,e)}var n=e.mixin,r=e.registerWrapper,o=e.unwrap,i=e.wrap,a=window.SVGUseElement,s="http://www.w3.org/2000/svg",c=i(document.createElementNS(s,"g")),u=document.createElementNS(s,"use"),l=c.constructor,p=Object.getPrototypeOf(l.prototype),d=p.constructor;t.prototype=Object.create(p),"instanceRoot"in u&&n(t.prototype,{get instanceRoot(){return i(o(this).instanceRoot)},get animatedInstanceRoot(){return i(o(this).animatedInstanceRoot)}}),r(a,t,u),e.wrappers.SVGUseElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.EventTarget,r=e.mixin,o=e.registerWrapper,i=e.unsafeUnwrap,a=e.wrap,s=window.SVGElementInstance;s&&(t.prototype=Object.create(n.prototype),r(t.prototype,{get correspondingElement(){return a(i(this).correspondingElement)},get correspondingUseElement(){return a(i(this).correspondingUseElement)},get parentNode(){return a(i(this).parentNode)},get childNodes(){throw new Error("Not implemented")},get firstChild(){return a(i(this).firstChild)},get lastChild(){return a(i(this).lastChild)},get previousSibling(){return a(i(this).previousSibling)},get nextSibling(){return a(i(this).nextSibling)}}),o(s,t),e.wrappers.SVGElementInstance=t)}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){o(e,this)}var n=e.mixin,r=e.registerWrapper,o=e.setWrapper,i=e.unsafeUnwrap,a=e.unwrap,s=e.unwrapIfNeeded,c=e.wrap,u=window.CanvasRenderingContext2D;n(t.prototype,{get canvas(){return c(i(this).canvas)},drawImage:function(){arguments[0]=s(arguments[0]),i(this).drawImage.apply(i(this),arguments)},createPattern:function(){return arguments[0]=a(arguments[0]),i(this).createPattern.apply(i(this),arguments)}}),r(u,t,document.createElement("canvas").getContext("2d")),e.wrappers.CanvasRenderingContext2D=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){o(e,this)}var n=e.mixin,r=e.registerWrapper,o=e.setWrapper,i=e.unsafeUnwrap,a=e.unwrapIfNeeded,s=e.wrap,c=window.WebGLRenderingContext;if(c){n(t.prototype,{get canvas(){return s(i(this).canvas)},texImage2D:function(){arguments[5]=a(arguments[5]),i(this).texImage2D.apply(i(this),arguments)},texSubImage2D:function(){arguments[6]=a(arguments[6]),i(this).texSubImage2D.apply(i(this),arguments)}});var u=/WebKit/.test(navigator.userAgent)?{drawingBufferHeight:null,drawingBufferWidth:null}:{};r(c,t,u),e.wrappers.WebGLRenderingContext=t}}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){r(e,this)}var n=e.registerWrapper,r=e.setWrapper,o=e.unsafeUnwrap,i=e.unwrap,a=e.unwrapIfNeeded,s=e.wrap,c=window.Range;t.prototype={get startContainer(){return s(o(this).startContainer)},get endContainer(){return s(o(this).endContainer)},get commonAncestorContainer(){return s(o(this).commonAncestorContainer)},setStart:function(e,t){o(this).setStart(a(e),t)},setEnd:function(e,t){o(this).setEnd(a(e),t)},setStartBefore:function(e){o(this).setStartBefore(a(e))},setStartAfter:function(e){o(this).setStartAfter(a(e))},setEndBefore:function(e){o(this).setEndBefore(a(e))},setEndAfter:function(e){o(this).setEndAfter(a(e))},selectNode:function(e){o(this).selectNode(a(e))},selectNodeContents:function(e){o(this).selectNodeContents(a(e))},compareBoundaryPoints:function(e,t){return o(this).compareBoundaryPoints(e,i(t))},extractContents:function(){return s(o(this).extractContents())},cloneContents:function(){return s(o(this).cloneContents())},insertNode:function(e){o(this).insertNode(a(e))},surroundContents:function(e){o(this).surroundContents(a(e))},cloneRange:function(){return s(o(this).cloneRange())},isPointInRange:function(e,t){return o(this).isPointInRange(a(e),t)},comparePoint:function(e,t){return o(this).comparePoint(a(e),t)},intersectsNode:function(e){return o(this).intersectsNode(a(e))},toString:function(){return o(this).toString()}},c.prototype.createContextualFragment&&(t.prototype.createContextualFragment=function(e){return s(o(this).createContextualFragment(e))}),n(window.Range,t,document.createRange()),e.wrappers.Range=t}(window.ShadowDOMPolyfill),function(e){"use strict";var t=e.GetElementsByInterface,n=e.ParentNodeInterface,r=e.SelectorsInterface,o=e.mixin,i=e.registerObject,a=i(document.createDocumentFragment());o(a.prototype,n),o(a.prototype,r),o(a.prototype,t);var s=i(document.createComment(""));e.wrappers.Comment=s,e.wrappers.DocumentFragment=a}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){var t=p(l(e).ownerDocument.createDocumentFragment());n.call(this,t),c(t,this);var o=e.shadowRoot;f.set(this,o),this.treeScope_=new r(this,a(o||e)),d.set(this,e)}var n=e.wrappers.DocumentFragment,r=e.TreeScope,o=e.elementFromPoint,i=e.getInnerHTML,a=e.getTreeScope,s=e.mixin,c=e.rewrap,u=e.setInnerHTML,l=e.unsafeUnwrap,p=e.unwrap,d=new WeakMap,f=new WeakMap,h=/[ \t\n\r\f]/;t.prototype=Object.create(n.prototype),s(t.prototype,{constructor:t,get innerHTML(){return i(this)},set innerHTML(e){u(this,e),this.invalidateShadowRenderer()},get olderShadowRoot(){return f.get(this)||null},get host(){return d.get(this)||null},invalidateShadowRenderer:function(){return d.get(this).invalidateShadowRenderer()},elementFromPoint:function(e,t){return o(this,this.ownerDocument,e,t)},getElementById:function(e){return h.test(e)?null:this.querySelector('[id="'+e+'"]')}}),e.wrappers.ShadowRoot=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){e.previousSibling_=e.previousSibling,e.nextSibling_=e.nextSibling,e.parentNode_=e.parentNode}function n(n,o,i){var a=x(n),s=x(o),c=i?x(i):null;if(r(o),t(o),i)n.firstChild===i&&(n.firstChild_=i),i.previousSibling_=i.previousSibling;else{n.lastChild_=n.lastChild,n.lastChild===n.firstChild&&(n.firstChild_=n.firstChild);var u=R(a.lastChild);u&&(u.nextSibling_=u.nextSibling)}e.originalInsertBefore.call(a,s,c)}function r(n){var r=x(n),o=r.parentNode;if(o){var i=R(o);t(n),n.previousSibling&&(n.previousSibling.nextSibling_=n),n.nextSibling&&(n.nextSibling.previousSibling_=n),i.lastChild===n&&(i.lastChild_=n),i.firstChild===n&&(i.firstChild_=n),e.originalRemoveChild.call(o,r)}}function o(e){W.set(e,[])}function i(e){var t=W.get(e);return t||W.set(e,t=[]),t}function a(e){for(var t=[],n=0,r=e.firstChild;r;r=r.nextSibling)t[n++]=r;return t}function s(){for(var e=0;ew;w++){var m=R(i[l++]);s.get(m)||r(m)}for(var g=f.addedCount,v=i[l]&&R(i[l]),w=0;g>w;w++){var b=o[u++],y=b.node;n(t,y,v),s.set(y,!0),b.sync(s)}p+=g}for(var d=p;d=0;o--){var i=r[o],a=w(i);if(a){var s=i.olderShadowRoot;s&&(n=h(s));for(var c=0;c=0;l--)u=Object.create(u);["createdCallback","attachedCallback","detachedCallback","attributeChangedCallback"].forEach(function(e){var t=o[e];t&&(u[e]=function(){N(this)instanceof r||T(this),t.apply(N(this),arguments)})});var p={prototype:u};i&&(p["extends"]=i),r.prototype=o,r.prototype.constructor=r,e.constructorTable.set(u,r),e.nativePrototypeTable.set(o,u);x.call(j(this),t,p);return r},b([window.HTMLDocument||window.Document],["registerElement"])}b([window.HTMLBodyElement,window.HTMLDocument||window.Document,window.HTMLHeadElement,window.HTMLHtmlElement],["appendChild","compareDocumentPosition","contains","getElementsByClassName","getElementsByTagName","getElementsByTagNameNS","insertBefore","querySelector","querySelectorAll","removeChild","replaceChild"]),b([window.HTMLBodyElement,window.HTMLHeadElement,window.HTMLHtmlElement],y),b([window.HTMLDocument||window.Document],["adoptNode","importNode","contains","createComment","createDocumentFragment","createElement","createElementNS","createEvent","createEventNS","createRange","createTextNode","elementFromPoint","getElementById","getElementsByName","getSelection"]),E(t.prototype,u),E(t.prototype,p),E(t.prototype,f),E(t.prototype,{get implementation(){var e=C.get(this);return e?e:(e=new a(j(this).implementation),C.set(this,e),e)},get defaultView(){return N(j(this).defaultView)}}),S(window.Document,t,document.implementation.createHTMLDocument("")),window.HTMLDocument&&S(window.HTMLDocument,t),_([window.HTMLBodyElement,window.HTMLDocument||window.Document,window.HTMLHeadElement]),s(a,"createDocumentType"),s(a,"createDocument"),s(a,"createHTMLDocument"),c(a,"hasFeature"),S(window.DOMImplementation,a),b([window.DOMImplementation],["createDocumentType","createDocument","createHTMLDocument","hasFeature"]),e.adoptNodeNoRemove=r,e.wrappers.DOMImplementation=a,e.wrappers.Document=t
-}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.EventTarget,r=e.wrappers.Selection,o=e.mixin,i=e.registerWrapper,a=e.renderAllPending,s=e.unwrap,c=e.unwrapIfNeeded,u=e.wrap,l=window.Window,p=window.getComputedStyle,d=window.getDefaultComputedStyle,f=window.getSelection;t.prototype=Object.create(n.prototype),l.prototype.getComputedStyle=function(e,t){return u(this||window).getComputedStyle(c(e),t)},d&&(l.prototype.getDefaultComputedStyle=function(e,t){return u(this||window).getDefaultComputedStyle(c(e),t)}),l.prototype.getSelection=function(){return u(this||window).getSelection()},delete window.getComputedStyle,delete window.getDefaultComputedStyle,delete window.getSelection,["addEventListener","removeEventListener","dispatchEvent"].forEach(function(e){l.prototype[e]=function(){var t=u(this||window);return t[e].apply(t,arguments)},delete window[e]}),o(t.prototype,{getComputedStyle:function(e,t){return a(),p.call(s(this),c(e),t)},getSelection:function(){return a(),new r(f.call(s(this)))},get document(){return u(s(this).document)}}),d&&(t.prototype.getDefaultComputedStyle=function(e,t){return a(),d.call(s(this),c(e),t)}),i(l,t,window),e.wrappers.Window=t}(window.ShadowDOMPolyfill),function(e){"use strict";var t=e.unwrap,n=window.DataTransfer||window.Clipboard,r=n.prototype.setDragImage;r&&(n.prototype.setDragImage=function(e,n,o){r.call(this,t(e),n,o)})}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){var t;t=e instanceof i?e:new i(e&&o(e)),r(t,this)}var n=e.registerWrapper,r=e.setWrapper,o=e.unwrap,i=window.FormData;i&&(n(i,t,new i),e.wrappers.FormData=t)}(window.ShadowDOMPolyfill),function(e){"use strict";var t=e.unwrapIfNeeded,n=XMLHttpRequest.prototype.send;XMLHttpRequest.prototype.send=function(e){return n.call(this,t(e))}}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){var t=n[e],r=window[t];if(r){var o=document.createElement(e),i=o.constructor;window[t]=i}}var n=(e.isWrapperFor,{a:"HTMLAnchorElement",area:"HTMLAreaElement",audio:"HTMLAudioElement",base:"HTMLBaseElement",body:"HTMLBodyElement",br:"HTMLBRElement",button:"HTMLButtonElement",canvas:"HTMLCanvasElement",caption:"HTMLTableCaptionElement",col:"HTMLTableColElement",content:"HTMLContentElement",data:"HTMLDataElement",datalist:"HTMLDataListElement",del:"HTMLModElement",dir:"HTMLDirectoryElement",div:"HTMLDivElement",dl:"HTMLDListElement",embed:"HTMLEmbedElement",fieldset:"HTMLFieldSetElement",font:"HTMLFontElement",form:"HTMLFormElement",frame:"HTMLFrameElement",frameset:"HTMLFrameSetElement",h1:"HTMLHeadingElement",head:"HTMLHeadElement",hr:"HTMLHRElement",html:"HTMLHtmlElement",iframe:"HTMLIFrameElement",img:"HTMLImageElement",input:"HTMLInputElement",keygen:"HTMLKeygenElement",label:"HTMLLabelElement",legend:"HTMLLegendElement",li:"HTMLLIElement",link:"HTMLLinkElement",map:"HTMLMapElement",marquee:"HTMLMarqueeElement",menu:"HTMLMenuElement",menuitem:"HTMLMenuItemElement",meta:"HTMLMetaElement",meter:"HTMLMeterElement",object:"HTMLObjectElement",ol:"HTMLOListElement",optgroup:"HTMLOptGroupElement",option:"HTMLOptionElement",output:"HTMLOutputElement",p:"HTMLParagraphElement",param:"HTMLParamElement",pre:"HTMLPreElement",progress:"HTMLProgressElement",q:"HTMLQuoteElement",script:"HTMLScriptElement",select:"HTMLSelectElement",shadow:"HTMLShadowElement",source:"HTMLSourceElement",span:"HTMLSpanElement",style:"HTMLStyleElement",table:"HTMLTableElement",tbody:"HTMLTableSectionElement",template:"HTMLTemplateElement",textarea:"HTMLTextAreaElement",thead:"HTMLTableSectionElement",time:"HTMLTimeElement",title:"HTMLTitleElement",tr:"HTMLTableRowElement",track:"HTMLTrackElement",ul:"HTMLUListElement",video:"HTMLVideoElement"});Object.keys(n).forEach(t),Object.getOwnPropertyNames(e.wrappers).forEach(function(t){window[t]=e.wrappers[t]})}(window.ShadowDOMPolyfill);
\ No newline at end of file
diff --git a/example/bower_components/webcomponentsjs/bower.json b/example/bower_components/webcomponentsjs/bower.json
deleted file mode 100644
index 4129deb3d..000000000
--- a/example/bower_components/webcomponentsjs/bower.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "name": "webcomponentsjs",
-  "main": "webcomponents.js",
-  "version": "0.5.5",
-  "homepage": "http://webcomponents.org",
-  "authors": [
-    "The Polymer Authors"
-  ],
-  "keywords": [
-    "webcomponents"
-  ],
-  "license": "BSD",
-  "ignore": []
-}
\ No newline at end of file
diff --git a/example/bower_components/webcomponentsjs/package.json b/example/bower_components/webcomponentsjs/package.json
deleted file mode 100644
index 52fdd0e78..000000000
--- a/example/bower_components/webcomponentsjs/package.json
+++ /dev/null
@@ -1,31 +0,0 @@
-{
-  "name": "webcomponents.js",
-  "version": "0.5.5",
-  "description": "webcomponents.js",
-  "main": "webcomponents.js",
-  "directories": {
-    "test": "tests"
-  },
-  "repository": {
-    "type": "git",
-    "url": "https://github.com/webcomponents/webcomponentsjs.git"
-  },
-  "author": "The Polymer Authors",
-  "license": {
-    "type": "BSD-3-Clause",
-    "url": "http://polymer.github.io/LICENSE.txt"
-  },
-  "bugs": {
-    "url": "https://github.com/webcomponents/webcomponentsjs/issues"
-  },
-  "homepage": "http://webcomponents.org",
-  "devDependencies": {
-    "gulp": "^3.8.8",
-    "gulp-audit": "^1.0.0",
-    "gulp-concat": "^2.4.1",
-    "gulp-header": "^1.1.1",
-    "gulp-uglify": "^1.0.1",
-    "run-sequence": "^1.0.1",
-    "web-component-tester": "*"
-  }
-}
diff --git a/example/bower_components/webcomponentsjs/webcomponents-lite.js b/example/bower_components/webcomponentsjs/webcomponents-lite.js
deleted file mode 100644
index a6e17b560..000000000
--- a/example/bower_components/webcomponentsjs/webcomponents-lite.js
+++ /dev/null
@@ -1,1728 +0,0 @@
-/**
- * @license
- * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
- * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
- * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
- * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
- * Code distributed by Google as part of the polymer project is also
- * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
- */
-// @version 0.5.5
-window.WebComponents = window.WebComponents || {};
-
-(function(scope) {
-  var flags = scope.flags || {};
-  var file = "webcomponents.js";
-  var script = document.querySelector('script[src*="' + file + '"]');
-  if (!flags.noOpts) {
-    location.search.slice(1).split("&").forEach(function(o) {
-      o = o.split("=");
-      o[0] && (flags[o[0]] = o[1] || true);
-    });
-    if (script) {
-      for (var i = 0, a; a = script.attributes[i]; i++) {
-        if (a.name !== "src") {
-          flags[a.name] = a.value || true;
-        }
-      }
-    }
-    if (flags.log) {
-      var parts = flags.log.split(",");
-      flags.log = {};
-      parts.forEach(function(f) {
-        flags.log[f] = true;
-      });
-    } else {
-      flags.log = {};
-    }
-  }
-  flags.shadow = flags.shadow || flags.shadowdom || flags.polyfill;
-  if (flags.shadow === "native") {
-    flags.shadow = false;
-  } else {
-    flags.shadow = flags.shadow || !HTMLElement.prototype.createShadowRoot;
-  }
-  if (flags.register) {
-    window.CustomElements = window.CustomElements || {
-      flags: {}
-    };
-    window.CustomElements.flags.register = flags.register;
-  }
-  scope.flags = flags;
-})(WebComponents);
-
-(function(global) {
-  var registrationsTable = new WeakMap();
-  var setImmediate;
-  if (/Trident|Edge/.test(navigator.userAgent)) {
-    setImmediate = setTimeout;
-  } else if (window.setImmediate) {
-    setImmediate = window.setImmediate;
-  } else {
-    var setImmediateQueue = [];
-    var sentinel = String(Math.random());
-    window.addEventListener("message", function(e) {
-      if (e.data === sentinel) {
-        var queue = setImmediateQueue;
-        setImmediateQueue = [];
-        queue.forEach(function(func) {
-          func();
-        });
-      }
-    });
-    setImmediate = function(func) {
-      setImmediateQueue.push(func);
-      window.postMessage(sentinel, "*");
-    };
-  }
-  var isScheduled = false;
-  var scheduledObservers = [];
-  function scheduleCallback(observer) {
-    scheduledObservers.push(observer);
-    if (!isScheduled) {
-      isScheduled = true;
-      setImmediate(dispatchCallbacks);
-    }
-  }
-  function wrapIfNeeded(node) {
-    return window.ShadowDOMPolyfill && window.ShadowDOMPolyfill.wrapIfNeeded(node) || node;
-  }
-  function dispatchCallbacks() {
-    isScheduled = false;
-    var observers = scheduledObservers;
-    scheduledObservers = [];
-    observers.sort(function(o1, o2) {
-      return o1.uid_ - o2.uid_;
-    });
-    var anyNonEmpty = false;
-    observers.forEach(function(observer) {
-      var queue = observer.takeRecords();
-      removeTransientObserversFor(observer);
-      if (queue.length) {
-        observer.callback_(queue, observer);
-        anyNonEmpty = true;
-      }
-    });
-    if (anyNonEmpty) dispatchCallbacks();
-  }
-  function removeTransientObserversFor(observer) {
-    observer.nodes_.forEach(function(node) {
-      var registrations = registrationsTable.get(node);
-      if (!registrations) return;
-      registrations.forEach(function(registration) {
-        if (registration.observer === observer) registration.removeTransientObservers();
-      });
-    });
-  }
-  function forEachAncestorAndObserverEnqueueRecord(target, callback) {
-    for (var node = target; node; node = node.parentNode) {
-      var registrations = registrationsTable.get(node);
-      if (registrations) {
-        for (var j = 0; j < registrations.length; j++) {
-          var registration = registrations[j];
-          var options = registration.options;
-          if (node !== target && !options.subtree) continue;
-          var record = callback(options);
-          if (record) registration.enqueue(record);
-        }
-      }
-    }
-  }
-  var uidCounter = 0;
-  function JsMutationObserver(callback) {
-    this.callback_ = callback;
-    this.nodes_ = [];
-    this.records_ = [];
-    this.uid_ = ++uidCounter;
-  }
-  JsMutationObserver.prototype = {
-    observe: function(target, options) {
-      target = wrapIfNeeded(target);
-      if (!options.childList && !options.attributes && !options.characterData || options.attributeOldValue && !options.attributes || options.attributeFilter && options.attributeFilter.length && !options.attributes || options.characterDataOldValue && !options.characterData) {
-        throw new SyntaxError();
-      }
-      var registrations = registrationsTable.get(target);
-      if (!registrations) registrationsTable.set(target, registrations = []);
-      var registration;
-      for (var i = 0; i < registrations.length; i++) {
-        if (registrations[i].observer === this) {
-          registration = registrations[i];
-          registration.removeListeners();
-          registration.options = options;
-          break;
-        }
-      }
-      if (!registration) {
-        registration = new Registration(this, target, options);
-        registrations.push(registration);
-        this.nodes_.push(target);
-      }
-      registration.addListeners();
-    },
-    disconnect: function() {
-      this.nodes_.forEach(function(node) {
-        var registrations = registrationsTable.get(node);
-        for (var i = 0; i < registrations.length; i++) {
-          var registration = registrations[i];
-          if (registration.observer === this) {
-            registration.removeListeners();
-            registrations.splice(i, 1);
-            break;
-          }
-        }
-      }, this);
-      this.records_ = [];
-    },
-    takeRecords: function() {
-      var copyOfRecords = this.records_;
-      this.records_ = [];
-      return copyOfRecords;
-    }
-  };
-  function MutationRecord(type, target) {
-    this.type = type;
-    this.target = target;
-    this.addedNodes = [];
-    this.removedNodes = [];
-    this.previousSibling = null;
-    this.nextSibling = null;
-    this.attributeName = null;
-    this.attributeNamespace = null;
-    this.oldValue = null;
-  }
-  function copyMutationRecord(original) {
-    var record = new MutationRecord(original.type, original.target);
-    record.addedNodes = original.addedNodes.slice();
-    record.removedNodes = original.removedNodes.slice();
-    record.previousSibling = original.previousSibling;
-    record.nextSibling = original.nextSibling;
-    record.attributeName = original.attributeName;
-    record.attributeNamespace = original.attributeNamespace;
-    record.oldValue = original.oldValue;
-    return record;
-  }
-  var currentRecord, recordWithOldValue;
-  function getRecord(type, target) {
-    return currentRecord = new MutationRecord(type, target);
-  }
-  function getRecordWithOldValue(oldValue) {
-    if (recordWithOldValue) return recordWithOldValue;
-    recordWithOldValue = copyMutationRecord(currentRecord);
-    recordWithOldValue.oldValue = oldValue;
-    return recordWithOldValue;
-  }
-  function clearRecords() {
-    currentRecord = recordWithOldValue = undefined;
-  }
-  function recordRepresentsCurrentMutation(record) {
-    return record === recordWithOldValue || record === currentRecord;
-  }
-  function selectRecord(lastRecord, newRecord) {
-    if (lastRecord === newRecord) return lastRecord;
-    if (recordWithOldValue && recordRepresentsCurrentMutation(lastRecord)) return recordWithOldValue;
-    return null;
-  }
-  function Registration(observer, target, options) {
-    this.observer = observer;
-    this.target = target;
-    this.options = options;
-    this.transientObservedNodes = [];
-  }
-  Registration.prototype = {
-    enqueue: function(record) {
-      var records = this.observer.records_;
-      var length = records.length;
-      if (records.length > 0) {
-        var lastRecord = records[length - 1];
-        var recordToReplaceLast = selectRecord(lastRecord, record);
-        if (recordToReplaceLast) {
-          records[length - 1] = recordToReplaceLast;
-          return;
-        }
-      } else {
-        scheduleCallback(this.observer);
-      }
-      records[length] = record;
-    },
-    addListeners: function() {
-      this.addListeners_(this.target);
-    },
-    addListeners_: function(node) {
-      var options = this.options;
-      if (options.attributes) node.addEventListener("DOMAttrModified", this, true);
-      if (options.characterData) node.addEventListener("DOMCharacterDataModified", this, true);
-      if (options.childList) node.addEventListener("DOMNodeInserted", this, true);
-      if (options.childList || options.subtree) node.addEventListener("DOMNodeRemoved", this, true);
-    },
-    removeListeners: function() {
-      this.removeListeners_(this.target);
-    },
-    removeListeners_: function(node) {
-      var options = this.options;
-      if (options.attributes) node.removeEventListener("DOMAttrModified", this, true);
-      if (options.characterData) node.removeEventListener("DOMCharacterDataModified", this, true);
-      if (options.childList) node.removeEventListener("DOMNodeInserted", this, true);
-      if (options.childList || options.subtree) node.removeEventListener("DOMNodeRemoved", this, true);
-    },
-    addTransientObserver: function(node) {
-      if (node === this.target) return;
-      this.addListeners_(node);
-      this.transientObservedNodes.push(node);
-      var registrations = registrationsTable.get(node);
-      if (!registrations) registrationsTable.set(node, registrations = []);
-      registrations.push(this);
-    },
-    removeTransientObservers: function() {
-      var transientObservedNodes = this.transientObservedNodes;
-      this.transientObservedNodes = [];
-      transientObservedNodes.forEach(function(node) {
-        this.removeListeners_(node);
-        var registrations = registrationsTable.get(node);
-        for (var i = 0; i < registrations.length; i++) {
-          if (registrations[i] === this) {
-            registrations.splice(i, 1);
-            break;
-          }
-        }
-      }, this);
-    },
-    handleEvent: function(e) {
-      e.stopImmediatePropagation();
-      switch (e.type) {
-       case "DOMAttrModified":
-        var name = e.attrName;
-        var namespace = e.relatedNode.namespaceURI;
-        var target = e.target;
-        var record = new getRecord("attributes", target);
-        record.attributeName = name;
-        record.attributeNamespace = namespace;
-        var oldValue = e.attrChange === MutationEvent.ADDITION ? null : e.prevValue;
-        forEachAncestorAndObserverEnqueueRecord(target, function(options) {
-          if (!options.attributes) return;
-          if (options.attributeFilter && options.attributeFilter.length && options.attributeFilter.indexOf(name) === -1 && options.attributeFilter.indexOf(namespace) === -1) {
-            return;
-          }
-          if (options.attributeOldValue) return getRecordWithOldValue(oldValue);
-          return record;
-        });
-        break;
-
-       case "DOMCharacterDataModified":
-        var target = e.target;
-        var record = getRecord("characterData", target);
-        var oldValue = e.prevValue;
-        forEachAncestorAndObserverEnqueueRecord(target, function(options) {
-          if (!options.characterData) return;
-          if (options.characterDataOldValue) return getRecordWithOldValue(oldValue);
-          return record;
-        });
-        break;
-
-       case "DOMNodeRemoved":
-        this.addTransientObserver(e.target);
-
-       case "DOMNodeInserted":
-        var changedNode = e.target;
-        var addedNodes, removedNodes;
-        if (e.type === "DOMNodeInserted") {
-          addedNodes = [ changedNode ];
-          removedNodes = [];
-        } else {
-          addedNodes = [];
-          removedNodes = [ changedNode ];
-        }
-        var previousSibling = changedNode.previousSibling;
-        var nextSibling = changedNode.nextSibling;
-        var record = getRecord("childList", e.target.parentNode);
-        record.addedNodes = addedNodes;
-        record.removedNodes = removedNodes;
-        record.previousSibling = previousSibling;
-        record.nextSibling = nextSibling;
-        forEachAncestorAndObserverEnqueueRecord(e.relatedNode, function(options) {
-          if (!options.childList) return;
-          return record;
-        });
-      }
-      clearRecords();
-    }
-  };
-  global.JsMutationObserver = JsMutationObserver;
-  if (!global.MutationObserver) global.MutationObserver = JsMutationObserver;
-})(this);
-
-if (typeof WeakMap === "undefined") {
-  (function() {
-    var defineProperty = Object.defineProperty;
-    var counter = Date.now() % 1e9;
-    var WeakMap = function() {
-      this.name = "__st" + (Math.random() * 1e9 >>> 0) + (counter++ + "__");
-    };
-    WeakMap.prototype = {
-      set: function(key, value) {
-        var entry = key[this.name];
-        if (entry && entry[0] === key) entry[1] = value; else defineProperty(key, this.name, {
-          value: [ key, value ],
-          writable: true
-        });
-        return this;
-      },
-      get: function(key) {
-        var entry;
-        return (entry = key[this.name]) && entry[0] === key ? entry[1] : undefined;
-      },
-      "delete": function(key) {
-        var entry = key[this.name];
-        if (!entry || entry[0] !== key) return false;
-        entry[0] = entry[1] = undefined;
-        return true;
-      },
-      has: function(key) {
-        var entry = key[this.name];
-        if (!entry) return false;
-        return entry[0] === key;
-      }
-    };
-    window.WeakMap = WeakMap;
-  })();
-}
-
-window.HTMLImports = window.HTMLImports || {
-  flags: {}
-};
-
-(function(scope) {
-  var IMPORT_LINK_TYPE = "import";
-  var useNative = Boolean(IMPORT_LINK_TYPE in document.createElement("link"));
-  var hasShadowDOMPolyfill = Boolean(window.ShadowDOMPolyfill);
-  var wrap = function(node) {
-    return hasShadowDOMPolyfill ? ShadowDOMPolyfill.wrapIfNeeded(node) : node;
-  };
-  var rootDocument = wrap(document);
-  var currentScriptDescriptor = {
-    get: function() {
-      var script = HTMLImports.currentScript || document.currentScript || (document.readyState !== "complete" ? document.scripts[document.scripts.length - 1] : null);
-      return wrap(script);
-    },
-    configurable: true
-  };
-  Object.defineProperty(document, "_currentScript", currentScriptDescriptor);
-  Object.defineProperty(rootDocument, "_currentScript", currentScriptDescriptor);
-  var isIE = /Trident|Edge/.test(navigator.userAgent);
-  function whenReady(callback, doc) {
-    doc = doc || rootDocument;
-    whenDocumentReady(function() {
-      watchImportsLoad(callback, doc);
-    }, doc);
-  }
-  var requiredReadyState = isIE ? "complete" : "interactive";
-  var READY_EVENT = "readystatechange";
-  function isDocumentReady(doc) {
-    return doc.readyState === "complete" || doc.readyState === requiredReadyState;
-  }
-  function whenDocumentReady(callback, doc) {
-    if (!isDocumentReady(doc)) {
-      var checkReady = function() {
-        if (doc.readyState === "complete" || doc.readyState === requiredReadyState) {
-          doc.removeEventListener(READY_EVENT, checkReady);
-          whenDocumentReady(callback, doc);
-        }
-      };
-      doc.addEventListener(READY_EVENT, checkReady);
-    } else if (callback) {
-      callback();
-    }
-  }
-  function markTargetLoaded(event) {
-    event.target.__loaded = true;
-  }
-  function watchImportsLoad(callback, doc) {
-    var imports = doc.querySelectorAll("link[rel=import]");
-    var loaded = 0, l = imports.length;
-    function checkDone(d) {
-      if (loaded == l && callback) {
-        callback();
-      }
-    }
-    function loadedImport(e) {
-      markTargetLoaded(e);
-      loaded++;
-      checkDone();
-    }
-    if (l) {
-      for (var i = 0, imp; i < l && (imp = imports[i]); i++) {
-        if (isImportLoaded(imp)) {
-          loadedImport.call(imp, {
-            target: imp
-          });
-        } else {
-          imp.addEventListener("load", loadedImport);
-          imp.addEventListener("error", loadedImport);
-        }
-      }
-    } else {
-      checkDone();
-    }
-  }
-  function isImportLoaded(link) {
-    return useNative ? link.__loaded || link.import && link.import.readyState !== "loading" : link.__importParsed;
-  }
-  if (useNative) {
-    new MutationObserver(function(mxns) {
-      for (var i = 0, l = mxns.length, m; i < l && (m = mxns[i]); i++) {
-        if (m.addedNodes) {
-          handleImports(m.addedNodes);
-        }
-      }
-    }).observe(document.head, {
-      childList: true
-    });
-    function handleImports(nodes) {
-      for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {
-        if (isImport(n)) {
-          handleImport(n);
-        }
-      }
-    }
-    function isImport(element) {
-      return element.localName === "link" && element.rel === "import";
-    }
-    function handleImport(element) {
-      var loaded = element.import;
-      if (loaded) {
-        markTargetLoaded({
-          target: element
-        });
-      } else {
-        element.addEventListener("load", markTargetLoaded);
-        element.addEventListener("error", markTargetLoaded);
-      }
-    }
-    (function() {
-      if (document.readyState === "loading") {
-        var imports = document.querySelectorAll("link[rel=import]");
-        for (var i = 0, l = imports.length, imp; i < l && (imp = imports[i]); i++) {
-          handleImport(imp);
-        }
-      }
-    })();
-  }
-  whenReady(function() {
-    HTMLImports.ready = true;
-    HTMLImports.readyTime = new Date().getTime();
-    var evt = rootDocument.createEvent("CustomEvent");
-    evt.initCustomEvent("HTMLImportsLoaded", true, true, {});
-    rootDocument.dispatchEvent(evt);
-  });
-  scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;
-  scope.useNative = useNative;
-  scope.rootDocument = rootDocument;
-  scope.whenReady = whenReady;
-  scope.isIE = isIE;
-})(HTMLImports);
-
-(function(scope) {
-  var modules = [];
-  var addModule = function(module) {
-    modules.push(module);
-  };
-  var initializeModules = function() {
-    modules.forEach(function(module) {
-      module(scope);
-    });
-  };
-  scope.addModule = addModule;
-  scope.initializeModules = initializeModules;
-})(HTMLImports);
-
-HTMLImports.addModule(function(scope) {
-  var CSS_URL_REGEXP = /(url\()([^)]*)(\))/g;
-  var CSS_IMPORT_REGEXP = /(@import[\s]+(?!url\())([^;]*)(;)/g;
-  var path = {
-    resolveUrlsInStyle: function(style) {
-      var doc = style.ownerDocument;
-      var resolver = doc.createElement("a");
-      style.textContent = this.resolveUrlsInCssText(style.textContent, resolver);
-      return style;
-    },
-    resolveUrlsInCssText: function(cssText, urlObj) {
-      var r = this.replaceUrls(cssText, urlObj, CSS_URL_REGEXP);
-      r = this.replaceUrls(r, urlObj, CSS_IMPORT_REGEXP);
-      return r;
-    },
-    replaceUrls: function(text, urlObj, regexp) {
-      return text.replace(regexp, function(m, pre, url, post) {
-        var urlPath = url.replace(/["']/g, "");
-        urlObj.href = urlPath;
-        urlPath = urlObj.href;
-        return pre + "'" + urlPath + "'" + post;
-      });
-    }
-  };
-  scope.path = path;
-});
-
-HTMLImports.addModule(function(scope) {
-  var xhr = {
-    async: true,
-    ok: function(request) {
-      return request.status >= 200 && request.status < 300 || request.status === 304 || request.status === 0;
-    },
-    load: function(url, next, nextContext) {
-      var request = new XMLHttpRequest();
-      if (scope.flags.debug || scope.flags.bust) {
-        url += "?" + Math.random();
-      }
-      request.open("GET", url, xhr.async);
-      request.addEventListener("readystatechange", function(e) {
-        if (request.readyState === 4) {
-          var locationHeader = request.getResponseHeader("Location");
-          var redirectedUrl = null;
-          if (locationHeader) {
-            var redirectedUrl = locationHeader.substr(0, 1) === "/" ? location.origin + locationHeader : locationHeader;
-          }
-          next.call(nextContext, !xhr.ok(request) && request, request.response || request.responseText, redirectedUrl);
-        }
-      });
-      request.send();
-      return request;
-    },
-    loadDocument: function(url, next, nextContext) {
-      this.load(url, next, nextContext).responseType = "document";
-    }
-  };
-  scope.xhr = xhr;
-});
-
-HTMLImports.addModule(function(scope) {
-  var xhr = scope.xhr;
-  var flags = scope.flags;
-  var Loader = function(onLoad, onComplete) {
-    this.cache = {};
-    this.onload = onLoad;
-    this.oncomplete = onComplete;
-    this.inflight = 0;
-    this.pending = {};
-  };
-  Loader.prototype = {
-    addNodes: function(nodes) {
-      this.inflight += nodes.length;
-      for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {
-        this.require(n);
-      }
-      this.checkDone();
-    },
-    addNode: function(node) {
-      this.inflight++;
-      this.require(node);
-      this.checkDone();
-    },
-    require: function(elt) {
-      var url = elt.src || elt.href;
-      elt.__nodeUrl = url;
-      if (!this.dedupe(url, elt)) {
-        this.fetch(url, elt);
-      }
-    },
-    dedupe: function(url, elt) {
-      if (this.pending[url]) {
-        this.pending[url].push(elt);
-        return true;
-      }
-      var resource;
-      if (this.cache[url]) {
-        this.onload(url, elt, this.cache[url]);
-        this.tail();
-        return true;
-      }
-      this.pending[url] = [ elt ];
-      return false;
-    },
-    fetch: function(url, elt) {
-      flags.load && console.log("fetch", url, elt);
-      if (!url) {
-        setTimeout(function() {
-          this.receive(url, elt, {
-            error: "href must be specified"
-          }, null);
-        }.bind(this), 0);
-      } else if (url.match(/^data:/)) {
-        var pieces = url.split(",");
-        var header = pieces[0];
-        var body = pieces[1];
-        if (header.indexOf(";base64") > -1) {
-          body = atob(body);
-        } else {
-          body = decodeURIComponent(body);
-        }
-        setTimeout(function() {
-          this.receive(url, elt, null, body);
-        }.bind(this), 0);
-      } else {
-        var receiveXhr = function(err, resource, redirectedUrl) {
-          this.receive(url, elt, err, resource, redirectedUrl);
-        }.bind(this);
-        xhr.load(url, receiveXhr);
-      }
-    },
-    receive: function(url, elt, err, resource, redirectedUrl) {
-      this.cache[url] = resource;
-      var $p = this.pending[url];
-      for (var i = 0, l = $p.length, p; i < l && (p = $p[i]); i++) {
-        this.onload(url, p, resource, err, redirectedUrl);
-        this.tail();
-      }
-      this.pending[url] = null;
-    },
-    tail: function() {
-      --this.inflight;
-      this.checkDone();
-    },
-    checkDone: function() {
-      if (!this.inflight) {
-        this.oncomplete();
-      }
-    }
-  };
-  scope.Loader = Loader;
-});
-
-HTMLImports.addModule(function(scope) {
-  var Observer = function(addCallback) {
-    this.addCallback = addCallback;
-    this.mo = new MutationObserver(this.handler.bind(this));
-  };
-  Observer.prototype = {
-    handler: function(mutations) {
-      for (var i = 0, l = mutations.length, m; i < l && (m = mutations[i]); i++) {
-        if (m.type === "childList" && m.addedNodes.length) {
-          this.addedNodes(m.addedNodes);
-        }
-      }
-    },
-    addedNodes: function(nodes) {
-      if (this.addCallback) {
-        this.addCallback(nodes);
-      }
-      for (var i = 0, l = nodes.length, n, loading; i < l && (n = nodes[i]); i++) {
-        if (n.children && n.children.length) {
-          this.addedNodes(n.children);
-        }
-      }
-    },
-    observe: function(root) {
-      this.mo.observe(root, {
-        childList: true,
-        subtree: true
-      });
-    }
-  };
-  scope.Observer = Observer;
-});
-
-HTMLImports.addModule(function(scope) {
-  var path = scope.path;
-  var rootDocument = scope.rootDocument;
-  var flags = scope.flags;
-  var isIE = scope.isIE;
-  var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;
-  var IMPORT_SELECTOR = "link[rel=" + IMPORT_LINK_TYPE + "]";
-  var importParser = {
-    documentSelectors: IMPORT_SELECTOR,
-    importsSelectors: [ IMPORT_SELECTOR, "link[rel=stylesheet]", "style", "script:not([type])", 'script[type="text/javascript"]' ].join(","),
-    map: {
-      link: "parseLink",
-      script: "parseScript",
-      style: "parseStyle"
-    },
-    dynamicElements: [],
-    parseNext: function() {
-      var next = this.nextToParse();
-      if (next) {
-        this.parse(next);
-      }
-    },
-    parse: function(elt) {
-      if (this.isParsed(elt)) {
-        flags.parse && console.log("[%s] is already parsed", elt.localName);
-        return;
-      }
-      var fn = this[this.map[elt.localName]];
-      if (fn) {
-        this.markParsing(elt);
-        fn.call(this, elt);
-      }
-    },
-    parseDynamic: function(elt, quiet) {
-      this.dynamicElements.push(elt);
-      if (!quiet) {
-        this.parseNext();
-      }
-    },
-    markParsing: function(elt) {
-      flags.parse && console.log("parsing", elt);
-      this.parsingElement = elt;
-    },
-    markParsingComplete: function(elt) {
-      elt.__importParsed = true;
-      this.markDynamicParsingComplete(elt);
-      if (elt.__importElement) {
-        elt.__importElement.__importParsed = true;
-        this.markDynamicParsingComplete(elt.__importElement);
-      }
-      this.parsingElement = null;
-      flags.parse && console.log("completed", elt);
-    },
-    markDynamicParsingComplete: function(elt) {
-      var i = this.dynamicElements.indexOf(elt);
-      if (i >= 0) {
-        this.dynamicElements.splice(i, 1);
-      }
-    },
-    parseImport: function(elt) {
-      if (HTMLImports.__importsParsingHook) {
-        HTMLImports.__importsParsingHook(elt);
-      }
-      if (elt.import) {
-        elt.import.__importParsed = true;
-      }
-      this.markParsingComplete(elt);
-      if (elt.__resource && !elt.__error) {
-        elt.dispatchEvent(new CustomEvent("load", {
-          bubbles: false
-        }));
-      } else {
-        elt.dispatchEvent(new CustomEvent("error", {
-          bubbles: false
-        }));
-      }
-      if (elt.__pending) {
-        var fn;
-        while (elt.__pending.length) {
-          fn = elt.__pending.shift();
-          if (fn) {
-            fn({
-              target: elt
-            });
-          }
-        }
-      }
-      this.parseNext();
-    },
-    parseLink: function(linkElt) {
-      if (nodeIsImport(linkElt)) {
-        this.parseImport(linkElt);
-      } else {
-        linkElt.href = linkElt.href;
-        this.parseGeneric(linkElt);
-      }
-    },
-    parseStyle: function(elt) {
-      var src = elt;
-      elt = cloneStyle(elt);
-      elt.__importElement = src;
-      this.parseGeneric(elt);
-    },
-    parseGeneric: function(elt) {
-      this.trackElement(elt);
-      this.addElementToDocument(elt);
-    },
-    rootImportForElement: function(elt) {
-      var n = elt;
-      while (n.ownerDocument.__importLink) {
-        n = n.ownerDocument.__importLink;
-      }
-      return n;
-    },
-    addElementToDocument: function(elt) {
-      var port = this.rootImportForElement(elt.__importElement || elt);
-      port.parentNode.insertBefore(elt, port);
-    },
-    trackElement: function(elt, callback) {
-      var self = this;
-      var done = function(e) {
-        if (callback) {
-          callback(e);
-        }
-        self.markParsingComplete(elt);
-        self.parseNext();
-      };
-      elt.addEventListener("load", done);
-      elt.addEventListener("error", done);
-      if (isIE && elt.localName === "style") {
-        var fakeLoad = false;
-        if (elt.textContent.indexOf("@import") == -1) {
-          fakeLoad = true;
-        } else if (elt.sheet) {
-          fakeLoad = true;
-          var csr = elt.sheet.cssRules;
-          var len = csr ? csr.length : 0;
-          for (var i = 0, r; i < len && (r = csr[i]); i++) {
-            if (r.type === CSSRule.IMPORT_RULE) {
-              fakeLoad = fakeLoad && Boolean(r.styleSheet);
-            }
-          }
-        }
-        if (fakeLoad) {
-          elt.dispatchEvent(new CustomEvent("load", {
-            bubbles: false
-          }));
-        }
-      }
-    },
-    parseScript: function(scriptElt) {
-      var script = document.createElement("script");
-      script.__importElement = scriptElt;
-      script.src = scriptElt.src ? scriptElt.src : generateScriptDataUrl(scriptElt);
-      scope.currentScript = scriptElt;
-      this.trackElement(script, function(e) {
-        script.parentNode.removeChild(script);
-        scope.currentScript = null;
-      });
-      this.addElementToDocument(script);
-    },
-    nextToParse: function() {
-      this._mayParse = [];
-      return !this.parsingElement && (this.nextToParseInDoc(rootDocument) || this.nextToParseDynamic());
-    },
-    nextToParseInDoc: function(doc, link) {
-      if (doc && this._mayParse.indexOf(doc) < 0) {
-        this._mayParse.push(doc);
-        var nodes = doc.querySelectorAll(this.parseSelectorsForNode(doc));
-        for (var i = 0, l = nodes.length, p = 0, n; i < l && (n = nodes[i]); i++) {
-          if (!this.isParsed(n)) {
-            if (this.hasResource(n)) {
-              return nodeIsImport(n) ? this.nextToParseInDoc(n.import, n) : n;
-            } else {
-              return;
-            }
-          }
-        }
-      }
-      return link;
-    },
-    nextToParseDynamic: function() {
-      return this.dynamicElements[0];
-    },
-    parseSelectorsForNode: function(node) {
-      var doc = node.ownerDocument || node;
-      return doc === rootDocument ? this.documentSelectors : this.importsSelectors;
-    },
-    isParsed: function(node) {
-      return node.__importParsed;
-    },
-    needsDynamicParsing: function(elt) {
-      return this.dynamicElements.indexOf(elt) >= 0;
-    },
-    hasResource: function(node) {
-      if (nodeIsImport(node) && node.import === undefined) {
-        return false;
-      }
-      return true;
-    }
-  };
-  function nodeIsImport(elt) {
-    return elt.localName === "link" && elt.rel === IMPORT_LINK_TYPE;
-  }
-  function generateScriptDataUrl(script) {
-    var scriptContent = generateScriptContent(script);
-    return "data:text/javascript;charset=utf-8," + encodeURIComponent(scriptContent);
-  }
-  function generateScriptContent(script) {
-    return script.textContent + generateSourceMapHint(script);
-  }
-  function generateSourceMapHint(script) {
-    var owner = script.ownerDocument;
-    owner.__importedScripts = owner.__importedScripts || 0;
-    var moniker = script.ownerDocument.baseURI;
-    var num = owner.__importedScripts ? "-" + owner.__importedScripts : "";
-    owner.__importedScripts++;
-    return "\n//# sourceURL=" + moniker + num + ".js\n";
-  }
-  function cloneStyle(style) {
-    var clone = style.ownerDocument.createElement("style");
-    clone.textContent = style.textContent;
-    path.resolveUrlsInStyle(clone);
-    return clone;
-  }
-  scope.parser = importParser;
-  scope.IMPORT_SELECTOR = IMPORT_SELECTOR;
-});
-
-HTMLImports.addModule(function(scope) {
-  var flags = scope.flags;
-  var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;
-  var IMPORT_SELECTOR = scope.IMPORT_SELECTOR;
-  var rootDocument = scope.rootDocument;
-  var Loader = scope.Loader;
-  var Observer = scope.Observer;
-  var parser = scope.parser;
-  var importer = {
-    documents: {},
-    documentPreloadSelectors: IMPORT_SELECTOR,
-    importsPreloadSelectors: [ IMPORT_SELECTOR ].join(","),
-    loadNode: function(node) {
-      importLoader.addNode(node);
-    },
-    loadSubtree: function(parent) {
-      var nodes = this.marshalNodes(parent);
-      importLoader.addNodes(nodes);
-    },
-    marshalNodes: function(parent) {
-      return parent.querySelectorAll(this.loadSelectorsForNode(parent));
-    },
-    loadSelectorsForNode: function(node) {
-      var doc = node.ownerDocument || node;
-      return doc === rootDocument ? this.documentPreloadSelectors : this.importsPreloadSelectors;
-    },
-    loaded: function(url, elt, resource, err, redirectedUrl) {
-      flags.load && console.log("loaded", url, elt);
-      elt.__resource = resource;
-      elt.__error = err;
-      if (isImportLink(elt)) {
-        var doc = this.documents[url];
-        if (doc === undefined) {
-          doc = err ? null : makeDocument(resource, redirectedUrl || url);
-          if (doc) {
-            doc.__importLink = elt;
-            this.bootDocument(doc);
-          }
-          this.documents[url] = doc;
-        }
-        elt.import = doc;
-      }
-      parser.parseNext();
-    },
-    bootDocument: function(doc) {
-      this.loadSubtree(doc);
-      this.observer.observe(doc);
-      parser.parseNext();
-    },
-    loadedAll: function() {
-      parser.parseNext();
-    }
-  };
-  var importLoader = new Loader(importer.loaded.bind(importer), importer.loadedAll.bind(importer));
-  importer.observer = new Observer();
-  function isImportLink(elt) {
-    return isLinkRel(elt, IMPORT_LINK_TYPE);
-  }
-  function isLinkRel(elt, rel) {
-    return elt.localName === "link" && elt.getAttribute("rel") === rel;
-  }
-  function hasBaseURIAccessor(doc) {
-    return !!Object.getOwnPropertyDescriptor(doc, "baseURI");
-  }
-  function makeDocument(resource, url) {
-    var doc = document.implementation.createHTMLDocument(IMPORT_LINK_TYPE);
-    doc._URL = url;
-    var base = doc.createElement("base");
-    base.setAttribute("href", url);
-    if (!doc.baseURI && !hasBaseURIAccessor(doc)) {
-      Object.defineProperty(doc, "baseURI", {
-        value: url
-      });
-    }
-    var meta = doc.createElement("meta");
-    meta.setAttribute("charset", "utf-8");
-    doc.head.appendChild(meta);
-    doc.head.appendChild(base);
-    doc.body.innerHTML = resource;
-    if (window.HTMLTemplateElement && HTMLTemplateElement.bootstrap) {
-      HTMLTemplateElement.bootstrap(doc);
-    }
-    return doc;
-  }
-  if (!document.baseURI) {
-    var baseURIDescriptor = {
-      get: function() {
-        var base = document.querySelector("base");
-        return base ? base.href : window.location.href;
-      },
-      configurable: true
-    };
-    Object.defineProperty(document, "baseURI", baseURIDescriptor);
-    Object.defineProperty(rootDocument, "baseURI", baseURIDescriptor);
-  }
-  scope.importer = importer;
-  scope.importLoader = importLoader;
-});
-
-HTMLImports.addModule(function(scope) {
-  var parser = scope.parser;
-  var importer = scope.importer;
-  var dynamic = {
-    added: function(nodes) {
-      var owner, parsed, loading;
-      for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {
-        if (!owner) {
-          owner = n.ownerDocument;
-          parsed = parser.isParsed(owner);
-        }
-        loading = this.shouldLoadNode(n);
-        if (loading) {
-          importer.loadNode(n);
-        }
-        if (this.shouldParseNode(n) && parsed) {
-          parser.parseDynamic(n, loading);
-        }
-      }
-    },
-    shouldLoadNode: function(node) {
-      return node.nodeType === 1 && matches.call(node, importer.loadSelectorsForNode(node));
-    },
-    shouldParseNode: function(node) {
-      return node.nodeType === 1 && matches.call(node, parser.parseSelectorsForNode(node));
-    }
-  };
-  importer.observer.addCallback = dynamic.added.bind(dynamic);
-  var matches = HTMLElement.prototype.matches || HTMLElement.prototype.matchesSelector || HTMLElement.prototype.webkitMatchesSelector || HTMLElement.prototype.mozMatchesSelector || HTMLElement.prototype.msMatchesSelector;
-});
-
-(function(scope) {
-  var initializeModules = scope.initializeModules;
-  var isIE = scope.isIE;
-  if (scope.useNative) {
-    return;
-  }
-  if (isIE && typeof window.CustomEvent !== "function") {
-    window.CustomEvent = function(inType, params) {
-      params = params || {};
-      var e = document.createEvent("CustomEvent");
-      e.initCustomEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable), params.detail);
-      return e;
-    };
-    window.CustomEvent.prototype = window.Event.prototype;
-  }
-  initializeModules();
-  var rootDocument = scope.rootDocument;
-  function bootstrap() {
-    HTMLImports.importer.bootDocument(rootDocument);
-  }
-  if (document.readyState === "complete" || document.readyState === "interactive" && !window.attachEvent) {
-    bootstrap();
-  } else {
-    document.addEventListener("DOMContentLoaded", bootstrap);
-  }
-})(HTMLImports);
-
-window.CustomElements = window.CustomElements || {
-  flags: {}
-};
-
-(function(scope) {
-  var flags = scope.flags;
-  var modules = [];
-  var addModule = function(module) {
-    modules.push(module);
-  };
-  var initializeModules = function() {
-    modules.forEach(function(module) {
-      module(scope);
-    });
-  };
-  scope.addModule = addModule;
-  scope.initializeModules = initializeModules;
-  scope.hasNative = Boolean(document.registerElement);
-  scope.useNative = !flags.register && scope.hasNative && !window.ShadowDOMPolyfill && (!window.HTMLImports || HTMLImports.useNative);
-})(CustomElements);
-
-CustomElements.addModule(function(scope) {
-  var IMPORT_LINK_TYPE = window.HTMLImports ? HTMLImports.IMPORT_LINK_TYPE : "none";
-  function forSubtree(node, cb) {
-    findAllElements(node, function(e) {
-      if (cb(e)) {
-        return true;
-      }
-      forRoots(e, cb);
-    });
-    forRoots(node, cb);
-  }
-  function findAllElements(node, find, data) {
-    var e = node.firstElementChild;
-    if (!e) {
-      e = node.firstChild;
-      while (e && e.nodeType !== Node.ELEMENT_NODE) {
-        e = e.nextSibling;
-      }
-    }
-    while (e) {
-      if (find(e, data) !== true) {
-        findAllElements(e, find, data);
-      }
-      e = e.nextElementSibling;
-    }
-    return null;
-  }
-  function forRoots(node, cb) {
-    var root = node.shadowRoot;
-    while (root) {
-      forSubtree(root, cb);
-      root = root.olderShadowRoot;
-    }
-  }
-  var processingDocuments;
-  function forDocumentTree(doc, cb) {
-    processingDocuments = [];
-    _forDocumentTree(doc, cb);
-    processingDocuments = null;
-  }
-  function _forDocumentTree(doc, cb) {
-    doc = wrap(doc);
-    if (processingDocuments.indexOf(doc) >= 0) {
-      return;
-    }
-    processingDocuments.push(doc);
-    var imports = doc.querySelectorAll("link[rel=" + IMPORT_LINK_TYPE + "]");
-    for (var i = 0, l = imports.length, n; i < l && (n = imports[i]); i++) {
-      if (n.import) {
-        _forDocumentTree(n.import, cb);
-      }
-    }
-    cb(doc);
-  }
-  scope.forDocumentTree = forDocumentTree;
-  scope.forSubtree = forSubtree;
-});
-
-CustomElements.addModule(function(scope) {
-  var flags = scope.flags;
-  var forSubtree = scope.forSubtree;
-  var forDocumentTree = scope.forDocumentTree;
-  function addedNode(node) {
-    return added(node) || addedSubtree(node);
-  }
-  function added(node) {
-    if (scope.upgrade(node)) {
-      return true;
-    }
-    attached(node);
-  }
-  function addedSubtree(node) {
-    forSubtree(node, function(e) {
-      if (added(e)) {
-        return true;
-      }
-    });
-  }
-  function attachedNode(node) {
-    attached(node);
-    if (inDocument(node)) {
-      forSubtree(node, function(e) {
-        attached(e);
-      });
-    }
-  }
-  var hasPolyfillMutations = !window.MutationObserver || window.MutationObserver === window.JsMutationObserver;
-  scope.hasPolyfillMutations = hasPolyfillMutations;
-  var isPendingMutations = false;
-  var pendingMutations = [];
-  function deferMutation(fn) {
-    pendingMutations.push(fn);
-    if (!isPendingMutations) {
-      isPendingMutations = true;
-      setTimeout(takeMutations);
-    }
-  }
-  function takeMutations() {
-    isPendingMutations = false;
-    var $p = pendingMutations;
-    for (var i = 0, l = $p.length, p; i < l && (p = $p[i]); i++) {
-      p();
-    }
-    pendingMutations = [];
-  }
-  function attached(element) {
-    if (hasPolyfillMutations) {
-      deferMutation(function() {
-        _attached(element);
-      });
-    } else {
-      _attached(element);
-    }
-  }
-  function _attached(element) {
-    if (element.__upgraded__ && (element.attachedCallback || element.detachedCallback)) {
-      if (!element.__attached && inDocument(element)) {
-        element.__attached = true;
-        if (element.attachedCallback) {
-          element.attachedCallback();
-        }
-      }
-    }
-  }
-  function detachedNode(node) {
-    detached(node);
-    forSubtree(node, function(e) {
-      detached(e);
-    });
-  }
-  function detached(element) {
-    if (hasPolyfillMutations) {
-      deferMutation(function() {
-        _detached(element);
-      });
-    } else {
-      _detached(element);
-    }
-  }
-  function _detached(element) {
-    if (element.__upgraded__ && (element.attachedCallback || element.detachedCallback)) {
-      if (element.__attached && !inDocument(element)) {
-        element.__attached = false;
-        if (element.detachedCallback) {
-          element.detachedCallback();
-        }
-      }
-    }
-  }
-  function inDocument(element) {
-    var p = element;
-    var doc = wrap(document);
-    while (p) {
-      if (p == doc) {
-        return true;
-      }
-      p = p.parentNode || p.host;
-    }
-  }
-  function watchShadow(node) {
-    if (node.shadowRoot && !node.shadowRoot.__watched) {
-      flags.dom && console.log("watching shadow-root for: ", node.localName);
-      var root = node.shadowRoot;
-      while (root) {
-        observe(root);
-        root = root.olderShadowRoot;
-      }
-    }
-  }
-  function handler(mutations) {
-    if (flags.dom) {
-      var mx = mutations[0];
-      if (mx && mx.type === "childList" && mx.addedNodes) {
-        if (mx.addedNodes) {
-          var d = mx.addedNodes[0];
-          while (d && d !== document && !d.host) {
-            d = d.parentNode;
-          }
-          var u = d && (d.URL || d._URL || d.host && d.host.localName) || "";
-          u = u.split("/?").shift().split("/").pop();
-        }
-      }
-      console.group("mutations (%d) [%s]", mutations.length, u || "");
-    }
-    mutations.forEach(function(mx) {
-      if (mx.type === "childList") {
-        forEach(mx.addedNodes, function(n) {
-          if (!n.localName) {
-            return;
-          }
-          addedNode(n);
-        });
-        forEach(mx.removedNodes, function(n) {
-          if (!n.localName) {
-            return;
-          }
-          detachedNode(n);
-        });
-      }
-    });
-    flags.dom && console.groupEnd();
-  }
-  function takeRecords(node) {
-    node = wrap(node);
-    if (!node) {
-      node = wrap(document);
-    }
-    while (node.parentNode) {
-      node = node.parentNode;
-    }
-    var observer = node.__observer;
-    if (observer) {
-      handler(observer.takeRecords());
-      takeMutations();
-    }
-  }
-  var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);
-  function observe(inRoot) {
-    if (inRoot.__observer) {
-      return;
-    }
-    var observer = new MutationObserver(handler);
-    observer.observe(inRoot, {
-      childList: true,
-      subtree: true
-    });
-    inRoot.__observer = observer;
-  }
-  function upgradeDocument(doc) {
-    doc = wrap(doc);
-    flags.dom && console.group("upgradeDocument: ", doc.baseURI.split("/").pop());
-    addedNode(doc);
-    observe(doc);
-    flags.dom && console.groupEnd();
-  }
-  function upgradeDocumentTree(doc) {
-    forDocumentTree(doc, upgradeDocument);
-  }
-  var originalCreateShadowRoot = Element.prototype.createShadowRoot;
-  if (originalCreateShadowRoot) {
-    Element.prototype.createShadowRoot = function() {
-      var root = originalCreateShadowRoot.call(this);
-      CustomElements.watchShadow(this);
-      return root;
-    };
-  }
-  scope.watchShadow = watchShadow;
-  scope.upgradeDocumentTree = upgradeDocumentTree;
-  scope.upgradeSubtree = addedSubtree;
-  scope.upgradeAll = addedNode;
-  scope.attachedNode = attachedNode;
-  scope.takeRecords = takeRecords;
-});
-
-CustomElements.addModule(function(scope) {
-  var flags = scope.flags;
-  function upgrade(node) {
-    if (!node.__upgraded__ && node.nodeType === Node.ELEMENT_NODE) {
-      var is = node.getAttribute("is");
-      var definition = scope.getRegisteredDefinition(is || node.localName);
-      if (definition) {
-        if (is && definition.tag == node.localName) {
-          return upgradeWithDefinition(node, definition);
-        } else if (!is && !definition.extends) {
-          return upgradeWithDefinition(node, definition);
-        }
-      }
-    }
-  }
-  function upgradeWithDefinition(element, definition) {
-    flags.upgrade && console.group("upgrade:", element.localName);
-    if (definition.is) {
-      element.setAttribute("is", definition.is);
-    }
-    implementPrototype(element, definition);
-    element.__upgraded__ = true;
-    created(element);
-    scope.attachedNode(element);
-    scope.upgradeSubtree(element);
-    flags.upgrade && console.groupEnd();
-    return element;
-  }
-  function implementPrototype(element, definition) {
-    if (Object.__proto__) {
-      element.__proto__ = definition.prototype;
-    } else {
-      customMixin(element, definition.prototype, definition.native);
-      element.__proto__ = definition.prototype;
-    }
-  }
-  function customMixin(inTarget, inSrc, inNative) {
-    var used = {};
-    var p = inSrc;
-    while (p !== inNative && p !== HTMLElement.prototype) {
-      var keys = Object.getOwnPropertyNames(p);
-      for (var i = 0, k; k = keys[i]; i++) {
-        if (!used[k]) {
-          Object.defineProperty(inTarget, k, Object.getOwnPropertyDescriptor(p, k));
-          used[k] = 1;
-        }
-      }
-      p = Object.getPrototypeOf(p);
-    }
-  }
-  function created(element) {
-    if (element.createdCallback) {
-      element.createdCallback();
-    }
-  }
-  scope.upgrade = upgrade;
-  scope.upgradeWithDefinition = upgradeWithDefinition;
-  scope.implementPrototype = implementPrototype;
-});
-
-CustomElements.addModule(function(scope) {
-  var upgradeDocumentTree = scope.upgradeDocumentTree;
-  var upgrade = scope.upgrade;
-  var upgradeWithDefinition = scope.upgradeWithDefinition;
-  var implementPrototype = scope.implementPrototype;
-  var useNative = scope.useNative;
-  function register(name, options) {
-    var definition = options || {};
-    if (!name) {
-      throw new Error("document.registerElement: first argument `name` must not be empty");
-    }
-    if (name.indexOf("-") < 0) {
-      throw new Error("document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '" + String(name) + "'.");
-    }
-    if (isReservedTag(name)) {
-      throw new Error("Failed to execute 'registerElement' on 'Document': Registration failed for type '" + String(name) + "'. The type name is invalid.");
-    }
-    if (getRegisteredDefinition(name)) {
-      throw new Error("DuplicateDefinitionError: a type with name '" + String(name) + "' is already registered");
-    }
-    if (!definition.prototype) {
-      definition.prototype = Object.create(HTMLElement.prototype);
-    }
-    definition.__name = name.toLowerCase();
-    definition.lifecycle = definition.lifecycle || {};
-    definition.ancestry = ancestry(definition.extends);
-    resolveTagName(definition);
-    resolvePrototypeChain(definition);
-    overrideAttributeApi(definition.prototype);
-    registerDefinition(definition.__name, definition);
-    definition.ctor = generateConstructor(definition);
-    definition.ctor.prototype = definition.prototype;
-    definition.prototype.constructor = definition.ctor;
-    if (scope.ready) {
-      upgradeDocumentTree(document);
-    }
-    return definition.ctor;
-  }
-  function overrideAttributeApi(prototype) {
-    if (prototype.setAttribute._polyfilled) {
-      return;
-    }
-    var setAttribute = prototype.setAttribute;
-    prototype.setAttribute = function(name, value) {
-      changeAttribute.call(this, name, value, setAttribute);
-    };
-    var removeAttribute = prototype.removeAttribute;
-    prototype.removeAttribute = function(name) {
-      changeAttribute.call(this, name, null, removeAttribute);
-    };
-    prototype.setAttribute._polyfilled = true;
-  }
-  function changeAttribute(name, value, operation) {
-    name = name.toLowerCase();
-    var oldValue = this.getAttribute(name);
-    operation.apply(this, arguments);
-    var newValue = this.getAttribute(name);
-    if (this.attributeChangedCallback && newValue !== oldValue) {
-      this.attributeChangedCallback(name, oldValue, newValue);
-    }
-  }
-  function isReservedTag(name) {
-    for (var i = 0; i < reservedTagList.length; i++) {
-      if (name === reservedTagList[i]) {
-        return true;
-      }
-    }
-  }
-  var reservedTagList = [ "annotation-xml", "color-profile", "font-face", "font-face-src", "font-face-uri", "font-face-format", "font-face-name", "missing-glyph" ];
-  function ancestry(extnds) {
-    var extendee = getRegisteredDefinition(extnds);
-    if (extendee) {
-      return ancestry(extendee.extends).concat([ extendee ]);
-    }
-    return [];
-  }
-  function resolveTagName(definition) {
-    var baseTag = definition.extends;
-    for (var i = 0, a; a = definition.ancestry[i]; i++) {
-      baseTag = a.is && a.tag;
-    }
-    definition.tag = baseTag || definition.__name;
-    if (baseTag) {
-      definition.is = definition.__name;
-    }
-  }
-  function resolvePrototypeChain(definition) {
-    if (!Object.__proto__) {
-      var nativePrototype = HTMLElement.prototype;
-      if (definition.is) {
-        var inst = document.createElement(definition.tag);
-        var expectedPrototype = Object.getPrototypeOf(inst);
-        if (expectedPrototype === definition.prototype) {
-          nativePrototype = expectedPrototype;
-        }
-      }
-      var proto = definition.prototype, ancestor;
-      while (proto && proto !== nativePrototype) {
-        ancestor = Object.getPrototypeOf(proto);
-        proto.__proto__ = ancestor;
-        proto = ancestor;
-      }
-      definition.native = nativePrototype;
-    }
-  }
-  function instantiate(definition) {
-    return upgradeWithDefinition(domCreateElement(definition.tag), definition);
-  }
-  var registry = {};
-  function getRegisteredDefinition(name) {
-    if (name) {
-      return registry[name.toLowerCase()];
-    }
-  }
-  function registerDefinition(name, definition) {
-    registry[name] = definition;
-  }
-  function generateConstructor(definition) {
-    return function() {
-      return instantiate(definition);
-    };
-  }
-  var HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
-  function createElementNS(namespace, tag, typeExtension) {
-    if (namespace === HTML_NAMESPACE) {
-      return createElement(tag, typeExtension);
-    } else {
-      return domCreateElementNS(namespace, tag);
-    }
-  }
-  function createElement(tag, typeExtension) {
-    var definition = getRegisteredDefinition(typeExtension || tag);
-    if (definition) {
-      if (tag == definition.tag && typeExtension == definition.is) {
-        return new definition.ctor();
-      }
-      if (!typeExtension && !definition.is) {
-        return new definition.ctor();
-      }
-    }
-    var element;
-    if (typeExtension) {
-      element = createElement(tag);
-      element.setAttribute("is", typeExtension);
-      return element;
-    }
-    element = domCreateElement(tag);
-    if (tag.indexOf("-") >= 0) {
-      implementPrototype(element, HTMLElement);
-    }
-    return element;
-  }
-  function cloneNode(deep) {
-    var n = domCloneNode.call(this, deep);
-    upgrade(n);
-    return n;
-  }
-  var domCreateElement = document.createElement.bind(document);
-  var domCreateElementNS = document.createElementNS.bind(document);
-  var domCloneNode = Node.prototype.cloneNode;
-  var isInstance;
-  if (!Object.__proto__ && !useNative) {
-    isInstance = function(obj, ctor) {
-      var p = obj;
-      while (p) {
-        if (p === ctor.prototype) {
-          return true;
-        }
-        p = p.__proto__;
-      }
-      return false;
-    };
-  } else {
-    isInstance = function(obj, base) {
-      return obj instanceof base;
-    };
-  }
-  document.registerElement = register;
-  document.createElement = createElement;
-  document.createElementNS = createElementNS;
-  Node.prototype.cloneNode = cloneNode;
-  scope.registry = registry;
-  scope.instanceof = isInstance;
-  scope.reservedTagList = reservedTagList;
-  scope.getRegisteredDefinition = getRegisteredDefinition;
-  document.register = document.registerElement;
-});
-
-(function(scope) {
-  var useNative = scope.useNative;
-  var initializeModules = scope.initializeModules;
-  var isIE11OrOlder = /Trident/.test(navigator.userAgent);
-  if (useNative) {
-    var nop = function() {};
-    scope.watchShadow = nop;
-    scope.upgrade = nop;
-    scope.upgradeAll = nop;
-    scope.upgradeDocumentTree = nop;
-    scope.upgradeSubtree = nop;
-    scope.takeRecords = nop;
-    scope.instanceof = function(obj, base) {
-      return obj instanceof base;
-    };
-  } else {
-    initializeModules();
-  }
-  var upgradeDocumentTree = scope.upgradeDocumentTree;
-  if (!window.wrap) {
-    if (window.ShadowDOMPolyfill) {
-      window.wrap = ShadowDOMPolyfill.wrapIfNeeded;
-      window.unwrap = ShadowDOMPolyfill.unwrapIfNeeded;
-    } else {
-      window.wrap = window.unwrap = function(node) {
-        return node;
-      };
-    }
-  }
-  function bootstrap() {
-    upgradeDocumentTree(wrap(document));
-    if (window.HTMLImports) {
-      HTMLImports.__importsParsingHook = function(elt) {
-        upgradeDocumentTree(wrap(elt.import));
-      };
-    }
-    CustomElements.ready = true;
-    setTimeout(function() {
-      CustomElements.readyTime = Date.now();
-      if (window.HTMLImports) {
-        CustomElements.elapsed = CustomElements.readyTime - HTMLImports.readyTime;
-      }
-      document.dispatchEvent(new CustomEvent("WebComponentsReady", {
-        bubbles: true
-      }));
-    });
-  }
-  if (isIE11OrOlder && typeof window.CustomEvent !== "function") {
-    window.CustomEvent = function(inType, params) {
-      params = params || {};
-      var e = document.createEvent("CustomEvent");
-      e.initCustomEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable), params.detail);
-      return e;
-    };
-    window.CustomEvent.prototype = window.Event.prototype;
-  }
-  if (document.readyState === "complete" || scope.flags.eager) {
-    bootstrap();
-  } else if (document.readyState === "interactive" && !window.attachEvent && (!window.HTMLImports || window.HTMLImports.ready)) {
-    bootstrap();
-  } else {
-    var loadEvent = window.HTMLImports && !HTMLImports.ready ? "HTMLImportsLoaded" : "DOMContentLoaded";
-    window.addEventListener(loadEvent, bootstrap);
-  }
-})(window.CustomElements);
-
-if (typeof HTMLTemplateElement === "undefined") {
-  (function() {
-    var TEMPLATE_TAG = "template";
-    HTMLTemplateElement = function() {};
-    HTMLTemplateElement.prototype = Object.create(HTMLElement.prototype);
-    HTMLTemplateElement.decorate = function(template) {
-      if (!template.content) {
-        template.content = template.ownerDocument.createDocumentFragment();
-        var child;
-        while (child = template.firstChild) {
-          template.content.appendChild(child);
-        }
-      }
-    };
-    HTMLTemplateElement.bootstrap = function(doc) {
-      var templates = doc.querySelectorAll(TEMPLATE_TAG);
-      for (var i = 0, l = templates.length, t; i < l && (t = templates[i]); i++) {
-        HTMLTemplateElement.decorate(t);
-      }
-    };
-    addEventListener("DOMContentLoaded", function() {
-      HTMLTemplateElement.bootstrap(document);
-    });
-  })();
-}
-
-(function(scope) {
-  var style = document.createElement("style");
-  style.textContent = "" + "body {" + "transition: opacity ease-in 0.2s;" + " } \n" + "body[unresolved] {" + "opacity: 0; display: block; overflow: hidden; position: relative;" + " } \n";
-  var head = document.querySelector("head");
-  head.insertBefore(style, head.firstChild);
-})(window.WebComponents);
\ No newline at end of file
diff --git a/example/bower_components/webcomponentsjs/webcomponents-lite.min.js b/example/bower_components/webcomponentsjs/webcomponents-lite.min.js
deleted file mode 100644
index db80a800e..000000000
--- a/example/bower_components/webcomponentsjs/webcomponents-lite.min.js
+++ /dev/null
@@ -1,11 +0,0 @@
-/**
- * @license
- * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
- * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
- * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
- * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
- * Code distributed by Google as part of the polymer project is also
- * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
- */
-// @version 0.5.5
-window.WebComponents=window.WebComponents||{},function(e){var t=e.flags||{},n="webcomponents.js",o=document.querySelector('script[src*="'+n+'"]');if(!t.noOpts){if(location.search.slice(1).split("&").forEach(function(e){e=e.split("="),e[0]&&(t[e[0]]=e[1]||!0)}),o)for(var r,i=0;r=o.attributes[i];i++)"src"!==r.name&&(t[r.name]=r.value||!0);if(t.log){var a=t.log.split(",");t.log={},a.forEach(function(e){t.log[e]=!0})}else t.log={}}t.shadow=t.shadow||t.shadowdom||t.polyfill,t.shadow="native"===t.shadow?!1:t.shadow||!HTMLElement.prototype.createShadowRoot,t.register&&(window.CustomElements=window.CustomElements||{flags:{}},window.CustomElements.flags.register=t.register),e.flags=t}(WebComponents),function(e){function t(e){_.push(e),w||(w=!0,h(o))}function n(e){return window.ShadowDOMPolyfill&&window.ShadowDOMPolyfill.wrapIfNeeded(e)||e}function o(){w=!1;var e=_;_=[],e.sort(function(e,t){return e.uid_-t.uid_});var t=!1;e.forEach(function(e){var n=e.takeRecords();r(e),n.length&&(e.callback_(n,e),t=!0)}),t&&o()}function r(e){e.nodes_.forEach(function(t){var n=v.get(t);n&&n.forEach(function(t){t.observer===e&&t.removeTransientObservers()})})}function i(e,t){for(var n=e;n;n=n.parentNode){var o=v.get(n);if(o)for(var r=0;r0){var r=n[o-1],i=m(r,e);if(i)return void(n[o-1]=i)}else t(this.observer);n[o]=e},addListeners:function(){this.addListeners_(this.target)},addListeners_:function(e){var t=this.options;t.attributes&&e.addEventListener("DOMAttrModified",this,!0),t.characterData&&e.addEventListener("DOMCharacterDataModified",this,!0),t.childList&&e.addEventListener("DOMNodeInserted",this,!0),(t.childList||t.subtree)&&e.addEventListener("DOMNodeRemoved",this,!0)},removeListeners:function(){this.removeListeners_(this.target)},removeListeners_:function(e){var t=this.options;t.attributes&&e.removeEventListener("DOMAttrModified",this,!0),t.characterData&&e.removeEventListener("DOMCharacterDataModified",this,!0),t.childList&&e.removeEventListener("DOMNodeInserted",this,!0),(t.childList||t.subtree)&&e.removeEventListener("DOMNodeRemoved",this,!0)},addTransientObserver:function(e){if(e!==this.target){this.addListeners_(e),this.transientObservedNodes.push(e);var t=v.get(e);t||v.set(e,t=[]),t.push(this)}},removeTransientObservers:function(){var e=this.transientObservedNodes;this.transientObservedNodes=[],e.forEach(function(e){this.removeListeners_(e);for(var t=v.get(e),n=0;n>>0)+(t++ +"__")};n.prototype={set:function(t,n){var o=t[this.name];return o&&o[0]===t?o[1]=n:e(t,this.name,{value:[t,n],writable:!0}),this},get:function(e){var t;return(t=e[this.name])&&t[0]===e?t[1]:void 0},"delete":function(e){var t=e[this.name];return t&&t[0]===e?(t[0]=t[1]=void 0,!0):!1},has:function(e){var t=e[this.name];return t?t[0]===e:!1}},window.WeakMap=n}(),window.HTMLImports=window.HTMLImports||{flags:{}},function(e){function t(e,t){t=t||p,o(function(){i(e,t)},t)}function n(e){return"complete"===e.readyState||e.readyState===g}function o(e,t){if(n(t))e&&e();else{var r=function(){("complete"===t.readyState||t.readyState===g)&&(t.removeEventListener(b,r),o(e,t))};t.addEventListener(b,r)}}function r(e){e.target.__loaded=!0}function i(e,t){function n(){s==d&&e&&e()}function o(e){r(e),s++,n()}var i=t.querySelectorAll("link[rel=import]"),s=0,d=i.length;if(d)for(var c,u=0;d>u&&(c=i[u]);u++)a(c)?o.call(c,{target:c}):(c.addEventListener("load",o),c.addEventListener("error",o));else n()}function a(e){return l?e.__loaded||e["import"]&&"loading"!==e["import"].readyState:e.__importParsed}function s(e){for(var t,n=0,o=e.length;o>n&&(t=e[n]);n++)d(t)&&c(t)}function d(e){return"link"===e.localName&&"import"===e.rel}function c(e){var t=e["import"];t?r({target:e}):(e.addEventListener("load",r),e.addEventListener("error",r))}var u="import",l=Boolean(u in document.createElement("link")),f=Boolean(window.ShadowDOMPolyfill),m=function(e){return f?ShadowDOMPolyfill.wrapIfNeeded(e):e},p=m(document),h={get:function(){var e=HTMLImports.currentScript||document.currentScript||("complete"!==document.readyState?document.scripts[document.scripts.length-1]:null);return m(e)},configurable:!0};Object.defineProperty(document,"_currentScript",h),Object.defineProperty(p,"_currentScript",h);var v=/Trident|Edge/.test(navigator.userAgent),g=v?"complete":"interactive",b="readystatechange";l&&(new MutationObserver(function(e){for(var t,n=0,o=e.length;o>n&&(t=e[n]);n++)t.addedNodes&&s(t.addedNodes)}).observe(document.head,{childList:!0}),function(){if("loading"===document.readyState)for(var e,t=document.querySelectorAll("link[rel=import]"),n=0,o=t.length;o>n&&(e=t[n]);n++)c(e)}()),t(function(){HTMLImports.ready=!0,HTMLImports.readyTime=(new Date).getTime();var e=p.createEvent("CustomEvent");e.initCustomEvent("HTMLImportsLoaded",!0,!0,{}),p.dispatchEvent(e)}),e.IMPORT_LINK_TYPE=u,e.useNative=l,e.rootDocument=p,e.whenReady=t,e.isIE=v}(HTMLImports),function(e){var t=[],n=function(e){t.push(e)},o=function(){t.forEach(function(t){t(e)})};e.addModule=n,e.initializeModules=o}(HTMLImports),HTMLImports.addModule(function(e){var t=/(url\()([^)]*)(\))/g,n=/(@import[\s]+(?!url\())([^;]*)(;)/g,o={resolveUrlsInStyle:function(e){var t=e.ownerDocument,n=t.createElement("a");return e.textContent=this.resolveUrlsInCssText(e.textContent,n),e},resolveUrlsInCssText:function(e,o){var r=this.replaceUrls(e,o,t);return r=this.replaceUrls(r,o,n)},replaceUrls:function(e,t,n){return e.replace(n,function(e,n,o,r){var i=o.replace(/["']/g,"");return t.href=i,i=t.href,n+"'"+i+"'"+r})}};e.path=o}),HTMLImports.addModule(function(e){var t={async:!0,ok:function(e){return e.status>=200&&e.status<300||304===e.status||0===e.status},load:function(n,o,r){var i=new XMLHttpRequest;return(e.flags.debug||e.flags.bust)&&(n+="?"+Math.random()),i.open("GET",n,t.async),i.addEventListener("readystatechange",function(){if(4===i.readyState){var e=i.getResponseHeader("Location"),n=null;if(e)var n="/"===e.substr(0,1)?location.origin+e:e;o.call(r,!t.ok(i)&&i,i.response||i.responseText,n)}}),i.send(),i},loadDocument:function(e,t,n){this.load(e,t,n).responseType="document"}};e.xhr=t}),HTMLImports.addModule(function(e){var t=e.xhr,n=e.flags,o=function(e,t){this.cache={},this.onload=e,this.oncomplete=t,this.inflight=0,this.pending={}};o.prototype={addNodes:function(e){this.inflight+=e.length;for(var t,n=0,o=e.length;o>n&&(t=e[n]);n++)this.require(t);this.checkDone()},addNode:function(e){this.inflight++,this.require(e),this.checkDone()},require:function(e){var t=e.src||e.href;e.__nodeUrl=t,this.dedupe(t,e)||this.fetch(t,e)},dedupe:function(e,t){if(this.pending[e])return this.pending[e].push(t),!0;return this.cache[e]?(this.onload(e,t,this.cache[e]),this.tail(),!0):(this.pending[e]=[t],!1)},fetch:function(e,o){if(n.load&&console.log("fetch",e,o),e)if(e.match(/^data:/)){var r=e.split(","),i=r[0],a=r[1];a=i.indexOf(";base64")>-1?atob(a):decodeURIComponent(a),setTimeout(function(){this.receive(e,o,null,a)}.bind(this),0)}else{var s=function(t,n,r){this.receive(e,o,t,n,r)}.bind(this);t.load(e,s)}else setTimeout(function(){this.receive(e,o,{error:"href must be specified"},null)}.bind(this),0)},receive:function(e,t,n,o,r){this.cache[e]=o;for(var i,a=this.pending[e],s=0,d=a.length;d>s&&(i=a[s]);s++)this.onload(e,i,o,n,r),this.tail();this.pending[e]=null},tail:function(){--this.inflight,this.checkDone()},checkDone:function(){this.inflight||this.oncomplete()}},e.Loader=o}),HTMLImports.addModule(function(e){var t=function(e){this.addCallback=e,this.mo=new MutationObserver(this.handler.bind(this))};t.prototype={handler:function(e){for(var t,n=0,o=e.length;o>n&&(t=e[n]);n++)"childList"===t.type&&t.addedNodes.length&&this.addedNodes(t.addedNodes)},addedNodes:function(e){this.addCallback&&this.addCallback(e);for(var t,n=0,o=e.length;o>n&&(t=e[n]);n++)t.children&&t.children.length&&this.addedNodes(t.children)},observe:function(e){this.mo.observe(e,{childList:!0,subtree:!0})}},e.Observer=t}),HTMLImports.addModule(function(e){function t(e){return"link"===e.localName&&e.rel===u}function n(e){var t=o(e);return"data:text/javascript;charset=utf-8,"+encodeURIComponent(t)}function o(e){return e.textContent+r(e)}function r(e){var t=e.ownerDocument;t.__importedScripts=t.__importedScripts||0;var n=e.ownerDocument.baseURI,o=t.__importedScripts?"-"+t.__importedScripts:"";return t.__importedScripts++,"\n//# sourceURL="+n+o+".js\n"}function i(e){var t=e.ownerDocument.createElement("style");return t.textContent=e.textContent,a.resolveUrlsInStyle(t),t}var a=e.path,s=e.rootDocument,d=e.flags,c=e.isIE,u=e.IMPORT_LINK_TYPE,l="link[rel="+u+"]",f={documentSelectors:l,importsSelectors:[l,"link[rel=stylesheet]","style","script:not([type])",'script[type="text/javascript"]'].join(","),map:{link:"parseLink",script:"parseScript",style:"parseStyle"},dynamicElements:[],parseNext:function(){var e=this.nextToParse();e&&this.parse(e)},parse:function(e){if(this.isParsed(e))return void(d.parse&&console.log("[%s] is already parsed",e.localName));var t=this[this.map[e.localName]];t&&(this.markParsing(e),t.call(this,e))},parseDynamic:function(e,t){this.dynamicElements.push(e),t||this.parseNext()},markParsing:function(e){d.parse&&console.log("parsing",e),this.parsingElement=e},markParsingComplete:function(e){e.__importParsed=!0,this.markDynamicParsingComplete(e),e.__importElement&&(e.__importElement.__importParsed=!0,this.markDynamicParsingComplete(e.__importElement)),this.parsingElement=null,d.parse&&console.log("completed",e)},markDynamicParsingComplete:function(e){var t=this.dynamicElements.indexOf(e);t>=0&&this.dynamicElements.splice(t,1)},parseImport:function(e){if(HTMLImports.__importsParsingHook&&HTMLImports.__importsParsingHook(e),e["import"]&&(e["import"].__importParsed=!0),this.markParsingComplete(e),e.dispatchEvent(e.__resource&&!e.__error?new CustomEvent("load",{bubbles:!1}):new CustomEvent("error",{bubbles:!1})),e.__pending)for(var t;e.__pending.length;)t=e.__pending.shift(),t&&t({target:e});this.parseNext()},parseLink:function(e){t(e)?this.parseImport(e):(e.href=e.href,this.parseGeneric(e))},parseStyle:function(e){var t=e;e=i(e),e.__importElement=t,this.parseGeneric(e)},parseGeneric:function(e){this.trackElement(e),this.addElementToDocument(e)},rootImportForElement:function(e){for(var t=e;t.ownerDocument.__importLink;)t=t.ownerDocument.__importLink;return t},addElementToDocument:function(e){var t=this.rootImportForElement(e.__importElement||e);t.parentNode.insertBefore(e,t)},trackElement:function(e,t){var n=this,o=function(o){t&&t(o),n.markParsingComplete(e),n.parseNext()};if(e.addEventListener("load",o),e.addEventListener("error",o),c&&"style"===e.localName){var r=!1;if(-1==e.textContent.indexOf("@import"))r=!0;else if(e.sheet){r=!0;for(var i,a=e.sheet.cssRules,s=a?a.length:0,d=0;s>d&&(i=a[d]);d++)i.type===CSSRule.IMPORT_RULE&&(r=r&&Boolean(i.styleSheet))}r&&e.dispatchEvent(new CustomEvent("load",{bubbles:!1}))}},parseScript:function(t){var o=document.createElement("script");o.__importElement=t,o.src=t.src?t.src:n(t),e.currentScript=t,this.trackElement(o,function(){o.parentNode.removeChild(o),e.currentScript=null}),this.addElementToDocument(o)},nextToParse:function(){return this._mayParse=[],!this.parsingElement&&(this.nextToParseInDoc(s)||this.nextToParseDynamic())},nextToParseInDoc:function(e,n){if(e&&this._mayParse.indexOf(e)<0){this._mayParse.push(e);for(var o,r=e.querySelectorAll(this.parseSelectorsForNode(e)),i=0,a=r.length;a>i&&(o=r[i]);i++)if(!this.isParsed(o))return this.hasResource(o)?t(o)?this.nextToParseInDoc(o["import"],o):o:void 0}return n},nextToParseDynamic:function(){return this.dynamicElements[0]},parseSelectorsForNode:function(e){var t=e.ownerDocument||e;return t===s?this.documentSelectors:this.importsSelectors},isParsed:function(e){return e.__importParsed},needsDynamicParsing:function(e){return this.dynamicElements.indexOf(e)>=0},hasResource:function(e){return t(e)&&void 0===e["import"]?!1:!0}};e.parser=f,e.IMPORT_SELECTOR=l}),HTMLImports.addModule(function(e){function t(e){return n(e,a)}function n(e,t){return"link"===e.localName&&e.getAttribute("rel")===t}function o(e){return!!Object.getOwnPropertyDescriptor(e,"baseURI")}function r(e,t){var n=document.implementation.createHTMLDocument(a);n._URL=t;var r=n.createElement("base");r.setAttribute("href",t),n.baseURI||o(n)||Object.defineProperty(n,"baseURI",{value:t});var i=n.createElement("meta");return i.setAttribute("charset","utf-8"),n.head.appendChild(i),n.head.appendChild(r),n.body.innerHTML=e,window.HTMLTemplateElement&&HTMLTemplateElement.bootstrap&&HTMLTemplateElement.bootstrap(n),n}var i=e.flags,a=e.IMPORT_LINK_TYPE,s=e.IMPORT_SELECTOR,d=e.rootDocument,c=e.Loader,u=e.Observer,l=e.parser,f={documents:{},documentPreloadSelectors:s,importsPreloadSelectors:[s].join(","),loadNode:function(e){m.addNode(e)},loadSubtree:function(e){var t=this.marshalNodes(e);m.addNodes(t)},marshalNodes:function(e){return e.querySelectorAll(this.loadSelectorsForNode(e))},loadSelectorsForNode:function(e){var t=e.ownerDocument||e;return t===d?this.documentPreloadSelectors:this.importsPreloadSelectors},loaded:function(e,n,o,a,s){if(i.load&&console.log("loaded",e,n),n.__resource=o,n.__error=a,t(n)){var d=this.documents[e];void 0===d&&(d=a?null:r(o,s||e),d&&(d.__importLink=n,this.bootDocument(d)),this.documents[e]=d),n["import"]=d}l.parseNext()},bootDocument:function(e){this.loadSubtree(e),this.observer.observe(e),l.parseNext()},loadedAll:function(){l.parseNext()}},m=new c(f.loaded.bind(f),f.loadedAll.bind(f));if(f.observer=new u,!document.baseURI){var p={get:function(){var e=document.querySelector("base");return e?e.href:window.location.href},configurable:!0};Object.defineProperty(document,"baseURI",p),Object.defineProperty(d,"baseURI",p)}e.importer=f,e.importLoader=m}),HTMLImports.addModule(function(e){var t=e.parser,n=e.importer,o={added:function(e){for(var o,r,i,a,s=0,d=e.length;d>s&&(a=e[s]);s++)o||(o=a.ownerDocument,r=t.isParsed(o)),i=this.shouldLoadNode(a),i&&n.loadNode(a),this.shouldParseNode(a)&&r&&t.parseDynamic(a,i)},shouldLoadNode:function(e){return 1===e.nodeType&&r.call(e,n.loadSelectorsForNode(e))},shouldParseNode:function(e){return 1===e.nodeType&&r.call(e,t.parseSelectorsForNode(e))}};n.observer.addCallback=o.added.bind(o);var r=HTMLElement.prototype.matches||HTMLElement.prototype.matchesSelector||HTMLElement.prototype.webkitMatchesSelector||HTMLElement.prototype.mozMatchesSelector||HTMLElement.prototype.msMatchesSelector}),function(e){function t(){HTMLImports.importer.bootDocument(r)}var n=e.initializeModules,o=e.isIE;if(!e.useNative){o&&"function"!=typeof window.CustomEvent&&(window.CustomEvent=function(e,t){t=t||{};var n=document.createEvent("CustomEvent");return n.initCustomEvent(e,Boolean(t.bubbles),Boolean(t.cancelable),t.detail),n},window.CustomEvent.prototype=window.Event.prototype),n();var r=e.rootDocument;"complete"===document.readyState||"interactive"===document.readyState&&!window.attachEvent?t():document.addEventListener("DOMContentLoaded",t)}}(HTMLImports),window.CustomElements=window.CustomElements||{flags:{}},function(e){var t=e.flags,n=[],o=function(e){n.push(e)},r=function(){n.forEach(function(t){t(e)})};e.addModule=o,e.initializeModules=r,e.hasNative=Boolean(document.registerElement),e.useNative=!t.register&&e.hasNative&&!window.ShadowDOMPolyfill&&(!window.HTMLImports||HTMLImports.useNative)}(CustomElements),CustomElements.addModule(function(e){function t(e,t){n(e,function(e){return t(e)?!0:void o(e,t)}),o(e,t)}function n(e,t,o){var r=e.firstElementChild;if(!r)for(r=e.firstChild;r&&r.nodeType!==Node.ELEMENT_NODE;)r=r.nextSibling;for(;r;)t(r,o)!==!0&&n(r,t,o),r=r.nextElementSibling;return null}function o(e,n){for(var o=e.shadowRoot;o;)t(o,n),o=o.olderShadowRoot}function r(e,t){a=[],i(e,t),a=null}function i(e,t){if(e=wrap(e),!(a.indexOf(e)>=0)){a.push(e);for(var n,o=e.querySelectorAll("link[rel="+s+"]"),r=0,d=o.length;d>r&&(n=o[r]);r++)n["import"]&&i(n["import"],t);t(e)}}var a,s=window.HTMLImports?HTMLImports.IMPORT_LINK_TYPE:"none";e.forDocumentTree=r,e.forSubtree=t}),CustomElements.addModule(function(e){function t(e){return n(e)||o(e)}function n(t){return e.upgrade(t)?!0:void s(t)}function o(e){_(e,function(e){return n(e)?!0:void 0})}function r(e){s(e),f(e)&&_(e,function(e){s(e)})}function i(e){M.push(e),L||(L=!0,setTimeout(a))}function a(){L=!1;for(var e,t=M,n=0,o=t.length;o>n&&(e=t[n]);n++)e();M=[]}function s(e){y?i(function(){d(e)}):d(e)}function d(e){e.__upgraded__&&(e.attachedCallback||e.detachedCallback)&&!e.__attached&&f(e)&&(e.__attached=!0,e.attachedCallback&&e.attachedCallback())}function c(e){u(e),_(e,function(e){u(e)})}function u(e){y?i(function(){l(e)}):l(e)}function l(e){e.__upgraded__&&(e.attachedCallback||e.detachedCallback)&&e.__attached&&!f(e)&&(e.__attached=!1,e.detachedCallback&&e.detachedCallback())}function f(e){for(var t=e,n=wrap(document);t;){if(t==n)return!0;t=t.parentNode||t.host}}function m(e){if(e.shadowRoot&&!e.shadowRoot.__watched){w.dom&&console.log("watching shadow-root for: ",e.localName);for(var t=e.shadowRoot;t;)v(t),t=t.olderShadowRoot}}function p(e){if(w.dom){var n=e[0];if(n&&"childList"===n.type&&n.addedNodes&&n.addedNodes){for(var o=n.addedNodes[0];o&&o!==document&&!o.host;)o=o.parentNode;var r=o&&(o.URL||o._URL||o.host&&o.host.localName)||"";r=r.split("/?").shift().split("/").pop()}console.group("mutations (%d) [%s]",e.length,r||"")}e.forEach(function(e){"childList"===e.type&&(T(e.addedNodes,function(e){e.localName&&t(e)}),T(e.removedNodes,function(e){e.localName&&c(e)}))}),w.dom&&console.groupEnd()}function h(e){for(e=wrap(e),e||(e=wrap(document));e.parentNode;)e=e.parentNode;var t=e.__observer;t&&(p(t.takeRecords()),a())}function v(e){if(!e.__observer){var t=new MutationObserver(p);t.observe(e,{childList:!0,subtree:!0}),e.__observer=t}}function g(e){e=wrap(e),w.dom&&console.group("upgradeDocument: ",e.baseURI.split("/").pop()),t(e),v(e),w.dom&&console.groupEnd()}function b(e){E(e,g)}var w=e.flags,_=e.forSubtree,E=e.forDocumentTree,y=!window.MutationObserver||window.MutationObserver===window.JsMutationObserver;e.hasPolyfillMutations=y;var L=!1,M=[],T=Array.prototype.forEach.call.bind(Array.prototype.forEach),N=Element.prototype.createShadowRoot;N&&(Element.prototype.createShadowRoot=function(){var e=N.call(this);return CustomElements.watchShadow(this),e}),e.watchShadow=m,e.upgradeDocumentTree=b,e.upgradeSubtree=o,e.upgradeAll=t,e.attachedNode=r,e.takeRecords=h}),CustomElements.addModule(function(e){function t(t){if(!t.__upgraded__&&t.nodeType===Node.ELEMENT_NODE){var o=t.getAttribute("is"),r=e.getRegisteredDefinition(o||t.localName);if(r){if(o&&r.tag==t.localName)return n(t,r);if(!o&&!r["extends"])return n(t,r)}}}function n(t,n){return a.upgrade&&console.group("upgrade:",t.localName),n.is&&t.setAttribute("is",n.is),o(t,n),t.__upgraded__=!0,i(t),e.attachedNode(t),e.upgradeSubtree(t),a.upgrade&&console.groupEnd(),t}function o(e,t){Object.__proto__?e.__proto__=t.prototype:(r(e,t.prototype,t["native"]),e.__proto__=t.prototype)}function r(e,t,n){for(var o={},r=t;r!==n&&r!==HTMLElement.prototype;){for(var i,a=Object.getOwnPropertyNames(r),s=0;i=a[s];s++)o[i]||(Object.defineProperty(e,i,Object.getOwnPropertyDescriptor(r,i)),o[i]=1);r=Object.getPrototypeOf(r)}}function i(e){e.createdCallback&&e.createdCallback()}var a=e.flags;e.upgrade=t,e.upgradeWithDefinition=n,e.implementPrototype=o}),CustomElements.addModule(function(e){function t(t,o){var d=o||{};if(!t)throw new Error("document.registerElement: first argument `name` must not be empty");if(t.indexOf("-")<0)throw new Error("document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '"+String(t)+"'.");if(r(t))throw new Error("Failed to execute 'registerElement' on 'Document': Registration failed for type '"+String(t)+"'. The type name is invalid.");if(c(t))throw new Error("DuplicateDefinitionError: a type with name '"+String(t)+"' is already registered");return d.prototype||(d.prototype=Object.create(HTMLElement.prototype)),d.__name=t.toLowerCase(),d.lifecycle=d.lifecycle||{},d.ancestry=i(d["extends"]),a(d),s(d),n(d.prototype),u(d.__name,d),d.ctor=l(d),d.ctor.prototype=d.prototype,d.prototype.constructor=d.ctor,e.ready&&v(document),d.ctor}function n(e){if(!e.setAttribute._polyfilled){var t=e.setAttribute;e.setAttribute=function(e,n){o.call(this,e,n,t)};var n=e.removeAttribute;e.removeAttribute=function(e){o.call(this,e,null,n)},e.setAttribute._polyfilled=!0}}function o(e,t,n){e=e.toLowerCase();var o=this.getAttribute(e);n.apply(this,arguments);var r=this.getAttribute(e);this.attributeChangedCallback&&r!==o&&this.attributeChangedCallback(e,o,r)}function r(e){for(var t=0;t=0&&w(o,HTMLElement),o)}function p(e){var t=N.call(this,e);return g(t),t}var h,v=e.upgradeDocumentTree,g=e.upgrade,b=e.upgradeWithDefinition,w=e.implementPrototype,_=e.useNative,E=["annotation-xml","color-profile","font-face","font-face-src","font-face-uri","font-face-format","font-face-name","missing-glyph"],y={},L="http://www.w3.org/1999/xhtml",M=document.createElement.bind(document),T=document.createElementNS.bind(document),N=Node.prototype.cloneNode;h=Object.__proto__||_?function(e,t){return e instanceof t}:function(e,t){for(var n=e;n;){if(n===t.prototype)return!0;n=n.__proto__}return!1},document.registerElement=t,document.createElement=m,document.createElementNS=f,Node.prototype.cloneNode=p,e.registry=y,e["instanceof"]=h,e.reservedTagList=E,e.getRegisteredDefinition=c,document.register=document.registerElement}),function(e){function t(){a(wrap(document)),window.HTMLImports&&(HTMLImports.__importsParsingHook=function(e){a(wrap(e["import"]))}),CustomElements.ready=!0,setTimeout(function(){CustomElements.readyTime=Date.now(),window.HTMLImports&&(CustomElements.elapsed=CustomElements.readyTime-HTMLImports.readyTime),document.dispatchEvent(new CustomEvent("WebComponentsReady",{bubbles:!0}))})}var n=e.useNative,o=e.initializeModules,r=/Trident/.test(navigator.userAgent);if(n){var i=function(){};e.watchShadow=i,e.upgrade=i,e.upgradeAll=i,e.upgradeDocumentTree=i,e.upgradeSubtree=i,e.takeRecords=i,e["instanceof"]=function(e,t){return e instanceof t}}else o();var a=e.upgradeDocumentTree;if(window.wrap||(window.ShadowDOMPolyfill?(window.wrap=ShadowDOMPolyfill.wrapIfNeeded,window.unwrap=ShadowDOMPolyfill.unwrapIfNeeded):window.wrap=window.unwrap=function(e){return e}),r&&"function"!=typeof window.CustomEvent&&(window.CustomEvent=function(e,t){t=t||{};var n=document.createEvent("CustomEvent");return n.initCustomEvent(e,Boolean(t.bubbles),Boolean(t.cancelable),t.detail),n},window.CustomEvent.prototype=window.Event.prototype),"complete"===document.readyState||e.flags.eager)t();else if("interactive"!==document.readyState||window.attachEvent||window.HTMLImports&&!window.HTMLImports.ready){var s=window.HTMLImports&&!HTMLImports.ready?"HTMLImportsLoaded":"DOMContentLoaded";window.addEventListener(s,t)}else t()}(window.CustomElements),"undefined"==typeof HTMLTemplateElement&&!function(){var e="template";HTMLTemplateElement=function(){},HTMLTemplateElement.prototype=Object.create(HTMLElement.prototype),HTMLTemplateElement.decorate=function(e){if(!e.content){e.content=e.ownerDocument.createDocumentFragment();for(var t;t=e.firstChild;)e.content.appendChild(t)}},HTMLTemplateElement.bootstrap=function(t){for(var n,o=t.querySelectorAll(e),r=0,i=o.length;i>r&&(n=o[r]);r++)HTMLTemplateElement.decorate(n)},addEventListener("DOMContentLoaded",function(){HTMLTemplateElement.bootstrap(document)})}(),function(){var e=document.createElement("style");e.textContent="body {transition: opacity ease-in 0.2s; } \nbody[unresolved] {opacity: 0; display: block; overflow: hidden; position: relative; } \n";var t=document.querySelector("head");t.insertBefore(e,t.firstChild)}(window.WebComponents);
\ No newline at end of file
diff --git a/example/bower_components/webcomponentsjs/webcomponents.js b/example/bower_components/webcomponentsjs/webcomponents.js
deleted file mode 100644
index 26f5d5bf6..000000000
--- a/example/bower_components/webcomponentsjs/webcomponents.js
+++ /dev/null
@@ -1,6114 +0,0 @@
-/**
- * @license
- * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
- * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
- * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
- * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
- * Code distributed by Google as part of the polymer project is also
- * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
- */
-// @version 0.5.5
-window.WebComponents = window.WebComponents || {};
-
-(function(scope) {
-  var flags = scope.flags || {};
-  var file = "webcomponents.js";
-  var script = document.querySelector('script[src*="' + file + '"]');
-  if (!flags.noOpts) {
-    location.search.slice(1).split("&").forEach(function(o) {
-      o = o.split("=");
-      o[0] && (flags[o[0]] = o[1] || true);
-    });
-    if (script) {
-      for (var i = 0, a; a = script.attributes[i]; i++) {
-        if (a.name !== "src") {
-          flags[a.name] = a.value || true;
-        }
-      }
-    }
-    if (flags.log) {
-      var parts = flags.log.split(",");
-      flags.log = {};
-      parts.forEach(function(f) {
-        flags.log[f] = true;
-      });
-    } else {
-      flags.log = {};
-    }
-  }
-  flags.shadow = flags.shadow || flags.shadowdom || flags.polyfill;
-  if (flags.shadow === "native") {
-    flags.shadow = false;
-  } else {
-    flags.shadow = flags.shadow || !HTMLElement.prototype.createShadowRoot;
-  }
-  if (flags.register) {
-    window.CustomElements = window.CustomElements || {
-      flags: {}
-    };
-    window.CustomElements.flags.register = flags.register;
-  }
-  scope.flags = flags;
-})(WebComponents);
-
-if (WebComponents.flags.shadow) {
-  if (typeof WeakMap === "undefined") {
-    (function() {
-      var defineProperty = Object.defineProperty;
-      var counter = Date.now() % 1e9;
-      var WeakMap = function() {
-        this.name = "__st" + (Math.random() * 1e9 >>> 0) + (counter++ + "__");
-      };
-      WeakMap.prototype = {
-        set: function(key, value) {
-          var entry = key[this.name];
-          if (entry && entry[0] === key) entry[1] = value; else defineProperty(key, this.name, {
-            value: [ key, value ],
-            writable: true
-          });
-          return this;
-        },
-        get: function(key) {
-          var entry;
-          return (entry = key[this.name]) && entry[0] === key ? entry[1] : undefined;
-        },
-        "delete": function(key) {
-          var entry = key[this.name];
-          if (!entry || entry[0] !== key) return false;
-          entry[0] = entry[1] = undefined;
-          return true;
-        },
-        has: function(key) {
-          var entry = key[this.name];
-          if (!entry) return false;
-          return entry[0] === key;
-        }
-      };
-      window.WeakMap = WeakMap;
-    })();
-  }
-  window.ShadowDOMPolyfill = {};
-  (function(scope) {
-    "use strict";
-    var constructorTable = new WeakMap();
-    var nativePrototypeTable = new WeakMap();
-    var wrappers = Object.create(null);
-    function detectEval() {
-      if (typeof chrome !== "undefined" && chrome.app && chrome.app.runtime) {
-        return false;
-      }
-      if (navigator.getDeviceStorage) {
-        return false;
-      }
-      try {
-        var f = new Function("return true;");
-        return f();
-      } catch (ex) {
-        return false;
-      }
-    }
-    var hasEval = detectEval();
-    function assert(b) {
-      if (!b) throw new Error("Assertion failed");
-    }
-    var defineProperty = Object.defineProperty;
-    var getOwnPropertyNames = Object.getOwnPropertyNames;
-    var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
-    function mixin(to, from) {
-      var names = getOwnPropertyNames(from);
-      for (var i = 0; i < names.length; i++) {
-        var name = names[i];
-        defineProperty(to, name, getOwnPropertyDescriptor(from, name));
-      }
-      return to;
-    }
-    function mixinStatics(to, from) {
-      var names = getOwnPropertyNames(from);
-      for (var i = 0; i < names.length; i++) {
-        var name = names[i];
-        switch (name) {
-         case "arguments":
-         case "caller":
-         case "length":
-         case "name":
-         case "prototype":
-         case "toString":
-          continue;
-        }
-        defineProperty(to, name, getOwnPropertyDescriptor(from, name));
-      }
-      return to;
-    }
-    function oneOf(object, propertyNames) {
-      for (var i = 0; i < propertyNames.length; i++) {
-        if (propertyNames[i] in object) return propertyNames[i];
-      }
-    }
-    var nonEnumerableDataDescriptor = {
-      value: undefined,
-      configurable: true,
-      enumerable: false,
-      writable: true
-    };
-    function defineNonEnumerableDataProperty(object, name, value) {
-      nonEnumerableDataDescriptor.value = value;
-      defineProperty(object, name, nonEnumerableDataDescriptor);
-    }
-    getOwnPropertyNames(window);
-    function getWrapperConstructor(node) {
-      var nativePrototype = node.__proto__ || Object.getPrototypeOf(node);
-      if (isFirefox) {
-        try {
-          getOwnPropertyNames(nativePrototype);
-        } catch (error) {
-          nativePrototype = nativePrototype.__proto__;
-        }
-      }
-      var wrapperConstructor = constructorTable.get(nativePrototype);
-      if (wrapperConstructor) return wrapperConstructor;
-      var parentWrapperConstructor = getWrapperConstructor(nativePrototype);
-      var GeneratedWrapper = createWrapperConstructor(parentWrapperConstructor);
-      registerInternal(nativePrototype, GeneratedWrapper, node);
-      return GeneratedWrapper;
-    }
-    function addForwardingProperties(nativePrototype, wrapperPrototype) {
-      installProperty(nativePrototype, wrapperPrototype, true);
-    }
-    function registerInstanceProperties(wrapperPrototype, instanceObject) {
-      installProperty(instanceObject, wrapperPrototype, false);
-    }
-    var isFirefox = /Firefox/.test(navigator.userAgent);
-    var dummyDescriptor = {
-      get: function() {},
-      set: function(v) {},
-      configurable: true,
-      enumerable: true
-    };
-    function isEventHandlerName(name) {
-      return /^on[a-z]+$/.test(name);
-    }
-    function isIdentifierName(name) {
-      return /^\w[a-zA-Z_0-9]*$/.test(name);
-    }
-    function getGetter(name) {
-      return hasEval && isIdentifierName(name) ? new Function("return this.__impl4cf1e782hg__." + name) : function() {
-        return this.__impl4cf1e782hg__[name];
-      };
-    }
-    function getSetter(name) {
-      return hasEval && isIdentifierName(name) ? new Function("v", "this.__impl4cf1e782hg__." + name + " = v") : function(v) {
-        this.__impl4cf1e782hg__[name] = v;
-      };
-    }
-    function getMethod(name) {
-      return hasEval && isIdentifierName(name) ? new Function("return this.__impl4cf1e782hg__." + name + ".apply(this.__impl4cf1e782hg__, arguments)") : function() {
-        return this.__impl4cf1e782hg__[name].apply(this.__impl4cf1e782hg__, arguments);
-      };
-    }
-    function getDescriptor(source, name) {
-      try {
-        return Object.getOwnPropertyDescriptor(source, name);
-      } catch (ex) {
-        return dummyDescriptor;
-      }
-    }
-    var isBrokenSafari = function() {
-      var descr = Object.getOwnPropertyDescriptor(Node.prototype, "nodeType");
-      return descr && !descr.get && !descr.set;
-    }();
-    function installProperty(source, target, allowMethod, opt_blacklist) {
-      var names = getOwnPropertyNames(source);
-      for (var i = 0; i < names.length; i++) {
-        var name = names[i];
-        if (name === "polymerBlackList_") continue;
-        if (name in target) continue;
-        if (source.polymerBlackList_ && source.polymerBlackList_[name]) continue;
-        if (isFirefox) {
-          source.__lookupGetter__(name);
-        }
-        var descriptor = getDescriptor(source, name);
-        var getter, setter;
-        if (allowMethod && typeof descriptor.value === "function") {
-          target[name] = getMethod(name);
-          continue;
-        }
-        var isEvent = isEventHandlerName(name);
-        if (isEvent) getter = scope.getEventHandlerGetter(name); else getter = getGetter(name);
-        if (descriptor.writable || descriptor.set || isBrokenSafari) {
-          if (isEvent) setter = scope.getEventHandlerSetter(name); else setter = getSetter(name);
-        }
-        var configurable = isBrokenSafari || descriptor.configurable;
-        defineProperty(target, name, {
-          get: getter,
-          set: setter,
-          configurable: configurable,
-          enumerable: descriptor.enumerable
-        });
-      }
-    }
-    function register(nativeConstructor, wrapperConstructor, opt_instance) {
-      var nativePrototype = nativeConstructor.prototype;
-      registerInternal(nativePrototype, wrapperConstructor, opt_instance);
-      mixinStatics(wrapperConstructor, nativeConstructor);
-    }
-    function registerInternal(nativePrototype, wrapperConstructor, opt_instance) {
-      var wrapperPrototype = wrapperConstructor.prototype;
-      assert(constructorTable.get(nativePrototype) === undefined);
-      constructorTable.set(nativePrototype, wrapperConstructor);
-      nativePrototypeTable.set(wrapperPrototype, nativePrototype);
-      addForwardingProperties(nativePrototype, wrapperPrototype);
-      if (opt_instance) registerInstanceProperties(wrapperPrototype, opt_instance);
-      defineNonEnumerableDataProperty(wrapperPrototype, "constructor", wrapperConstructor);
-      wrapperConstructor.prototype = wrapperPrototype;
-    }
-    function isWrapperFor(wrapperConstructor, nativeConstructor) {
-      return constructorTable.get(nativeConstructor.prototype) === wrapperConstructor;
-    }
-    function registerObject(object) {
-      var nativePrototype = Object.getPrototypeOf(object);
-      var superWrapperConstructor = getWrapperConstructor(nativePrototype);
-      var GeneratedWrapper = createWrapperConstructor(superWrapperConstructor);
-      registerInternal(nativePrototype, GeneratedWrapper, object);
-      return GeneratedWrapper;
-    }
-    function createWrapperConstructor(superWrapperConstructor) {
-      function GeneratedWrapper(node) {
-        superWrapperConstructor.call(this, node);
-      }
-      var p = Object.create(superWrapperConstructor.prototype);
-      p.constructor = GeneratedWrapper;
-      GeneratedWrapper.prototype = p;
-      return GeneratedWrapper;
-    }
-    function isWrapper(object) {
-      return object && object.__impl4cf1e782hg__;
-    }
-    function isNative(object) {
-      return !isWrapper(object);
-    }
-    function wrap(impl) {
-      if (impl === null) return null;
-      assert(isNative(impl));
-      return impl.__wrapper8e3dd93a60__ || (impl.__wrapper8e3dd93a60__ = new (getWrapperConstructor(impl))(impl));
-    }
-    function unwrap(wrapper) {
-      if (wrapper === null) return null;
-      assert(isWrapper(wrapper));
-      return wrapper.__impl4cf1e782hg__;
-    }
-    function unsafeUnwrap(wrapper) {
-      return wrapper.__impl4cf1e782hg__;
-    }
-    function setWrapper(impl, wrapper) {
-      wrapper.__impl4cf1e782hg__ = impl;
-      impl.__wrapper8e3dd93a60__ = wrapper;
-    }
-    function unwrapIfNeeded(object) {
-      return object && isWrapper(object) ? unwrap(object) : object;
-    }
-    function wrapIfNeeded(object) {
-      return object && !isWrapper(object) ? wrap(object) : object;
-    }
-    function rewrap(node, wrapper) {
-      if (wrapper === null) return;
-      assert(isNative(node));
-      assert(wrapper === undefined || isWrapper(wrapper));
-      node.__wrapper8e3dd93a60__ = wrapper;
-    }
-    var getterDescriptor = {
-      get: undefined,
-      configurable: true,
-      enumerable: true
-    };
-    function defineGetter(constructor, name, getter) {
-      getterDescriptor.get = getter;
-      defineProperty(constructor.prototype, name, getterDescriptor);
-    }
-    function defineWrapGetter(constructor, name) {
-      defineGetter(constructor, name, function() {
-        return wrap(this.__impl4cf1e782hg__[name]);
-      });
-    }
-    function forwardMethodsToWrapper(constructors, names) {
-      constructors.forEach(function(constructor) {
-        names.forEach(function(name) {
-          constructor.prototype[name] = function() {
-            var w = wrapIfNeeded(this);
-            return w[name].apply(w, arguments);
-          };
-        });
-      });
-    }
-    scope.assert = assert;
-    scope.constructorTable = constructorTable;
-    scope.defineGetter = defineGetter;
-    scope.defineWrapGetter = defineWrapGetter;
-    scope.forwardMethodsToWrapper = forwardMethodsToWrapper;
-    scope.isWrapper = isWrapper;
-    scope.isWrapperFor = isWrapperFor;
-    scope.mixin = mixin;
-    scope.nativePrototypeTable = nativePrototypeTable;
-    scope.oneOf = oneOf;
-    scope.registerObject = registerObject;
-    scope.registerWrapper = register;
-    scope.rewrap = rewrap;
-    scope.setWrapper = setWrapper;
-    scope.unsafeUnwrap = unsafeUnwrap;
-    scope.unwrap = unwrap;
-    scope.unwrapIfNeeded = unwrapIfNeeded;
-    scope.wrap = wrap;
-    scope.wrapIfNeeded = wrapIfNeeded;
-    scope.wrappers = wrappers;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    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;
-      }
-    };
-    scope.ArraySplice = ArraySplice;
-  })(window.ShadowDOMPolyfill);
-  (function(context) {
-    "use strict";
-    var OriginalMutationObserver = window.MutationObserver;
-    var callbacks = [];
-    var pending = false;
-    var timerFunc;
-    function handle() {
-      pending = false;
-      var copies = callbacks.slice(0);
-      callbacks = [];
-      for (var i = 0; i < copies.length; i++) {
-        (0, copies[i])();
-      }
-    }
-    if (OriginalMutationObserver) {
-      var counter = 1;
-      var observer = new OriginalMutationObserver(handle);
-      var textNode = document.createTextNode(counter);
-      observer.observe(textNode, {
-        characterData: true
-      });
-      timerFunc = function() {
-        counter = (counter + 1) % 2;
-        textNode.data = counter;
-      };
-    } else {
-      timerFunc = window.setTimeout;
-    }
-    function setEndOfMicrotask(func) {
-      callbacks.push(func);
-      if (pending) return;
-      pending = true;
-      timerFunc(handle, 0);
-    }
-    context.setEndOfMicrotask = setEndOfMicrotask;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var setEndOfMicrotask = scope.setEndOfMicrotask;
-    var wrapIfNeeded = scope.wrapIfNeeded;
-    var wrappers = scope.wrappers;
-    var registrationsTable = new WeakMap();
-    var globalMutationObservers = [];
-    var isScheduled = false;
-    function scheduleCallback(observer) {
-      if (observer.scheduled_) return;
-      observer.scheduled_ = true;
-      globalMutationObservers.push(observer);
-      if (isScheduled) return;
-      setEndOfMicrotask(notifyObservers);
-      isScheduled = true;
-    }
-    function notifyObservers() {
-      isScheduled = false;
-      while (globalMutationObservers.length) {
-        var notifyList = globalMutationObservers;
-        globalMutationObservers = [];
-        notifyList.sort(function(x, y) {
-          return x.uid_ - y.uid_;
-        });
-        for (var i = 0; i < notifyList.length; i++) {
-          var mo = notifyList[i];
-          mo.scheduled_ = false;
-          var queue = mo.takeRecords();
-          removeTransientObserversFor(mo);
-          if (queue.length) {
-            mo.callback_(queue, mo);
-          }
-        }
-      }
-    }
-    function MutationRecord(type, target) {
-      this.type = type;
-      this.target = target;
-      this.addedNodes = new wrappers.NodeList();
-      this.removedNodes = new wrappers.NodeList();
-      this.previousSibling = null;
-      this.nextSibling = null;
-      this.attributeName = null;
-      this.attributeNamespace = null;
-      this.oldValue = null;
-    }
-    function registerTransientObservers(ancestor, node) {
-      for (;ancestor; ancestor = ancestor.parentNode) {
-        var registrations = registrationsTable.get(ancestor);
-        if (!registrations) continue;
-        for (var i = 0; i < registrations.length; i++) {
-          var registration = registrations[i];
-          if (registration.options.subtree) registration.addTransientObserver(node);
-        }
-      }
-    }
-    function removeTransientObserversFor(observer) {
-      for (var i = 0; i < observer.nodes_.length; i++) {
-        var node = observer.nodes_[i];
-        var registrations = registrationsTable.get(node);
-        if (!registrations) return;
-        for (var j = 0; j < registrations.length; j++) {
-          var registration = registrations[j];
-          if (registration.observer === observer) registration.removeTransientObservers();
-        }
-      }
-    }
-    function enqueueMutation(target, type, data) {
-      var interestedObservers = Object.create(null);
-      var associatedStrings = Object.create(null);
-      for (var node = target; node; node = node.parentNode) {
-        var registrations = registrationsTable.get(node);
-        if (!registrations) continue;
-        for (var j = 0; j < registrations.length; j++) {
-          var registration = registrations[j];
-          var options = registration.options;
-          if (node !== target && !options.subtree) continue;
-          if (type === "attributes" && !options.attributes) continue;
-          if (type === "attributes" && options.attributeFilter && (data.namespace !== null || options.attributeFilter.indexOf(data.name) === -1)) {
-            continue;
-          }
-          if (type === "characterData" && !options.characterData) continue;
-          if (type === "childList" && !options.childList) continue;
-          var observer = registration.observer;
-          interestedObservers[observer.uid_] = observer;
-          if (type === "attributes" && options.attributeOldValue || type === "characterData" && options.characterDataOldValue) {
-            associatedStrings[observer.uid_] = data.oldValue;
-          }
-        }
-      }
-      for (var uid in interestedObservers) {
-        var observer = interestedObservers[uid];
-        var record = new MutationRecord(type, target);
-        if ("name" in data && "namespace" in data) {
-          record.attributeName = data.name;
-          record.attributeNamespace = data.namespace;
-        }
-        if (data.addedNodes) record.addedNodes = data.addedNodes;
-        if (data.removedNodes) record.removedNodes = data.removedNodes;
-        if (data.previousSibling) record.previousSibling = data.previousSibling;
-        if (data.nextSibling) record.nextSibling = data.nextSibling;
-        if (associatedStrings[uid] !== undefined) record.oldValue = associatedStrings[uid];
-        scheduleCallback(observer);
-        observer.records_.push(record);
-      }
-    }
-    var slice = Array.prototype.slice;
-    function MutationObserverOptions(options) {
-      this.childList = !!options.childList;
-      this.subtree = !!options.subtree;
-      if (!("attributes" in options) && ("attributeOldValue" in options || "attributeFilter" in options)) {
-        this.attributes = true;
-      } else {
-        this.attributes = !!options.attributes;
-      }
-      if ("characterDataOldValue" in options && !("characterData" in options)) this.characterData = true; else this.characterData = !!options.characterData;
-      if (!this.attributes && (options.attributeOldValue || "attributeFilter" in options) || !this.characterData && options.characterDataOldValue) {
-        throw new TypeError();
-      }
-      this.characterData = !!options.characterData;
-      this.attributeOldValue = !!options.attributeOldValue;
-      this.characterDataOldValue = !!options.characterDataOldValue;
-      if ("attributeFilter" in options) {
-        if (options.attributeFilter == null || typeof options.attributeFilter !== "object") {
-          throw new TypeError();
-        }
-        this.attributeFilter = slice.call(options.attributeFilter);
-      } else {
-        this.attributeFilter = null;
-      }
-    }
-    var uidCounter = 0;
-    function MutationObserver(callback) {
-      this.callback_ = callback;
-      this.nodes_ = [];
-      this.records_ = [];
-      this.uid_ = ++uidCounter;
-      this.scheduled_ = false;
-    }
-    MutationObserver.prototype = {
-      constructor: MutationObserver,
-      observe: function(target, options) {
-        target = wrapIfNeeded(target);
-        var newOptions = new MutationObserverOptions(options);
-        var registration;
-        var registrations = registrationsTable.get(target);
-        if (!registrations) registrationsTable.set(target, registrations = []);
-        for (var i = 0; i < registrations.length; i++) {
-          if (registrations[i].observer === this) {
-            registration = registrations[i];
-            registration.removeTransientObservers();
-            registration.options = newOptions;
-          }
-        }
-        if (!registration) {
-          registration = new Registration(this, target, newOptions);
-          registrations.push(registration);
-          this.nodes_.push(target);
-        }
-      },
-      disconnect: function() {
-        this.nodes_.forEach(function(node) {
-          var registrations = registrationsTable.get(node);
-          for (var i = 0; i < registrations.length; i++) {
-            var registration = registrations[i];
-            if (registration.observer === this) {
-              registrations.splice(i, 1);
-              break;
-            }
-          }
-        }, this);
-        this.records_ = [];
-      },
-      takeRecords: function() {
-        var copyOfRecords = this.records_;
-        this.records_ = [];
-        return copyOfRecords;
-      }
-    };
-    function Registration(observer, target, options) {
-      this.observer = observer;
-      this.target = target;
-      this.options = options;
-      this.transientObservedNodes = [];
-    }
-    Registration.prototype = {
-      addTransientObserver: function(node) {
-        if (node === this.target) return;
-        scheduleCallback(this.observer);
-        this.transientObservedNodes.push(node);
-        var registrations = registrationsTable.get(node);
-        if (!registrations) registrationsTable.set(node, registrations = []);
-        registrations.push(this);
-      },
-      removeTransientObservers: function() {
-        var transientObservedNodes = this.transientObservedNodes;
-        this.transientObservedNodes = [];
-        for (var i = 0; i < transientObservedNodes.length; i++) {
-          var node = transientObservedNodes[i];
-          var registrations = registrationsTable.get(node);
-          for (var j = 0; j < registrations.length; j++) {
-            if (registrations[j] === this) {
-              registrations.splice(j, 1);
-              break;
-            }
-          }
-        }
-      }
-    };
-    scope.enqueueMutation = enqueueMutation;
-    scope.registerTransientObservers = registerTransientObservers;
-    scope.wrappers.MutationObserver = MutationObserver;
-    scope.wrappers.MutationRecord = MutationRecord;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    function TreeScope(root, parent) {
-      this.root = root;
-      this.parent = parent;
-    }
-    TreeScope.prototype = {
-      get renderer() {
-        if (this.root instanceof scope.wrappers.ShadowRoot) {
-          return scope.getRendererForHost(this.root.host);
-        }
-        return null;
-      },
-      contains: function(treeScope) {
-        for (;treeScope; treeScope = treeScope.parent) {
-          if (treeScope === this) return true;
-        }
-        return false;
-      }
-    };
-    function setTreeScope(node, treeScope) {
-      if (node.treeScope_ !== treeScope) {
-        node.treeScope_ = treeScope;
-        for (var sr = node.shadowRoot; sr; sr = sr.olderShadowRoot) {
-          sr.treeScope_.parent = treeScope;
-        }
-        for (var child = node.firstChild; child; child = child.nextSibling) {
-          setTreeScope(child, treeScope);
-        }
-      }
-    }
-    function getTreeScope(node) {
-      if (node instanceof scope.wrappers.Window) {
-        debugger;
-      }
-      if (node.treeScope_) return node.treeScope_;
-      var parent = node.parentNode;
-      var treeScope;
-      if (parent) treeScope = getTreeScope(parent); else treeScope = new TreeScope(node, null);
-      return node.treeScope_ = treeScope;
-    }
-    scope.TreeScope = TreeScope;
-    scope.getTreeScope = getTreeScope;
-    scope.setTreeScope = setTreeScope;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
-    var getTreeScope = scope.getTreeScope;
-    var mixin = scope.mixin;
-    var registerWrapper = scope.registerWrapper;
-    var setWrapper = scope.setWrapper;
-    var unsafeUnwrap = scope.unsafeUnwrap;
-    var unwrap = scope.unwrap;
-    var wrap = scope.wrap;
-    var wrappers = scope.wrappers;
-    var wrappedFuns = new WeakMap();
-    var listenersTable = new WeakMap();
-    var handledEventsTable = new WeakMap();
-    var currentlyDispatchingEvents = new WeakMap();
-    var targetTable = new WeakMap();
-    var currentTargetTable = new WeakMap();
-    var relatedTargetTable = new WeakMap();
-    var eventPhaseTable = new WeakMap();
-    var stopPropagationTable = new WeakMap();
-    var stopImmediatePropagationTable = new WeakMap();
-    var eventHandlersTable = new WeakMap();
-    var eventPathTable = new WeakMap();
-    function isShadowRoot(node) {
-      return node instanceof wrappers.ShadowRoot;
-    }
-    function rootOfNode(node) {
-      return getTreeScope(node).root;
-    }
-    function getEventPath(node, event) {
-      var path = [];
-      var current = node;
-      path.push(current);
-      while (current) {
-        var destinationInsertionPoints = getDestinationInsertionPoints(current);
-        if (destinationInsertionPoints && destinationInsertionPoints.length > 0) {
-          for (var i = 0; i < destinationInsertionPoints.length; i++) {
-            var insertionPoint = destinationInsertionPoints[i];
-            if (isShadowInsertionPoint(insertionPoint)) {
-              var shadowRoot = rootOfNode(insertionPoint);
-              var olderShadowRoot = shadowRoot.olderShadowRoot;
-              if (olderShadowRoot) path.push(olderShadowRoot);
-            }
-            path.push(insertionPoint);
-          }
-          current = destinationInsertionPoints[destinationInsertionPoints.length - 1];
-        } else {
-          if (isShadowRoot(current)) {
-            if (inSameTree(node, current) && eventMustBeStopped(event)) {
-              break;
-            }
-            current = current.host;
-            path.push(current);
-          } else {
-            current = current.parentNode;
-            if (current) path.push(current);
-          }
-        }
-      }
-      return path;
-    }
-    function eventMustBeStopped(event) {
-      if (!event) return false;
-      switch (event.type) {
-       case "abort":
-       case "error":
-       case "select":
-       case "change":
-       case "load":
-       case "reset":
-       case "resize":
-       case "scroll":
-       case "selectstart":
-        return true;
-      }
-      return false;
-    }
-    function isShadowInsertionPoint(node) {
-      return node instanceof HTMLShadowElement;
-    }
-    function getDestinationInsertionPoints(node) {
-      return scope.getDestinationInsertionPoints(node);
-    }
-    function eventRetargetting(path, currentTarget) {
-      if (path.length === 0) return currentTarget;
-      if (currentTarget instanceof wrappers.Window) currentTarget = currentTarget.document;
-      var currentTargetTree = getTreeScope(currentTarget);
-      var originalTarget = path[0];
-      var originalTargetTree = getTreeScope(originalTarget);
-      var relativeTargetTree = lowestCommonInclusiveAncestor(currentTargetTree, originalTargetTree);
-      for (var i = 0; i < path.length; i++) {
-        var node = path[i];
-        if (getTreeScope(node) === relativeTargetTree) return node;
-      }
-      return path[path.length - 1];
-    }
-    function getTreeScopeAncestors(treeScope) {
-      var ancestors = [];
-      for (;treeScope; treeScope = treeScope.parent) {
-        ancestors.push(treeScope);
-      }
-      return ancestors;
-    }
-    function lowestCommonInclusiveAncestor(tsA, tsB) {
-      var ancestorsA = getTreeScopeAncestors(tsA);
-      var ancestorsB = getTreeScopeAncestors(tsB);
-      var result = null;
-      while (ancestorsA.length > 0 && ancestorsB.length > 0) {
-        var a = ancestorsA.pop();
-        var b = ancestorsB.pop();
-        if (a === b) result = a; else break;
-      }
-      return result;
-    }
-    function getTreeScopeRoot(ts) {
-      if (!ts.parent) return ts;
-      return getTreeScopeRoot(ts.parent);
-    }
-    function relatedTargetResolution(event, currentTarget, relatedTarget) {
-      if (currentTarget instanceof wrappers.Window) currentTarget = currentTarget.document;
-      var currentTargetTree = getTreeScope(currentTarget);
-      var relatedTargetTree = getTreeScope(relatedTarget);
-      var relatedTargetEventPath = getEventPath(relatedTarget, event);
-      var lowestCommonAncestorTree;
-      var lowestCommonAncestorTree = lowestCommonInclusiveAncestor(currentTargetTree, relatedTargetTree);
-      if (!lowestCommonAncestorTree) lowestCommonAncestorTree = relatedTargetTree.root;
-      for (var commonAncestorTree = lowestCommonAncestorTree; commonAncestorTree; commonAncestorTree = commonAncestorTree.parent) {
-        var adjustedRelatedTarget;
-        for (var i = 0; i < relatedTargetEventPath.length; i++) {
-          var node = relatedTargetEventPath[i];
-          if (getTreeScope(node) === commonAncestorTree) return node;
-        }
-      }
-      return null;
-    }
-    function inSameTree(a, b) {
-      return getTreeScope(a) === getTreeScope(b);
-    }
-    var NONE = 0;
-    var CAPTURING_PHASE = 1;
-    var AT_TARGET = 2;
-    var BUBBLING_PHASE = 3;
-    var pendingError;
-    function dispatchOriginalEvent(originalEvent) {
-      if (handledEventsTable.get(originalEvent)) return;
-      handledEventsTable.set(originalEvent, true);
-      dispatchEvent(wrap(originalEvent), wrap(originalEvent.target));
-      if (pendingError) {
-        var err = pendingError;
-        pendingError = null;
-        throw err;
-      }
-    }
-    function isLoadLikeEvent(event) {
-      switch (event.type) {
-       case "load":
-       case "beforeunload":
-       case "unload":
-        return true;
-      }
-      return false;
-    }
-    function dispatchEvent(event, originalWrapperTarget) {
-      if (currentlyDispatchingEvents.get(event)) throw new Error("InvalidStateError");
-      currentlyDispatchingEvents.set(event, true);
-      scope.renderAllPending();
-      var eventPath;
-      var overrideTarget;
-      var win;
-      if (isLoadLikeEvent(event) && !event.bubbles) {
-        var doc = originalWrapperTarget;
-        if (doc instanceof wrappers.Document && (win = doc.defaultView)) {
-          overrideTarget = doc;
-          eventPath = [];
-        }
-      }
-      if (!eventPath) {
-        if (originalWrapperTarget instanceof wrappers.Window) {
-          win = originalWrapperTarget;
-          eventPath = [];
-        } else {
-          eventPath = getEventPath(originalWrapperTarget, event);
-          if (!isLoadLikeEvent(event)) {
-            var doc = eventPath[eventPath.length - 1];
-            if (doc instanceof wrappers.Document) win = doc.defaultView;
-          }
-        }
-      }
-      eventPathTable.set(event, eventPath);
-      if (dispatchCapturing(event, eventPath, win, overrideTarget)) {
-        if (dispatchAtTarget(event, eventPath, win, overrideTarget)) {
-          dispatchBubbling(event, eventPath, win, overrideTarget);
-        }
-      }
-      eventPhaseTable.set(event, NONE);
-      currentTargetTable.delete(event, null);
-      currentlyDispatchingEvents.delete(event);
-      return event.defaultPrevented;
-    }
-    function dispatchCapturing(event, eventPath, win, overrideTarget) {
-      var phase = CAPTURING_PHASE;
-      if (win) {
-        if (!invoke(win, event, phase, eventPath, overrideTarget)) return false;
-      }
-      for (var i = eventPath.length - 1; i > 0; i--) {
-        if (!invoke(eventPath[i], event, phase, eventPath, overrideTarget)) return false;
-      }
-      return true;
-    }
-    function dispatchAtTarget(event, eventPath, win, overrideTarget) {
-      var phase = AT_TARGET;
-      var currentTarget = eventPath[0] || win;
-      return invoke(currentTarget, event, phase, eventPath, overrideTarget);
-    }
-    function dispatchBubbling(event, eventPath, win, overrideTarget) {
-      var phase = BUBBLING_PHASE;
-      for (var i = 1; i < eventPath.length; i++) {
-        if (!invoke(eventPath[i], event, phase, eventPath, overrideTarget)) return;
-      }
-      if (win && eventPath.length > 0) {
-        invoke(win, event, phase, eventPath, overrideTarget);
-      }
-    }
-    function invoke(currentTarget, event, phase, eventPath, overrideTarget) {
-      var listeners = listenersTable.get(currentTarget);
-      if (!listeners) return true;
-      var target = overrideTarget || eventRetargetting(eventPath, currentTarget);
-      if (target === currentTarget) {
-        if (phase === CAPTURING_PHASE) return true;
-        if (phase === BUBBLING_PHASE) phase = AT_TARGET;
-      } else if (phase === BUBBLING_PHASE && !event.bubbles) {
-        return true;
-      }
-      if ("relatedTarget" in event) {
-        var originalEvent = unwrap(event);
-        var unwrappedRelatedTarget = originalEvent.relatedTarget;
-        if (unwrappedRelatedTarget) {
-          if (unwrappedRelatedTarget instanceof Object && unwrappedRelatedTarget.addEventListener) {
-            var relatedTarget = wrap(unwrappedRelatedTarget);
-            var adjusted = relatedTargetResolution(event, currentTarget, relatedTarget);
-            if (adjusted === target) return true;
-          } else {
-            adjusted = null;
-          }
-          relatedTargetTable.set(event, adjusted);
-        }
-      }
-      eventPhaseTable.set(event, phase);
-      var type = event.type;
-      var anyRemoved = false;
-      targetTable.set(event, target);
-      currentTargetTable.set(event, currentTarget);
-      listeners.depth++;
-      for (var i = 0, len = listeners.length; i < len; i++) {
-        var listener = listeners[i];
-        if (listener.removed) {
-          anyRemoved = true;
-          continue;
-        }
-        if (listener.type !== type || !listener.capture && phase === CAPTURING_PHASE || listener.capture && phase === BUBBLING_PHASE) {
-          continue;
-        }
-        try {
-          if (typeof listener.handler === "function") listener.handler.call(currentTarget, event); else listener.handler.handleEvent(event);
-          if (stopImmediatePropagationTable.get(event)) return false;
-        } catch (ex) {
-          if (!pendingError) pendingError = ex;
-        }
-      }
-      listeners.depth--;
-      if (anyRemoved && listeners.depth === 0) {
-        var copy = listeners.slice();
-        listeners.length = 0;
-        for (var i = 0; i < copy.length; i++) {
-          if (!copy[i].removed) listeners.push(copy[i]);
-        }
-      }
-      return !stopPropagationTable.get(event);
-    }
-    function Listener(type, handler, capture) {
-      this.type = type;
-      this.handler = handler;
-      this.capture = Boolean(capture);
-    }
-    Listener.prototype = {
-      equals: function(that) {
-        return this.handler === that.handler && this.type === that.type && this.capture === that.capture;
-      },
-      get removed() {
-        return this.handler === null;
-      },
-      remove: function() {
-        this.handler = null;
-      }
-    };
-    var OriginalEvent = window.Event;
-    OriginalEvent.prototype.polymerBlackList_ = {
-      returnValue: true,
-      keyLocation: true
-    };
-    function Event(type, options) {
-      if (type instanceof OriginalEvent) {
-        var impl = type;
-        if (!OriginalBeforeUnloadEvent && impl.type === "beforeunload" && !(this instanceof BeforeUnloadEvent)) {
-          return new BeforeUnloadEvent(impl);
-        }
-        setWrapper(impl, this);
-      } else {
-        return wrap(constructEvent(OriginalEvent, "Event", type, options));
-      }
-    }
-    Event.prototype = {
-      get target() {
-        return targetTable.get(this);
-      },
-      get currentTarget() {
-        return currentTargetTable.get(this);
-      },
-      get eventPhase() {
-        return eventPhaseTable.get(this);
-      },
-      get path() {
-        var eventPath = eventPathTable.get(this);
-        if (!eventPath) return [];
-        return eventPath.slice();
-      },
-      stopPropagation: function() {
-        stopPropagationTable.set(this, true);
-      },
-      stopImmediatePropagation: function() {
-        stopPropagationTable.set(this, true);
-        stopImmediatePropagationTable.set(this, true);
-      }
-    };
-    registerWrapper(OriginalEvent, Event, document.createEvent("Event"));
-    function unwrapOptions(options) {
-      if (!options || !options.relatedTarget) return options;
-      return Object.create(options, {
-        relatedTarget: {
-          value: unwrap(options.relatedTarget)
-        }
-      });
-    }
-    function registerGenericEvent(name, SuperEvent, prototype) {
-      var OriginalEvent = window[name];
-      var GenericEvent = function(type, options) {
-        if (type instanceof OriginalEvent) setWrapper(type, this); else return wrap(constructEvent(OriginalEvent, name, type, options));
-      };
-      GenericEvent.prototype = Object.create(SuperEvent.prototype);
-      if (prototype) mixin(GenericEvent.prototype, prototype);
-      if (OriginalEvent) {
-        try {
-          registerWrapper(OriginalEvent, GenericEvent, new OriginalEvent("temp"));
-        } catch (ex) {
-          registerWrapper(OriginalEvent, GenericEvent, document.createEvent(name));
-        }
-      }
-      return GenericEvent;
-    }
-    var UIEvent = registerGenericEvent("UIEvent", Event);
-    var CustomEvent = registerGenericEvent("CustomEvent", Event);
-    var relatedTargetProto = {
-      get relatedTarget() {
-        var relatedTarget = relatedTargetTable.get(this);
-        if (relatedTarget !== undefined) return relatedTarget;
-        return wrap(unwrap(this).relatedTarget);
-      }
-    };
-    function getInitFunction(name, relatedTargetIndex) {
-      return function() {
-        arguments[relatedTargetIndex] = unwrap(arguments[relatedTargetIndex]);
-        var impl = unwrap(this);
-        impl[name].apply(impl, arguments);
-      };
-    }
-    var mouseEventProto = mixin({
-      initMouseEvent: getInitFunction("initMouseEvent", 14)
-    }, relatedTargetProto);
-    var focusEventProto = mixin({
-      initFocusEvent: getInitFunction("initFocusEvent", 5)
-    }, relatedTargetProto);
-    var MouseEvent = registerGenericEvent("MouseEvent", UIEvent, mouseEventProto);
-    var FocusEvent = registerGenericEvent("FocusEvent", UIEvent, focusEventProto);
-    var defaultInitDicts = Object.create(null);
-    var supportsEventConstructors = function() {
-      try {
-        new window.FocusEvent("focus");
-      } catch (ex) {
-        return false;
-      }
-      return true;
-    }();
-    function constructEvent(OriginalEvent, name, type, options) {
-      if (supportsEventConstructors) return new OriginalEvent(type, unwrapOptions(options));
-      var event = unwrap(document.createEvent(name));
-      var defaultDict = defaultInitDicts[name];
-      var args = [ type ];
-      Object.keys(defaultDict).forEach(function(key) {
-        var v = options != null && key in options ? options[key] : defaultDict[key];
-        if (key === "relatedTarget") v = unwrap(v);
-        args.push(v);
-      });
-      event["init" + name].apply(event, args);
-      return event;
-    }
-    if (!supportsEventConstructors) {
-      var configureEventConstructor = function(name, initDict, superName) {
-        if (superName) {
-          var superDict = defaultInitDicts[superName];
-          initDict = mixin(mixin({}, superDict), initDict);
-        }
-        defaultInitDicts[name] = initDict;
-      };
-      configureEventConstructor("Event", {
-        bubbles: false,
-        cancelable: false
-      });
-      configureEventConstructor("CustomEvent", {
-        detail: null
-      }, "Event");
-      configureEventConstructor("UIEvent", {
-        view: null,
-        detail: 0
-      }, "Event");
-      configureEventConstructor("MouseEvent", {
-        screenX: 0,
-        screenY: 0,
-        clientX: 0,
-        clientY: 0,
-        ctrlKey: false,
-        altKey: false,
-        shiftKey: false,
-        metaKey: false,
-        button: 0,
-        relatedTarget: null
-      }, "UIEvent");
-      configureEventConstructor("FocusEvent", {
-        relatedTarget: null
-      }, "UIEvent");
-    }
-    var OriginalBeforeUnloadEvent = window.BeforeUnloadEvent;
-    function BeforeUnloadEvent(impl) {
-      Event.call(this, impl);
-    }
-    BeforeUnloadEvent.prototype = Object.create(Event.prototype);
-    mixin(BeforeUnloadEvent.prototype, {
-      get returnValue() {
-        return unsafeUnwrap(this).returnValue;
-      },
-      set returnValue(v) {
-        unsafeUnwrap(this).returnValue = v;
-      }
-    });
-    if (OriginalBeforeUnloadEvent) registerWrapper(OriginalBeforeUnloadEvent, BeforeUnloadEvent);
-    function isValidListener(fun) {
-      if (typeof fun === "function") return true;
-      return fun && fun.handleEvent;
-    }
-    function isMutationEvent(type) {
-      switch (type) {
-       case "DOMAttrModified":
-       case "DOMAttributeNameChanged":
-       case "DOMCharacterDataModified":
-       case "DOMElementNameChanged":
-       case "DOMNodeInserted":
-       case "DOMNodeInsertedIntoDocument":
-       case "DOMNodeRemoved":
-       case "DOMNodeRemovedFromDocument":
-       case "DOMSubtreeModified":
-        return true;
-      }
-      return false;
-    }
-    var OriginalEventTarget = window.EventTarget;
-    function EventTarget(impl) {
-      setWrapper(impl, this);
-    }
-    var methodNames = [ "addEventListener", "removeEventListener", "dispatchEvent" ];
-    [ Node, Window ].forEach(function(constructor) {
-      var p = constructor.prototype;
-      methodNames.forEach(function(name) {
-        Object.defineProperty(p, name + "_", {
-          value: p[name]
-        });
-      });
-    });
-    function getTargetToListenAt(wrapper) {
-      if (wrapper instanceof wrappers.ShadowRoot) wrapper = wrapper.host;
-      return unwrap(wrapper);
-    }
-    EventTarget.prototype = {
-      addEventListener: function(type, fun, capture) {
-        if (!isValidListener(fun) || isMutationEvent(type)) return;
-        var listener = new Listener(type, fun, capture);
-        var listeners = listenersTable.get(this);
-        if (!listeners) {
-          listeners = [];
-          listeners.depth = 0;
-          listenersTable.set(this, listeners);
-        } else {
-          for (var i = 0; i < listeners.length; i++) {
-            if (listener.equals(listeners[i])) return;
-          }
-        }
-        listeners.push(listener);
-        var target = getTargetToListenAt(this);
-        target.addEventListener_(type, dispatchOriginalEvent, true);
-      },
-      removeEventListener: function(type, fun, capture) {
-        capture = Boolean(capture);
-        var listeners = listenersTable.get(this);
-        if (!listeners) return;
-        var count = 0, found = false;
-        for (var i = 0; i < listeners.length; i++) {
-          if (listeners[i].type === type && listeners[i].capture === capture) {
-            count++;
-            if (listeners[i].handler === fun) {
-              found = true;
-              listeners[i].remove();
-            }
-          }
-        }
-        if (found && count === 1) {
-          var target = getTargetToListenAt(this);
-          target.removeEventListener_(type, dispatchOriginalEvent, true);
-        }
-      },
-      dispatchEvent: function(event) {
-        var nativeEvent = unwrap(event);
-        var eventType = nativeEvent.type;
-        handledEventsTable.set(nativeEvent, false);
-        scope.renderAllPending();
-        var tempListener;
-        if (!hasListenerInAncestors(this, eventType)) {
-          tempListener = function() {};
-          this.addEventListener(eventType, tempListener, true);
-        }
-        try {
-          return unwrap(this).dispatchEvent_(nativeEvent);
-        } finally {
-          if (tempListener) this.removeEventListener(eventType, tempListener, true);
-        }
-      }
-    };
-    function hasListener(node, type) {
-      var listeners = listenersTable.get(node);
-      if (listeners) {
-        for (var i = 0; i < listeners.length; i++) {
-          if (!listeners[i].removed && listeners[i].type === type) return true;
-        }
-      }
-      return false;
-    }
-    function hasListenerInAncestors(target, type) {
-      for (var node = unwrap(target); node; node = node.parentNode) {
-        if (hasListener(wrap(node), type)) return true;
-      }
-      return false;
-    }
-    if (OriginalEventTarget) registerWrapper(OriginalEventTarget, EventTarget);
-    function wrapEventTargetMethods(constructors) {
-      forwardMethodsToWrapper(constructors, methodNames);
-    }
-    var originalElementFromPoint = document.elementFromPoint;
-    function elementFromPoint(self, document, x, y) {
-      scope.renderAllPending();
-      var element = wrap(originalElementFromPoint.call(unsafeUnwrap(document), x, y));
-      if (!element) return null;
-      var path = getEventPath(element, null);
-      var idx = path.lastIndexOf(self);
-      if (idx == -1) return null; else path = path.slice(0, idx);
-      return eventRetargetting(path, self);
-    }
-    function getEventHandlerGetter(name) {
-      return function() {
-        var inlineEventHandlers = eventHandlersTable.get(this);
-        return inlineEventHandlers && inlineEventHandlers[name] && inlineEventHandlers[name].value || null;
-      };
-    }
-    function getEventHandlerSetter(name) {
-      var eventType = name.slice(2);
-      return function(value) {
-        var inlineEventHandlers = eventHandlersTable.get(this);
-        if (!inlineEventHandlers) {
-          inlineEventHandlers = Object.create(null);
-          eventHandlersTable.set(this, inlineEventHandlers);
-        }
-        var old = inlineEventHandlers[name];
-        if (old) this.removeEventListener(eventType, old.wrapped, false);
-        if (typeof value === "function") {
-          var wrapped = function(e) {
-            var rv = value.call(this, e);
-            if (rv === false) e.preventDefault(); else if (name === "onbeforeunload" && typeof rv === "string") e.returnValue = rv;
-          };
-          this.addEventListener(eventType, wrapped, false);
-          inlineEventHandlers[name] = {
-            value: value,
-            wrapped: wrapped
-          };
-        }
-      };
-    }
-    scope.elementFromPoint = elementFromPoint;
-    scope.getEventHandlerGetter = getEventHandlerGetter;
-    scope.getEventHandlerSetter = getEventHandlerSetter;
-    scope.wrapEventTargetMethods = wrapEventTargetMethods;
-    scope.wrappers.BeforeUnloadEvent = BeforeUnloadEvent;
-    scope.wrappers.CustomEvent = CustomEvent;
-    scope.wrappers.Event = Event;
-    scope.wrappers.EventTarget = EventTarget;
-    scope.wrappers.FocusEvent = FocusEvent;
-    scope.wrappers.MouseEvent = MouseEvent;
-    scope.wrappers.UIEvent = UIEvent;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var UIEvent = scope.wrappers.UIEvent;
-    var mixin = scope.mixin;
-    var registerWrapper = scope.registerWrapper;
-    var setWrapper = scope.setWrapper;
-    var unsafeUnwrap = scope.unsafeUnwrap;
-    var wrap = scope.wrap;
-    var OriginalTouchEvent = window.TouchEvent;
-    if (!OriginalTouchEvent) return;
-    var nativeEvent;
-    try {
-      nativeEvent = document.createEvent("TouchEvent");
-    } catch (ex) {
-      return;
-    }
-    var nonEnumDescriptor = {
-      enumerable: false
-    };
-    function nonEnum(obj, prop) {
-      Object.defineProperty(obj, prop, nonEnumDescriptor);
-    }
-    function Touch(impl) {
-      setWrapper(impl, this);
-    }
-    Touch.prototype = {
-      get target() {
-        return wrap(unsafeUnwrap(this).target);
-      }
-    };
-    var descr = {
-      configurable: true,
-      enumerable: true,
-      get: null
-    };
-    [ "clientX", "clientY", "screenX", "screenY", "pageX", "pageY", "identifier", "webkitRadiusX", "webkitRadiusY", "webkitRotationAngle", "webkitForce" ].forEach(function(name) {
-      descr.get = function() {
-        return unsafeUnwrap(this)[name];
-      };
-      Object.defineProperty(Touch.prototype, name, descr);
-    });
-    function TouchList() {
-      this.length = 0;
-      nonEnum(this, "length");
-    }
-    TouchList.prototype = {
-      item: function(index) {
-        return this[index];
-      }
-    };
-    function wrapTouchList(nativeTouchList) {
-      var list = new TouchList();
-      for (var i = 0; i < nativeTouchList.length; i++) {
-        list[i] = new Touch(nativeTouchList[i]);
-      }
-      list.length = i;
-      return list;
-    }
-    function TouchEvent(impl) {
-      UIEvent.call(this, impl);
-    }
-    TouchEvent.prototype = Object.create(UIEvent.prototype);
-    mixin(TouchEvent.prototype, {
-      get touches() {
-        return wrapTouchList(unsafeUnwrap(this).touches);
-      },
-      get targetTouches() {
-        return wrapTouchList(unsafeUnwrap(this).targetTouches);
-      },
-      get changedTouches() {
-        return wrapTouchList(unsafeUnwrap(this).changedTouches);
-      },
-      initTouchEvent: function() {
-        throw new Error("Not implemented");
-      }
-    });
-    registerWrapper(OriginalTouchEvent, TouchEvent, nativeEvent);
-    scope.wrappers.Touch = Touch;
-    scope.wrappers.TouchEvent = TouchEvent;
-    scope.wrappers.TouchList = TouchList;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var unsafeUnwrap = scope.unsafeUnwrap;
-    var wrap = scope.wrap;
-    var nonEnumDescriptor = {
-      enumerable: false
-    };
-    function nonEnum(obj, prop) {
-      Object.defineProperty(obj, prop, nonEnumDescriptor);
-    }
-    function NodeList() {
-      this.length = 0;
-      nonEnum(this, "length");
-    }
-    NodeList.prototype = {
-      item: function(index) {
-        return this[index];
-      }
-    };
-    nonEnum(NodeList.prototype, "item");
-    function wrapNodeList(list) {
-      if (list == null) return list;
-      var wrapperList = new NodeList();
-      for (var i = 0, length = list.length; i < length; i++) {
-        wrapperList[i] = wrap(list[i]);
-      }
-      wrapperList.length = length;
-      return wrapperList;
-    }
-    function addWrapNodeListMethod(wrapperConstructor, name) {
-      wrapperConstructor.prototype[name] = function() {
-        return wrapNodeList(unsafeUnwrap(this)[name].apply(unsafeUnwrap(this), arguments));
-      };
-    }
-    scope.wrappers.NodeList = NodeList;
-    scope.addWrapNodeListMethod = addWrapNodeListMethod;
-    scope.wrapNodeList = wrapNodeList;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    scope.wrapHTMLCollection = scope.wrapNodeList;
-    scope.wrappers.HTMLCollection = scope.wrappers.NodeList;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var EventTarget = scope.wrappers.EventTarget;
-    var NodeList = scope.wrappers.NodeList;
-    var TreeScope = scope.TreeScope;
-    var assert = scope.assert;
-    var defineWrapGetter = scope.defineWrapGetter;
-    var enqueueMutation = scope.enqueueMutation;
-    var getTreeScope = scope.getTreeScope;
-    var isWrapper = scope.isWrapper;
-    var mixin = scope.mixin;
-    var registerTransientObservers = scope.registerTransientObservers;
-    var registerWrapper = scope.registerWrapper;
-    var setTreeScope = scope.setTreeScope;
-    var unsafeUnwrap = scope.unsafeUnwrap;
-    var unwrap = scope.unwrap;
-    var unwrapIfNeeded = scope.unwrapIfNeeded;
-    var wrap = scope.wrap;
-    var wrapIfNeeded = scope.wrapIfNeeded;
-    var wrappers = scope.wrappers;
-    function assertIsNodeWrapper(node) {
-      assert(node instanceof Node);
-    }
-    function createOneElementNodeList(node) {
-      var nodes = new NodeList();
-      nodes[0] = node;
-      nodes.length = 1;
-      return nodes;
-    }
-    var surpressMutations = false;
-    function enqueueRemovalForInsertedNodes(node, parent, nodes) {
-      enqueueMutation(parent, "childList", {
-        removedNodes: nodes,
-        previousSibling: node.previousSibling,
-        nextSibling: node.nextSibling
-      });
-    }
-    function enqueueRemovalForInsertedDocumentFragment(df, nodes) {
-      enqueueMutation(df, "childList", {
-        removedNodes: nodes
-      });
-    }
-    function collectNodes(node, parentNode, previousNode, nextNode) {
-      if (node instanceof DocumentFragment) {
-        var nodes = collectNodesForDocumentFragment(node);
-        surpressMutations = true;
-        for (var i = nodes.length - 1; i >= 0; i--) {
-          node.removeChild(nodes[i]);
-          nodes[i].parentNode_ = parentNode;
-        }
-        surpressMutations = false;
-        for (var i = 0; i < nodes.length; i++) {
-          nodes[i].previousSibling_ = nodes[i - 1] || previousNode;
-          nodes[i].nextSibling_ = nodes[i + 1] || nextNode;
-        }
-        if (previousNode) previousNode.nextSibling_ = nodes[0];
-        if (nextNode) nextNode.previousSibling_ = nodes[nodes.length - 1];
-        return nodes;
-      }
-      var nodes = createOneElementNodeList(node);
-      var oldParent = node.parentNode;
-      if (oldParent) {
-        oldParent.removeChild(node);
-      }
-      node.parentNode_ = parentNode;
-      node.previousSibling_ = previousNode;
-      node.nextSibling_ = nextNode;
-      if (previousNode) previousNode.nextSibling_ = node;
-      if (nextNode) nextNode.previousSibling_ = node;
-      return nodes;
-    }
-    function collectNodesNative(node) {
-      if (node instanceof DocumentFragment) return collectNodesForDocumentFragment(node);
-      var nodes = createOneElementNodeList(node);
-      var oldParent = node.parentNode;
-      if (oldParent) enqueueRemovalForInsertedNodes(node, oldParent, nodes);
-      return nodes;
-    }
-    function collectNodesForDocumentFragment(node) {
-      var nodes = new NodeList();
-      var i = 0;
-      for (var child = node.firstChild; child; child = child.nextSibling) {
-        nodes[i++] = child;
-      }
-      nodes.length = i;
-      enqueueRemovalForInsertedDocumentFragment(node, nodes);
-      return nodes;
-    }
-    function snapshotNodeList(nodeList) {
-      return nodeList;
-    }
-    function nodeWasAdded(node, treeScope) {
-      setTreeScope(node, treeScope);
-      node.nodeIsInserted_();
-    }
-    function nodesWereAdded(nodes, parent) {
-      var treeScope = getTreeScope(parent);
-      for (var i = 0; i < nodes.length; i++) {
-        nodeWasAdded(nodes[i], treeScope);
-      }
-    }
-    function nodeWasRemoved(node) {
-      setTreeScope(node, new TreeScope(node, null));
-    }
-    function nodesWereRemoved(nodes) {
-      for (var i = 0; i < nodes.length; i++) {
-        nodeWasRemoved(nodes[i]);
-      }
-    }
-    function ensureSameOwnerDocument(parent, child) {
-      var ownerDoc = parent.nodeType === Node.DOCUMENT_NODE ? parent : parent.ownerDocument;
-      if (ownerDoc !== child.ownerDocument) ownerDoc.adoptNode(child);
-    }
-    function adoptNodesIfNeeded(owner, nodes) {
-      if (!nodes.length) return;
-      var ownerDoc = owner.ownerDocument;
-      if (ownerDoc === nodes[0].ownerDocument) return;
-      for (var i = 0; i < nodes.length; i++) {
-        scope.adoptNodeNoRemove(nodes[i], ownerDoc);
-      }
-    }
-    function unwrapNodesForInsertion(owner, nodes) {
-      adoptNodesIfNeeded(owner, nodes);
-      var length = nodes.length;
-      if (length === 1) return unwrap(nodes[0]);
-      var df = unwrap(owner.ownerDocument.createDocumentFragment());
-      for (var i = 0; i < length; i++) {
-        df.appendChild(unwrap(nodes[i]));
-      }
-      return df;
-    }
-    function clearChildNodes(wrapper) {
-      if (wrapper.firstChild_ !== undefined) {
-        var child = wrapper.firstChild_;
-        while (child) {
-          var tmp = child;
-          child = child.nextSibling_;
-          tmp.parentNode_ = tmp.previousSibling_ = tmp.nextSibling_ = undefined;
-        }
-      }
-      wrapper.firstChild_ = wrapper.lastChild_ = undefined;
-    }
-    function removeAllChildNodes(wrapper) {
-      if (wrapper.invalidateShadowRenderer()) {
-        var childWrapper = wrapper.firstChild;
-        while (childWrapper) {
-          assert(childWrapper.parentNode === wrapper);
-          var nextSibling = childWrapper.nextSibling;
-          var childNode = unwrap(childWrapper);
-          var parentNode = childNode.parentNode;
-          if (parentNode) originalRemoveChild.call(parentNode, childNode);
-          childWrapper.previousSibling_ = childWrapper.nextSibling_ = childWrapper.parentNode_ = null;
-          childWrapper = nextSibling;
-        }
-        wrapper.firstChild_ = wrapper.lastChild_ = null;
-      } else {
-        var node = unwrap(wrapper);
-        var child = node.firstChild;
-        var nextSibling;
-        while (child) {
-          nextSibling = child.nextSibling;
-          originalRemoveChild.call(node, child);
-          child = nextSibling;
-        }
-      }
-    }
-    function invalidateParent(node) {
-      var p = node.parentNode;
-      return p && p.invalidateShadowRenderer();
-    }
-    function cleanupNodes(nodes) {
-      for (var i = 0, n; i < nodes.length; i++) {
-        n = nodes[i];
-        n.parentNode.removeChild(n);
-      }
-    }
-    var originalImportNode = document.importNode;
-    var originalCloneNode = window.Node.prototype.cloneNode;
-    function cloneNode(node, deep, opt_doc) {
-      var clone;
-      if (opt_doc) clone = wrap(originalImportNode.call(opt_doc, unsafeUnwrap(node), false)); else clone = wrap(originalCloneNode.call(unsafeUnwrap(node), false));
-      if (deep) {
-        for (var child = node.firstChild; child; child = child.nextSibling) {
-          clone.appendChild(cloneNode(child, true, opt_doc));
-        }
-        if (node instanceof wrappers.HTMLTemplateElement) {
-          var cloneContent = clone.content;
-          for (var child = node.content.firstChild; child; child = child.nextSibling) {
-            cloneContent.appendChild(cloneNode(child, true, opt_doc));
-          }
-        }
-      }
-      return clone;
-    }
-    function contains(self, child) {
-      if (!child || getTreeScope(self) !== getTreeScope(child)) return false;
-      for (var node = child; node; node = node.parentNode) {
-        if (node === self) return true;
-      }
-      return false;
-    }
-    var OriginalNode = window.Node;
-    function Node(original) {
-      assert(original instanceof OriginalNode);
-      EventTarget.call(this, original);
-      this.parentNode_ = undefined;
-      this.firstChild_ = undefined;
-      this.lastChild_ = undefined;
-      this.nextSibling_ = undefined;
-      this.previousSibling_ = undefined;
-      this.treeScope_ = undefined;
-    }
-    var OriginalDocumentFragment = window.DocumentFragment;
-    var originalAppendChild = OriginalNode.prototype.appendChild;
-    var originalCompareDocumentPosition = OriginalNode.prototype.compareDocumentPosition;
-    var originalInsertBefore = OriginalNode.prototype.insertBefore;
-    var originalRemoveChild = OriginalNode.prototype.removeChild;
-    var originalReplaceChild = OriginalNode.prototype.replaceChild;
-    var isIe = /Trident|Edge/.test(navigator.userAgent);
-    var removeChildOriginalHelper = isIe ? function(parent, child) {
-      try {
-        originalRemoveChild.call(parent, child);
-      } catch (ex) {
-        if (!(parent instanceof OriginalDocumentFragment)) throw ex;
-      }
-    } : function(parent, child) {
-      originalRemoveChild.call(parent, child);
-    };
-    Node.prototype = Object.create(EventTarget.prototype);
-    mixin(Node.prototype, {
-      appendChild: function(childWrapper) {
-        return this.insertBefore(childWrapper, null);
-      },
-      insertBefore: function(childWrapper, refWrapper) {
-        assertIsNodeWrapper(childWrapper);
-        var refNode;
-        if (refWrapper) {
-          if (isWrapper(refWrapper)) {
-            refNode = unwrap(refWrapper);
-          } else {
-            refNode = refWrapper;
-            refWrapper = wrap(refNode);
-          }
-        } else {
-          refWrapper = null;
-          refNode = null;
-        }
-        refWrapper && assert(refWrapper.parentNode === this);
-        var nodes;
-        var previousNode = refWrapper ? refWrapper.previousSibling : this.lastChild;
-        var useNative = !this.invalidateShadowRenderer() && !invalidateParent(childWrapper);
-        if (useNative) nodes = collectNodesNative(childWrapper); else nodes = collectNodes(childWrapper, this, previousNode, refWrapper);
-        if (useNative) {
-          ensureSameOwnerDocument(this, childWrapper);
-          clearChildNodes(this);
-          originalInsertBefore.call(unsafeUnwrap(this), unwrap(childWrapper), refNode);
-        } else {
-          if (!previousNode) this.firstChild_ = nodes[0];
-          if (!refWrapper) {
-            this.lastChild_ = nodes[nodes.length - 1];
-            if (this.firstChild_ === undefined) this.firstChild_ = this.firstChild;
-          }
-          var parentNode = refNode ? refNode.parentNode : unsafeUnwrap(this);
-          if (parentNode) {
-            originalInsertBefore.call(parentNode, unwrapNodesForInsertion(this, nodes), refNode);
-          } else {
-            adoptNodesIfNeeded(this, nodes);
-          }
-        }
-        enqueueMutation(this, "childList", {
-          addedNodes: nodes,
-          nextSibling: refWrapper,
-          previousSibling: previousNode
-        });
-        nodesWereAdded(nodes, this);
-        return childWrapper;
-      },
-      removeChild: function(childWrapper) {
-        assertIsNodeWrapper(childWrapper);
-        if (childWrapper.parentNode !== this) {
-          var found = false;
-          var childNodes = this.childNodes;
-          for (var ieChild = this.firstChild; ieChild; ieChild = ieChild.nextSibling) {
-            if (ieChild === childWrapper) {
-              found = true;
-              break;
-            }
-          }
-          if (!found) {
-            throw new Error("NotFoundError");
-          }
-        }
-        var childNode = unwrap(childWrapper);
-        var childWrapperNextSibling = childWrapper.nextSibling;
-        var childWrapperPreviousSibling = childWrapper.previousSibling;
-        if (this.invalidateShadowRenderer()) {
-          var thisFirstChild = this.firstChild;
-          var thisLastChild = this.lastChild;
-          var parentNode = childNode.parentNode;
-          if (parentNode) removeChildOriginalHelper(parentNode, childNode);
-          if (thisFirstChild === childWrapper) this.firstChild_ = childWrapperNextSibling;
-          if (thisLastChild === childWrapper) this.lastChild_ = childWrapperPreviousSibling;
-          if (childWrapperPreviousSibling) childWrapperPreviousSibling.nextSibling_ = childWrapperNextSibling;
-          if (childWrapperNextSibling) {
-            childWrapperNextSibling.previousSibling_ = childWrapperPreviousSibling;
-          }
-          childWrapper.previousSibling_ = childWrapper.nextSibling_ = childWrapper.parentNode_ = undefined;
-        } else {
-          clearChildNodes(this);
-          removeChildOriginalHelper(unsafeUnwrap(this), childNode);
-        }
-        if (!surpressMutations) {
-          enqueueMutation(this, "childList", {
-            removedNodes: createOneElementNodeList(childWrapper),
-            nextSibling: childWrapperNextSibling,
-            previousSibling: childWrapperPreviousSibling
-          });
-        }
-        registerTransientObservers(this, childWrapper);
-        return childWrapper;
-      },
-      replaceChild: function(newChildWrapper, oldChildWrapper) {
-        assertIsNodeWrapper(newChildWrapper);
-        var oldChildNode;
-        if (isWrapper(oldChildWrapper)) {
-          oldChildNode = unwrap(oldChildWrapper);
-        } else {
-          oldChildNode = oldChildWrapper;
-          oldChildWrapper = wrap(oldChildNode);
-        }
-        if (oldChildWrapper.parentNode !== this) {
-          throw new Error("NotFoundError");
-        }
-        var nextNode = oldChildWrapper.nextSibling;
-        var previousNode = oldChildWrapper.previousSibling;
-        var nodes;
-        var useNative = !this.invalidateShadowRenderer() && !invalidateParent(newChildWrapper);
-        if (useNative) {
-          nodes = collectNodesNative(newChildWrapper);
-        } else {
-          if (nextNode === newChildWrapper) nextNode = newChildWrapper.nextSibling;
-          nodes = collectNodes(newChildWrapper, this, previousNode, nextNode);
-        }
-        if (!useNative) {
-          if (this.firstChild === oldChildWrapper) this.firstChild_ = nodes[0];
-          if (this.lastChild === oldChildWrapper) this.lastChild_ = nodes[nodes.length - 1];
-          oldChildWrapper.previousSibling_ = oldChildWrapper.nextSibling_ = oldChildWrapper.parentNode_ = undefined;
-          if (oldChildNode.parentNode) {
-            originalReplaceChild.call(oldChildNode.parentNode, unwrapNodesForInsertion(this, nodes), oldChildNode);
-          }
-        } else {
-          ensureSameOwnerDocument(this, newChildWrapper);
-          clearChildNodes(this);
-          originalReplaceChild.call(unsafeUnwrap(this), unwrap(newChildWrapper), oldChildNode);
-        }
-        enqueueMutation(this, "childList", {
-          addedNodes: nodes,
-          removedNodes: createOneElementNodeList(oldChildWrapper),
-          nextSibling: nextNode,
-          previousSibling: previousNode
-        });
-        nodeWasRemoved(oldChildWrapper);
-        nodesWereAdded(nodes, this);
-        return oldChildWrapper;
-      },
-      nodeIsInserted_: function() {
-        for (var child = this.firstChild; child; child = child.nextSibling) {
-          child.nodeIsInserted_();
-        }
-      },
-      hasChildNodes: function() {
-        return this.firstChild !== null;
-      },
-      get parentNode() {
-        return this.parentNode_ !== undefined ? this.parentNode_ : wrap(unsafeUnwrap(this).parentNode);
-      },
-      get firstChild() {
-        return this.firstChild_ !== undefined ? this.firstChild_ : wrap(unsafeUnwrap(this).firstChild);
-      },
-      get lastChild() {
-        return this.lastChild_ !== undefined ? this.lastChild_ : wrap(unsafeUnwrap(this).lastChild);
-      },
-      get nextSibling() {
-        return this.nextSibling_ !== undefined ? this.nextSibling_ : wrap(unsafeUnwrap(this).nextSibling);
-      },
-      get previousSibling() {
-        return this.previousSibling_ !== undefined ? this.previousSibling_ : wrap(unsafeUnwrap(this).previousSibling);
-      },
-      get parentElement() {
-        var p = this.parentNode;
-        while (p && p.nodeType !== Node.ELEMENT_NODE) {
-          p = p.parentNode;
-        }
-        return p;
-      },
-      get textContent() {
-        var s = "";
-        for (var child = this.firstChild; child; child = child.nextSibling) {
-          if (child.nodeType != Node.COMMENT_NODE) {
-            s += child.textContent;
-          }
-        }
-        return s;
-      },
-      set textContent(textContent) {
-        if (textContent == null) textContent = "";
-        var removedNodes = snapshotNodeList(this.childNodes);
-        if (this.invalidateShadowRenderer()) {
-          removeAllChildNodes(this);
-          if (textContent !== "") {
-            var textNode = unsafeUnwrap(this).ownerDocument.createTextNode(textContent);
-            this.appendChild(textNode);
-          }
-        } else {
-          clearChildNodes(this);
-          unsafeUnwrap(this).textContent = textContent;
-        }
-        var addedNodes = snapshotNodeList(this.childNodes);
-        enqueueMutation(this, "childList", {
-          addedNodes: addedNodes,
-          removedNodes: removedNodes
-        });
-        nodesWereRemoved(removedNodes);
-        nodesWereAdded(addedNodes, this);
-      },
-      get childNodes() {
-        var wrapperList = new NodeList();
-        var i = 0;
-        for (var child = this.firstChild; child; child = child.nextSibling) {
-          wrapperList[i++] = child;
-        }
-        wrapperList.length = i;
-        return wrapperList;
-      },
-      cloneNode: function(deep) {
-        return cloneNode(this, deep);
-      },
-      contains: function(child) {
-        return contains(this, wrapIfNeeded(child));
-      },
-      compareDocumentPosition: function(otherNode) {
-        return originalCompareDocumentPosition.call(unsafeUnwrap(this), unwrapIfNeeded(otherNode));
-      },
-      normalize: function() {
-        var nodes = snapshotNodeList(this.childNodes);
-        var remNodes = [];
-        var s = "";
-        var modNode;
-        for (var i = 0, n; i < nodes.length; i++) {
-          n = nodes[i];
-          if (n.nodeType === Node.TEXT_NODE) {
-            if (!modNode && !n.data.length) this.removeChild(n); else if (!modNode) modNode = n; else {
-              s += n.data;
-              remNodes.push(n);
-            }
-          } else {
-            if (modNode && remNodes.length) {
-              modNode.data += s;
-              cleanupNodes(remNodes);
-            }
-            remNodes = [];
-            s = "";
-            modNode = null;
-            if (n.childNodes.length) n.normalize();
-          }
-        }
-        if (modNode && remNodes.length) {
-          modNode.data += s;
-          cleanupNodes(remNodes);
-        }
-      }
-    });
-    defineWrapGetter(Node, "ownerDocument");
-    registerWrapper(OriginalNode, Node, document.createDocumentFragment());
-    delete Node.prototype.querySelector;
-    delete Node.prototype.querySelectorAll;
-    Node.prototype = mixin(Object.create(EventTarget.prototype), Node.prototype);
-    scope.cloneNode = cloneNode;
-    scope.nodeWasAdded = nodeWasAdded;
-    scope.nodeWasRemoved = nodeWasRemoved;
-    scope.nodesWereAdded = nodesWereAdded;
-    scope.nodesWereRemoved = nodesWereRemoved;
-    scope.originalInsertBefore = originalInsertBefore;
-    scope.originalRemoveChild = originalRemoveChild;
-    scope.snapshotNodeList = snapshotNodeList;
-    scope.wrappers.Node = Node;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var HTMLCollection = scope.wrappers.HTMLCollection;
-    var NodeList = scope.wrappers.NodeList;
-    var getTreeScope = scope.getTreeScope;
-    var unsafeUnwrap = scope.unsafeUnwrap;
-    var wrap = scope.wrap;
-    var originalDocumentQuerySelector = document.querySelector;
-    var originalElementQuerySelector = document.documentElement.querySelector;
-    var originalDocumentQuerySelectorAll = document.querySelectorAll;
-    var originalElementQuerySelectorAll = document.documentElement.querySelectorAll;
-    var originalDocumentGetElementsByTagName = document.getElementsByTagName;
-    var originalElementGetElementsByTagName = document.documentElement.getElementsByTagName;
-    var originalDocumentGetElementsByTagNameNS = document.getElementsByTagNameNS;
-    var originalElementGetElementsByTagNameNS = document.documentElement.getElementsByTagNameNS;
-    var OriginalElement = window.Element;
-    var OriginalDocument = window.HTMLDocument || window.Document;
-    function filterNodeList(list, index, result, deep) {
-      var wrappedItem = null;
-      var root = null;
-      for (var i = 0, length = list.length; i < length; i++) {
-        wrappedItem = wrap(list[i]);
-        if (!deep && (root = getTreeScope(wrappedItem).root)) {
-          if (root instanceof scope.wrappers.ShadowRoot) {
-            continue;
-          }
-        }
-        result[index++] = wrappedItem;
-      }
-      return index;
-    }
-    function shimSelector(selector) {
-      return String(selector).replace(/\/deep\/|::shadow/g, " ");
-    }
-    function shimMatchesSelector(selector) {
-      return String(selector).replace(/:host\(([^\s]+)\)/g, "$1").replace(/([^\s]):host/g, "$1").replace(":host", "*").replace(/\^|\/shadow\/|\/shadow-deep\/|::shadow|\/deep\/|::content/g, " ");
-    }
-    function findOne(node, selector) {
-      var m, el = node.firstElementChild;
-      while (el) {
-        if (el.matches(selector)) return el;
-        m = findOne(el, selector);
-        if (m) return m;
-        el = el.nextElementSibling;
-      }
-      return null;
-    }
-    function matchesSelector(el, selector) {
-      return el.matches(selector);
-    }
-    var XHTML_NS = "http://www.w3.org/1999/xhtml";
-    function matchesTagName(el, localName, localNameLowerCase) {
-      var ln = el.localName;
-      return ln === localName || ln === localNameLowerCase && el.namespaceURI === XHTML_NS;
-    }
-    function matchesEveryThing() {
-      return true;
-    }
-    function matchesLocalNameOnly(el, ns, localName) {
-      return el.localName === localName;
-    }
-    function matchesNameSpace(el, ns) {
-      return el.namespaceURI === ns;
-    }
-    function matchesLocalNameNS(el, ns, localName) {
-      return el.namespaceURI === ns && el.localName === localName;
-    }
-    function findElements(node, index, result, p, arg0, arg1) {
-      var el = node.firstElementChild;
-      while (el) {
-        if (p(el, arg0, arg1)) result[index++] = el;
-        index = findElements(el, index, result, p, arg0, arg1);
-        el = el.nextElementSibling;
-      }
-      return index;
-    }
-    function querySelectorAllFiltered(p, index, result, selector, deep) {
-      var target = unsafeUnwrap(this);
-      var list;
-      var root = getTreeScope(this).root;
-      if (root instanceof scope.wrappers.ShadowRoot) {
-        return findElements(this, index, result, p, selector, null);
-      } else if (target instanceof OriginalElement) {
-        list = originalElementQuerySelectorAll.call(target, selector);
-      } else if (target instanceof OriginalDocument) {
-        list = originalDocumentQuerySelectorAll.call(target, selector);
-      } else {
-        return findElements(this, index, result, p, selector, null);
-      }
-      return filterNodeList(list, index, result, deep);
-    }
-    var SelectorsInterface = {
-      querySelector: function(selector) {
-        var shimmed = shimSelector(selector);
-        var deep = shimmed !== selector;
-        selector = shimmed;
-        var target = unsafeUnwrap(this);
-        var wrappedItem;
-        var root = getTreeScope(this).root;
-        if (root instanceof scope.wrappers.ShadowRoot) {
-          return findOne(this, selector);
-        } else if (target instanceof OriginalElement) {
-          wrappedItem = wrap(originalElementQuerySelector.call(target, selector));
-        } else if (target instanceof OriginalDocument) {
-          wrappedItem = wrap(originalDocumentQuerySelector.call(target, selector));
-        } else {
-          return findOne(this, selector);
-        }
-        if (!wrappedItem) {
-          return wrappedItem;
-        } else if (!deep && (root = getTreeScope(wrappedItem).root)) {
-          if (root instanceof scope.wrappers.ShadowRoot) {
-            return findOne(this, selector);
-          }
-        }
-        return wrappedItem;
-      },
-      querySelectorAll: function(selector) {
-        var shimmed = shimSelector(selector);
-        var deep = shimmed !== selector;
-        selector = shimmed;
-        var result = new NodeList();
-        result.length = querySelectorAllFiltered.call(this, matchesSelector, 0, result, selector, deep);
-        return result;
-      }
-    };
-    var MatchesInterface = {
-      matches: function(selector) {
-        selector = shimMatchesSelector(selector);
-        return scope.originalMatches.call(unsafeUnwrap(this), selector);
-      }
-    };
-    function getElementsByTagNameFiltered(p, index, result, localName, lowercase) {
-      var target = unsafeUnwrap(this);
-      var list;
-      var root = getTreeScope(this).root;
-      if (root instanceof scope.wrappers.ShadowRoot) {
-        return findElements(this, index, result, p, localName, lowercase);
-      } else if (target instanceof OriginalElement) {
-        list = originalElementGetElementsByTagName.call(target, localName, lowercase);
-      } else if (target instanceof OriginalDocument) {
-        list = originalDocumentGetElementsByTagName.call(target, localName, lowercase);
-      } else {
-        return findElements(this, index, result, p, localName, lowercase);
-      }
-      return filterNodeList(list, index, result, false);
-    }
-    function getElementsByTagNameNSFiltered(p, index, result, ns, localName) {
-      var target = unsafeUnwrap(this);
-      var list;
-      var root = getTreeScope(this).root;
-      if (root instanceof scope.wrappers.ShadowRoot) {
-        return findElements(this, index, result, p, ns, localName);
-      } else if (target instanceof OriginalElement) {
-        list = originalElementGetElementsByTagNameNS.call(target, ns, localName);
-      } else if (target instanceof OriginalDocument) {
-        list = originalDocumentGetElementsByTagNameNS.call(target, ns, localName);
-      } else {
-        return findElements(this, index, result, p, ns, localName);
-      }
-      return filterNodeList(list, index, result, false);
-    }
-    var GetElementsByInterface = {
-      getElementsByTagName: function(localName) {
-        var result = new HTMLCollection();
-        var match = localName === "*" ? matchesEveryThing : matchesTagName;
-        result.length = getElementsByTagNameFiltered.call(this, match, 0, result, localName, localName.toLowerCase());
-        return result;
-      },
-      getElementsByClassName: function(className) {
-        return this.querySelectorAll("." + className);
-      },
-      getElementsByTagNameNS: function(ns, localName) {
-        var result = new HTMLCollection();
-        var match = null;
-        if (ns === "*") {
-          match = localName === "*" ? matchesEveryThing : matchesLocalNameOnly;
-        } else {
-          match = localName === "*" ? matchesNameSpace : matchesLocalNameNS;
-        }
-        result.length = getElementsByTagNameNSFiltered.call(this, match, 0, result, ns || null, localName);
-        return result;
-      }
-    };
-    scope.GetElementsByInterface = GetElementsByInterface;
-    scope.SelectorsInterface = SelectorsInterface;
-    scope.MatchesInterface = MatchesInterface;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var NodeList = scope.wrappers.NodeList;
-    function forwardElement(node) {
-      while (node && node.nodeType !== Node.ELEMENT_NODE) {
-        node = node.nextSibling;
-      }
-      return node;
-    }
-    function backwardsElement(node) {
-      while (node && node.nodeType !== Node.ELEMENT_NODE) {
-        node = node.previousSibling;
-      }
-      return node;
-    }
-    var ParentNodeInterface = {
-      get firstElementChild() {
-        return forwardElement(this.firstChild);
-      },
-      get lastElementChild() {
-        return backwardsElement(this.lastChild);
-      },
-      get childElementCount() {
-        var count = 0;
-        for (var child = this.firstElementChild; child; child = child.nextElementSibling) {
-          count++;
-        }
-        return count;
-      },
-      get children() {
-        var wrapperList = new NodeList();
-        var i = 0;
-        for (var child = this.firstElementChild; child; child = child.nextElementSibling) {
-          wrapperList[i++] = child;
-        }
-        wrapperList.length = i;
-        return wrapperList;
-      },
-      remove: function() {
-        var p = this.parentNode;
-        if (p) p.removeChild(this);
-      }
-    };
-    var ChildNodeInterface = {
-      get nextElementSibling() {
-        return forwardElement(this.nextSibling);
-      },
-      get previousElementSibling() {
-        return backwardsElement(this.previousSibling);
-      }
-    };
-    scope.ChildNodeInterface = ChildNodeInterface;
-    scope.ParentNodeInterface = ParentNodeInterface;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var ChildNodeInterface = scope.ChildNodeInterface;
-    var Node = scope.wrappers.Node;
-    var enqueueMutation = scope.enqueueMutation;
-    var mixin = scope.mixin;
-    var registerWrapper = scope.registerWrapper;
-    var unsafeUnwrap = scope.unsafeUnwrap;
-    var OriginalCharacterData = window.CharacterData;
-    function CharacterData(node) {
-      Node.call(this, node);
-    }
-    CharacterData.prototype = Object.create(Node.prototype);
-    mixin(CharacterData.prototype, {
-      get textContent() {
-        return this.data;
-      },
-      set textContent(value) {
-        this.data = value;
-      },
-      get data() {
-        return unsafeUnwrap(this).data;
-      },
-      set data(value) {
-        var oldValue = unsafeUnwrap(this).data;
-        enqueueMutation(this, "characterData", {
-          oldValue: oldValue
-        });
-        unsafeUnwrap(this).data = value;
-      }
-    });
-    mixin(CharacterData.prototype, ChildNodeInterface);
-    registerWrapper(OriginalCharacterData, CharacterData, document.createTextNode(""));
-    scope.wrappers.CharacterData = CharacterData;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var CharacterData = scope.wrappers.CharacterData;
-    var enqueueMutation = scope.enqueueMutation;
-    var mixin = scope.mixin;
-    var registerWrapper = scope.registerWrapper;
-    function toUInt32(x) {
-      return x >>> 0;
-    }
-    var OriginalText = window.Text;
-    function Text(node) {
-      CharacterData.call(this, node);
-    }
-    Text.prototype = Object.create(CharacterData.prototype);
-    mixin(Text.prototype, {
-      splitText: function(offset) {
-        offset = toUInt32(offset);
-        var s = this.data;
-        if (offset > s.length) throw new Error("IndexSizeError");
-        var head = s.slice(0, offset);
-        var tail = s.slice(offset);
-        this.data = head;
-        var newTextNode = this.ownerDocument.createTextNode(tail);
-        if (this.parentNode) this.parentNode.insertBefore(newTextNode, this.nextSibling);
-        return newTextNode;
-      }
-    });
-    registerWrapper(OriginalText, Text, document.createTextNode(""));
-    scope.wrappers.Text = Text;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    if (!window.DOMTokenList) {
-      console.warn("Missing DOMTokenList prototype, please include a " + "compatible classList polyfill such as http://goo.gl/uTcepH.");
-      return;
-    }
-    var unsafeUnwrap = scope.unsafeUnwrap;
-    var enqueueMutation = scope.enqueueMutation;
-    function getClass(el) {
-      return unsafeUnwrap(el).getAttribute("class");
-    }
-    function enqueueClassAttributeChange(el, oldValue) {
-      enqueueMutation(el, "attributes", {
-        name: "class",
-        namespace: null,
-        oldValue: oldValue
-      });
-    }
-    function invalidateClass(el) {
-      scope.invalidateRendererBasedOnAttribute(el, "class");
-    }
-    function changeClass(tokenList, method, args) {
-      var ownerElement = tokenList.ownerElement_;
-      if (ownerElement == null) {
-        return method.apply(tokenList, args);
-      }
-      var oldValue = getClass(ownerElement);
-      var retv = method.apply(tokenList, args);
-      if (getClass(ownerElement) !== oldValue) {
-        enqueueClassAttributeChange(ownerElement, oldValue);
-        invalidateClass(ownerElement);
-      }
-      return retv;
-    }
-    var oldAdd = DOMTokenList.prototype.add;
-    DOMTokenList.prototype.add = function() {
-      changeClass(this, oldAdd, arguments);
-    };
-    var oldRemove = DOMTokenList.prototype.remove;
-    DOMTokenList.prototype.remove = function() {
-      changeClass(this, oldRemove, arguments);
-    };
-    var oldToggle = DOMTokenList.prototype.toggle;
-    DOMTokenList.prototype.toggle = function() {
-      return changeClass(this, oldToggle, arguments);
-    };
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var ChildNodeInterface = scope.ChildNodeInterface;
-    var GetElementsByInterface = scope.GetElementsByInterface;
-    var Node = scope.wrappers.Node;
-    var ParentNodeInterface = scope.ParentNodeInterface;
-    var SelectorsInterface = scope.SelectorsInterface;
-    var MatchesInterface = scope.MatchesInterface;
-    var addWrapNodeListMethod = scope.addWrapNodeListMethod;
-    var enqueueMutation = scope.enqueueMutation;
-    var mixin = scope.mixin;
-    var oneOf = scope.oneOf;
-    var registerWrapper = scope.registerWrapper;
-    var unsafeUnwrap = scope.unsafeUnwrap;
-    var wrappers = scope.wrappers;
-    var OriginalElement = window.Element;
-    var matchesNames = [ "matches", "mozMatchesSelector", "msMatchesSelector", "webkitMatchesSelector" ].filter(function(name) {
-      return OriginalElement.prototype[name];
-    });
-    var matchesName = matchesNames[0];
-    var originalMatches = OriginalElement.prototype[matchesName];
-    function invalidateRendererBasedOnAttribute(element, name) {
-      var p = element.parentNode;
-      if (!p || !p.shadowRoot) return;
-      var renderer = scope.getRendererForHost(p);
-      if (renderer.dependsOnAttribute(name)) renderer.invalidate();
-    }
-    function enqueAttributeChange(element, name, oldValue) {
-      enqueueMutation(element, "attributes", {
-        name: name,
-        namespace: null,
-        oldValue: oldValue
-      });
-    }
-    var classListTable = new WeakMap();
-    function Element(node) {
-      Node.call(this, node);
-    }
-    Element.prototype = Object.create(Node.prototype);
-    mixin(Element.prototype, {
-      createShadowRoot: function() {
-        var newShadowRoot = new wrappers.ShadowRoot(this);
-        unsafeUnwrap(this).polymerShadowRoot_ = newShadowRoot;
-        var renderer = scope.getRendererForHost(this);
-        renderer.invalidate();
-        return newShadowRoot;
-      },
-      get shadowRoot() {
-        return unsafeUnwrap(this).polymerShadowRoot_ || null;
-      },
-      setAttribute: function(name, value) {
-        var oldValue = unsafeUnwrap(this).getAttribute(name);
-        unsafeUnwrap(this).setAttribute(name, value);
-        enqueAttributeChange(this, name, oldValue);
-        invalidateRendererBasedOnAttribute(this, name);
-      },
-      removeAttribute: function(name) {
-        var oldValue = unsafeUnwrap(this).getAttribute(name);
-        unsafeUnwrap(this).removeAttribute(name);
-        enqueAttributeChange(this, name, oldValue);
-        invalidateRendererBasedOnAttribute(this, name);
-      },
-      get classList() {
-        var list = classListTable.get(this);
-        if (!list) {
-          list = unsafeUnwrap(this).classList;
-          if (!list) return;
-          list.ownerElement_ = this;
-          classListTable.set(this, list);
-        }
-        return list;
-      },
-      get className() {
-        return unsafeUnwrap(this).className;
-      },
-      set className(v) {
-        this.setAttribute("class", v);
-      },
-      get id() {
-        return unsafeUnwrap(this).id;
-      },
-      set id(v) {
-        this.setAttribute("id", v);
-      }
-    });
-    matchesNames.forEach(function(name) {
-      if (name !== "matches") {
-        Element.prototype[name] = function(selector) {
-          return this.matches(selector);
-        };
-      }
-    });
-    if (OriginalElement.prototype.webkitCreateShadowRoot) {
-      Element.prototype.webkitCreateShadowRoot = Element.prototype.createShadowRoot;
-    }
-    mixin(Element.prototype, ChildNodeInterface);
-    mixin(Element.prototype, GetElementsByInterface);
-    mixin(Element.prototype, ParentNodeInterface);
-    mixin(Element.prototype, SelectorsInterface);
-    mixin(Element.prototype, MatchesInterface);
-    registerWrapper(OriginalElement, Element, document.createElementNS(null, "x"));
-    scope.invalidateRendererBasedOnAttribute = invalidateRendererBasedOnAttribute;
-    scope.matchesNames = matchesNames;
-    scope.originalMatches = originalMatches;
-    scope.wrappers.Element = Element;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var Element = scope.wrappers.Element;
-    var defineGetter = scope.defineGetter;
-    var enqueueMutation = scope.enqueueMutation;
-    var mixin = scope.mixin;
-    var nodesWereAdded = scope.nodesWereAdded;
-    var nodesWereRemoved = scope.nodesWereRemoved;
-    var registerWrapper = scope.registerWrapper;
-    var snapshotNodeList = scope.snapshotNodeList;
-    var unsafeUnwrap = scope.unsafeUnwrap;
-    var unwrap = scope.unwrap;
-    var wrap = scope.wrap;
-    var wrappers = scope.wrappers;
-    var escapeAttrRegExp = /[&\u00A0"]/g;
-    var escapeDataRegExp = /[&\u00A0<>]/g;
-    function escapeReplace(c) {
-      switch (c) {
-       case "&":
-        return "&";
-
-       case "<":
-        return "<";
-
-       case ">":
-        return ">";
-
-       case '"':
-        return """;
-
-       case " ":
-        return " ";
-      }
-    }
-    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) {
-      switch (node.nodeType) {
-       case Node.ELEMENT_NODE:
-        var tagName = node.tagName.toLowerCase();
-        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) + "";
-
-       case Node.TEXT_NODE:
-        var data = node.data;
-        if (parentNode && plaintextParents[parentNode.localName]) return data;
-        return escapeData(data);
-
-       case Node.COMMENT_NODE:
-        return "";
-
-       default:
-        console.error(node);
-        throw new Error("not implemented");
-      }
-    }
-    function getInnerHTML(node) {
-      if (node instanceof wrappers.HTMLTemplateElement) node = node.content;
-      var s = "";
-      for (var child = node.firstChild; child; child = child.nextSibling) {
-        s += getOuterHTML(child, node);
-      }
-      return s;
-    }
-    function setInnerHTML(node, value, opt_tagName) {
-      var tagName = opt_tagName || "div";
-      node.textContent = "";
-      var tempElement = unwrap(node.ownerDocument.createElement(tagName));
-      tempElement.innerHTML = value;
-      var firstChild;
-      while (firstChild = tempElement.firstChild) {
-        node.appendChild(wrap(firstChild));
-      }
-    }
-    var oldIe = /MSIE/.test(navigator.userAgent);
-    var OriginalHTMLElement = window.HTMLElement;
-    var OriginalHTMLTemplateElement = window.HTMLTemplateElement;
-    function HTMLElement(node) {
-      Element.call(this, node);
-    }
-    HTMLElement.prototype = Object.create(Element.prototype);
-    mixin(HTMLElement.prototype, {
-      get innerHTML() {
-        return getInnerHTML(this);
-      },
-      set innerHTML(value) {
-        if (oldIe && plaintextParents[this.localName]) {
-          this.textContent = value;
-          return;
-        }
-        var removedNodes = snapshotNodeList(this.childNodes);
-        if (this.invalidateShadowRenderer()) {
-          if (this instanceof wrappers.HTMLTemplateElement) setInnerHTML(this.content, value); else setInnerHTML(this, value, this.tagName);
-        } else if (!OriginalHTMLTemplateElement && this instanceof wrappers.HTMLTemplateElement) {
-          setInnerHTML(this.content, value);
-        } else {
-          unsafeUnwrap(this).innerHTML = value;
-        }
-        var addedNodes = snapshotNodeList(this.childNodes);
-        enqueueMutation(this, "childList", {
-          addedNodes: addedNodes,
-          removedNodes: removedNodes
-        });
-        nodesWereRemoved(removedNodes);
-        nodesWereAdded(addedNodes, this);
-      },
-      get outerHTML() {
-        return getOuterHTML(this, this.parentNode);
-      },
-      set outerHTML(value) {
-        var p = this.parentNode;
-        if (p) {
-          p.invalidateShadowRenderer();
-          var df = frag(p, value);
-          p.replaceChild(df, this);
-        }
-      },
-      insertAdjacentHTML: function(position, text) {
-        var contextElement, refNode;
-        switch (String(position).toLowerCase()) {
-         case "beforebegin":
-          contextElement = this.parentNode;
-          refNode = this;
-          break;
-
-         case "afterend":
-          contextElement = this.parentNode;
-          refNode = this.nextSibling;
-          break;
-
-         case "afterbegin":
-          contextElement = this;
-          refNode = this.firstChild;
-          break;
-
-         case "beforeend":
-          contextElement = this;
-          refNode = null;
-          break;
-
-         default:
-          return;
-        }
-        var df = frag(contextElement, text);
-        contextElement.insertBefore(df, refNode);
-      },
-      get hidden() {
-        return this.hasAttribute("hidden");
-      },
-      set hidden(v) {
-        if (v) {
-          this.setAttribute("hidden", "");
-        } else {
-          this.removeAttribute("hidden");
-        }
-      }
-    });
-    function frag(contextElement, html) {
-      var p = unwrap(contextElement.cloneNode(false));
-      p.innerHTML = html;
-      var df = unwrap(document.createDocumentFragment());
-      var c;
-      while (c = p.firstChild) {
-        df.appendChild(c);
-      }
-      return wrap(df);
-    }
-    function getter(name) {
-      return function() {
-        scope.renderAllPending();
-        return unsafeUnwrap(this)[name];
-      };
-    }
-    function getterRequiresRendering(name) {
-      defineGetter(HTMLElement, name, getter(name));
-    }
-    [ "clientHeight", "clientLeft", "clientTop", "clientWidth", "offsetHeight", "offsetLeft", "offsetTop", "offsetWidth", "scrollHeight", "scrollWidth" ].forEach(getterRequiresRendering);
-    function getterAndSetterRequiresRendering(name) {
-      Object.defineProperty(HTMLElement.prototype, name, {
-        get: getter(name),
-        set: function(v) {
-          scope.renderAllPending();
-          unsafeUnwrap(this)[name] = v;
-        },
-        configurable: true,
-        enumerable: true
-      });
-    }
-    [ "scrollLeft", "scrollTop" ].forEach(getterAndSetterRequiresRendering);
-    function methodRequiresRendering(name) {
-      Object.defineProperty(HTMLElement.prototype, name, {
-        value: function() {
-          scope.renderAllPending();
-          return unsafeUnwrap(this)[name].apply(unsafeUnwrap(this), arguments);
-        },
-        configurable: true,
-        enumerable: true
-      });
-    }
-    [ "getBoundingClientRect", "getClientRects", "scrollIntoView" ].forEach(methodRequiresRendering);
-    registerWrapper(OriginalHTMLElement, HTMLElement, document.createElement("b"));
-    scope.wrappers.HTMLElement = HTMLElement;
-    scope.getInnerHTML = getInnerHTML;
-    scope.setInnerHTML = setInnerHTML;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var HTMLElement = scope.wrappers.HTMLElement;
-    var mixin = scope.mixin;
-    var registerWrapper = scope.registerWrapper;
-    var unsafeUnwrap = scope.unsafeUnwrap;
-    var wrap = scope.wrap;
-    var OriginalHTMLCanvasElement = window.HTMLCanvasElement;
-    function HTMLCanvasElement(node) {
-      HTMLElement.call(this, node);
-    }
-    HTMLCanvasElement.prototype = Object.create(HTMLElement.prototype);
-    mixin(HTMLCanvasElement.prototype, {
-      getContext: function() {
-        var context = unsafeUnwrap(this).getContext.apply(unsafeUnwrap(this), arguments);
-        return context && wrap(context);
-      }
-    });
-    registerWrapper(OriginalHTMLCanvasElement, HTMLCanvasElement, document.createElement("canvas"));
-    scope.wrappers.HTMLCanvasElement = HTMLCanvasElement;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var HTMLElement = scope.wrappers.HTMLElement;
-    var mixin = scope.mixin;
-    var registerWrapper = scope.registerWrapper;
-    var OriginalHTMLContentElement = window.HTMLContentElement;
-    function HTMLContentElement(node) {
-      HTMLElement.call(this, node);
-    }
-    HTMLContentElement.prototype = Object.create(HTMLElement.prototype);
-    mixin(HTMLContentElement.prototype, {
-      constructor: HTMLContentElement,
-      get select() {
-        return this.getAttribute("select");
-      },
-      set select(value) {
-        this.setAttribute("select", value);
-      },
-      setAttribute: function(n, v) {
-        HTMLElement.prototype.setAttribute.call(this, n, v);
-        if (String(n).toLowerCase() === "select") this.invalidateShadowRenderer(true);
-      }
-    });
-    if (OriginalHTMLContentElement) registerWrapper(OriginalHTMLContentElement, HTMLContentElement);
-    scope.wrappers.HTMLContentElement = HTMLContentElement;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var HTMLElement = scope.wrappers.HTMLElement;
-    var mixin = scope.mixin;
-    var registerWrapper = scope.registerWrapper;
-    var wrapHTMLCollection = scope.wrapHTMLCollection;
-    var unwrap = scope.unwrap;
-    var OriginalHTMLFormElement = window.HTMLFormElement;
-    function HTMLFormElement(node) {
-      HTMLElement.call(this, node);
-    }
-    HTMLFormElement.prototype = Object.create(HTMLElement.prototype);
-    mixin(HTMLFormElement.prototype, {
-      get elements() {
-        return wrapHTMLCollection(unwrap(this).elements);
-      }
-    });
-    registerWrapper(OriginalHTMLFormElement, HTMLFormElement, document.createElement("form"));
-    scope.wrappers.HTMLFormElement = HTMLFormElement;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var HTMLElement = scope.wrappers.HTMLElement;
-    var registerWrapper = scope.registerWrapper;
-    var unwrap = scope.unwrap;
-    var rewrap = scope.rewrap;
-    var OriginalHTMLImageElement = window.HTMLImageElement;
-    function HTMLImageElement(node) {
-      HTMLElement.call(this, node);
-    }
-    HTMLImageElement.prototype = Object.create(HTMLElement.prototype);
-    registerWrapper(OriginalHTMLImageElement, HTMLImageElement, document.createElement("img"));
-    function Image(width, height) {
-      if (!(this instanceof Image)) {
-        throw new TypeError("DOM object constructor cannot be called as a function.");
-      }
-      var node = unwrap(document.createElement("img"));
-      HTMLElement.call(this, node);
-      rewrap(node, this);
-      if (width !== undefined) node.width = width;
-      if (height !== undefined) node.height = height;
-    }
-    Image.prototype = HTMLImageElement.prototype;
-    scope.wrappers.HTMLImageElement = HTMLImageElement;
-    scope.wrappers.Image = Image;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var HTMLElement = scope.wrappers.HTMLElement;
-    var mixin = scope.mixin;
-    var NodeList = scope.wrappers.NodeList;
-    var registerWrapper = scope.registerWrapper;
-    var OriginalHTMLShadowElement = window.HTMLShadowElement;
-    function HTMLShadowElement(node) {
-      HTMLElement.call(this, node);
-    }
-    HTMLShadowElement.prototype = Object.create(HTMLElement.prototype);
-    HTMLShadowElement.prototype.constructor = HTMLShadowElement;
-    if (OriginalHTMLShadowElement) registerWrapper(OriginalHTMLShadowElement, HTMLShadowElement);
-    scope.wrappers.HTMLShadowElement = HTMLShadowElement;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var HTMLElement = scope.wrappers.HTMLElement;
-    var mixin = scope.mixin;
-    var registerWrapper = scope.registerWrapper;
-    var unsafeUnwrap = scope.unsafeUnwrap;
-    var unwrap = scope.unwrap;
-    var wrap = scope.wrap;
-    var contentTable = new WeakMap();
-    var templateContentsOwnerTable = new WeakMap();
-    function getTemplateContentsOwner(doc) {
-      if (!doc.defaultView) return doc;
-      var d = templateContentsOwnerTable.get(doc);
-      if (!d) {
-        d = doc.implementation.createHTMLDocument("");
-        while (d.lastChild) {
-          d.removeChild(d.lastChild);
-        }
-        templateContentsOwnerTable.set(doc, d);
-      }
-      return d;
-    }
-    function extractContent(templateElement) {
-      var doc = getTemplateContentsOwner(templateElement.ownerDocument);
-      var df = unwrap(doc.createDocumentFragment());
-      var child;
-      while (child = templateElement.firstChild) {
-        df.appendChild(child);
-      }
-      return df;
-    }
-    var OriginalHTMLTemplateElement = window.HTMLTemplateElement;
-    function HTMLTemplateElement(node) {
-      HTMLElement.call(this, node);
-      if (!OriginalHTMLTemplateElement) {
-        var content = extractContent(node);
-        contentTable.set(this, wrap(content));
-      }
-    }
-    HTMLTemplateElement.prototype = Object.create(HTMLElement.prototype);
-    mixin(HTMLTemplateElement.prototype, {
-      constructor: HTMLTemplateElement,
-      get content() {
-        if (OriginalHTMLTemplateElement) return wrap(unsafeUnwrap(this).content);
-        return contentTable.get(this);
-      }
-    });
-    if (OriginalHTMLTemplateElement) registerWrapper(OriginalHTMLTemplateElement, HTMLTemplateElement);
-    scope.wrappers.HTMLTemplateElement = HTMLTemplateElement;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var HTMLElement = scope.wrappers.HTMLElement;
-    var registerWrapper = scope.registerWrapper;
-    var OriginalHTMLMediaElement = window.HTMLMediaElement;
-    if (!OriginalHTMLMediaElement) return;
-    function HTMLMediaElement(node) {
-      HTMLElement.call(this, node);
-    }
-    HTMLMediaElement.prototype = Object.create(HTMLElement.prototype);
-    registerWrapper(OriginalHTMLMediaElement, HTMLMediaElement, document.createElement("audio"));
-    scope.wrappers.HTMLMediaElement = HTMLMediaElement;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var HTMLMediaElement = scope.wrappers.HTMLMediaElement;
-    var registerWrapper = scope.registerWrapper;
-    var unwrap = scope.unwrap;
-    var rewrap = scope.rewrap;
-    var OriginalHTMLAudioElement = window.HTMLAudioElement;
-    if (!OriginalHTMLAudioElement) return;
-    function HTMLAudioElement(node) {
-      HTMLMediaElement.call(this, node);
-    }
-    HTMLAudioElement.prototype = Object.create(HTMLMediaElement.prototype);
-    registerWrapper(OriginalHTMLAudioElement, HTMLAudioElement, document.createElement("audio"));
-    function Audio(src) {
-      if (!(this instanceof Audio)) {
-        throw new TypeError("DOM object constructor cannot be called as a function.");
-      }
-      var node = unwrap(document.createElement("audio"));
-      HTMLMediaElement.call(this, node);
-      rewrap(node, this);
-      node.setAttribute("preload", "auto");
-      if (src !== undefined) node.setAttribute("src", src);
-    }
-    Audio.prototype = HTMLAudioElement.prototype;
-    scope.wrappers.HTMLAudioElement = HTMLAudioElement;
-    scope.wrappers.Audio = Audio;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var HTMLElement = scope.wrappers.HTMLElement;
-    var mixin = scope.mixin;
-    var registerWrapper = scope.registerWrapper;
-    var rewrap = scope.rewrap;
-    var unwrap = scope.unwrap;
-    var wrap = scope.wrap;
-    var OriginalHTMLOptionElement = window.HTMLOptionElement;
-    function trimText(s) {
-      return s.replace(/\s+/g, " ").trim();
-    }
-    function HTMLOptionElement(node) {
-      HTMLElement.call(this, node);
-    }
-    HTMLOptionElement.prototype = Object.create(HTMLElement.prototype);
-    mixin(HTMLOptionElement.prototype, {
-      get text() {
-        return trimText(this.textContent);
-      },
-      set text(value) {
-        this.textContent = trimText(String(value));
-      },
-      get form() {
-        return wrap(unwrap(this).form);
-      }
-    });
-    registerWrapper(OriginalHTMLOptionElement, HTMLOptionElement, document.createElement("option"));
-    function Option(text, value, defaultSelected, selected) {
-      if (!(this instanceof Option)) {
-        throw new TypeError("DOM object constructor cannot be called as a function.");
-      }
-      var node = unwrap(document.createElement("option"));
-      HTMLElement.call(this, node);
-      rewrap(node, this);
-      if (text !== undefined) node.text = text;
-      if (value !== undefined) node.setAttribute("value", value);
-      if (defaultSelected === true) node.setAttribute("selected", "");
-      node.selected = selected === true;
-    }
-    Option.prototype = HTMLOptionElement.prototype;
-    scope.wrappers.HTMLOptionElement = HTMLOptionElement;
-    scope.wrappers.Option = Option;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var HTMLElement = scope.wrappers.HTMLElement;
-    var mixin = scope.mixin;
-    var registerWrapper = scope.registerWrapper;
-    var unwrap = scope.unwrap;
-    var wrap = scope.wrap;
-    var OriginalHTMLSelectElement = window.HTMLSelectElement;
-    function HTMLSelectElement(node) {
-      HTMLElement.call(this, node);
-    }
-    HTMLSelectElement.prototype = Object.create(HTMLElement.prototype);
-    mixin(HTMLSelectElement.prototype, {
-      add: function(element, before) {
-        if (typeof before === "object") before = unwrap(before);
-        unwrap(this).add(unwrap(element), before);
-      },
-      remove: function(indexOrNode) {
-        if (indexOrNode === undefined) {
-          HTMLElement.prototype.remove.call(this);
-          return;
-        }
-        if (typeof indexOrNode === "object") indexOrNode = unwrap(indexOrNode);
-        unwrap(this).remove(indexOrNode);
-      },
-      get form() {
-        return wrap(unwrap(this).form);
-      }
-    });
-    registerWrapper(OriginalHTMLSelectElement, HTMLSelectElement, document.createElement("select"));
-    scope.wrappers.HTMLSelectElement = HTMLSelectElement;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var HTMLElement = scope.wrappers.HTMLElement;
-    var mixin = scope.mixin;
-    var registerWrapper = scope.registerWrapper;
-    var unwrap = scope.unwrap;
-    var wrap = scope.wrap;
-    var wrapHTMLCollection = scope.wrapHTMLCollection;
-    var OriginalHTMLTableElement = window.HTMLTableElement;
-    function HTMLTableElement(node) {
-      HTMLElement.call(this, node);
-    }
-    HTMLTableElement.prototype = Object.create(HTMLElement.prototype);
-    mixin(HTMLTableElement.prototype, {
-      get caption() {
-        return wrap(unwrap(this).caption);
-      },
-      createCaption: function() {
-        return wrap(unwrap(this).createCaption());
-      },
-      get tHead() {
-        return wrap(unwrap(this).tHead);
-      },
-      createTHead: function() {
-        return wrap(unwrap(this).createTHead());
-      },
-      createTFoot: function() {
-        return wrap(unwrap(this).createTFoot());
-      },
-      get tFoot() {
-        return wrap(unwrap(this).tFoot);
-      },
-      get tBodies() {
-        return wrapHTMLCollection(unwrap(this).tBodies);
-      },
-      createTBody: function() {
-        return wrap(unwrap(this).createTBody());
-      },
-      get rows() {
-        return wrapHTMLCollection(unwrap(this).rows);
-      },
-      insertRow: function(index) {
-        return wrap(unwrap(this).insertRow(index));
-      }
-    });
-    registerWrapper(OriginalHTMLTableElement, HTMLTableElement, document.createElement("table"));
-    scope.wrappers.HTMLTableElement = HTMLTableElement;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var HTMLElement = scope.wrappers.HTMLElement;
-    var mixin = scope.mixin;
-    var registerWrapper = scope.registerWrapper;
-    var wrapHTMLCollection = scope.wrapHTMLCollection;
-    var unwrap = scope.unwrap;
-    var wrap = scope.wrap;
-    var OriginalHTMLTableSectionElement = window.HTMLTableSectionElement;
-    function HTMLTableSectionElement(node) {
-      HTMLElement.call(this, node);
-    }
-    HTMLTableSectionElement.prototype = Object.create(HTMLElement.prototype);
-    mixin(HTMLTableSectionElement.prototype, {
-      constructor: HTMLTableSectionElement,
-      get rows() {
-        return wrapHTMLCollection(unwrap(this).rows);
-      },
-      insertRow: function(index) {
-        return wrap(unwrap(this).insertRow(index));
-      }
-    });
-    registerWrapper(OriginalHTMLTableSectionElement, HTMLTableSectionElement, document.createElement("thead"));
-    scope.wrappers.HTMLTableSectionElement = HTMLTableSectionElement;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var HTMLElement = scope.wrappers.HTMLElement;
-    var mixin = scope.mixin;
-    var registerWrapper = scope.registerWrapper;
-    var wrapHTMLCollection = scope.wrapHTMLCollection;
-    var unwrap = scope.unwrap;
-    var wrap = scope.wrap;
-    var OriginalHTMLTableRowElement = window.HTMLTableRowElement;
-    function HTMLTableRowElement(node) {
-      HTMLElement.call(this, node);
-    }
-    HTMLTableRowElement.prototype = Object.create(HTMLElement.prototype);
-    mixin(HTMLTableRowElement.prototype, {
-      get cells() {
-        return wrapHTMLCollection(unwrap(this).cells);
-      },
-      insertCell: function(index) {
-        return wrap(unwrap(this).insertCell(index));
-      }
-    });
-    registerWrapper(OriginalHTMLTableRowElement, HTMLTableRowElement, document.createElement("tr"));
-    scope.wrappers.HTMLTableRowElement = HTMLTableRowElement;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var HTMLContentElement = scope.wrappers.HTMLContentElement;
-    var HTMLElement = scope.wrappers.HTMLElement;
-    var HTMLShadowElement = scope.wrappers.HTMLShadowElement;
-    var HTMLTemplateElement = scope.wrappers.HTMLTemplateElement;
-    var mixin = scope.mixin;
-    var registerWrapper = scope.registerWrapper;
-    var OriginalHTMLUnknownElement = window.HTMLUnknownElement;
-    function HTMLUnknownElement(node) {
-      switch (node.localName) {
-       case "content":
-        return new HTMLContentElement(node);
-
-       case "shadow":
-        return new HTMLShadowElement(node);
-
-       case "template":
-        return new HTMLTemplateElement(node);
-      }
-      HTMLElement.call(this, node);
-    }
-    HTMLUnknownElement.prototype = Object.create(HTMLElement.prototype);
-    registerWrapper(OriginalHTMLUnknownElement, HTMLUnknownElement);
-    scope.wrappers.HTMLUnknownElement = HTMLUnknownElement;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var Element = scope.wrappers.Element;
-    var HTMLElement = scope.wrappers.HTMLElement;
-    var registerObject = scope.registerObject;
-    var defineWrapGetter = scope.defineWrapGetter;
-    var SVG_NS = "http://www.w3.org/2000/svg";
-    var svgTitleElement = document.createElementNS(SVG_NS, "title");
-    var SVGTitleElement = registerObject(svgTitleElement);
-    var SVGElement = Object.getPrototypeOf(SVGTitleElement.prototype).constructor;
-    if (!("classList" in svgTitleElement)) {
-      var descr = Object.getOwnPropertyDescriptor(Element.prototype, "classList");
-      Object.defineProperty(HTMLElement.prototype, "classList", descr);
-      delete Element.prototype.classList;
-    }
-    defineWrapGetter(SVGElement, "ownerSVGElement");
-    scope.wrappers.SVGElement = SVGElement;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var mixin = scope.mixin;
-    var registerWrapper = scope.registerWrapper;
-    var unwrap = scope.unwrap;
-    var wrap = scope.wrap;
-    var OriginalSVGUseElement = window.SVGUseElement;
-    var SVG_NS = "http://www.w3.org/2000/svg";
-    var gWrapper = wrap(document.createElementNS(SVG_NS, "g"));
-    var useElement = document.createElementNS(SVG_NS, "use");
-    var SVGGElement = gWrapper.constructor;
-    var parentInterfacePrototype = Object.getPrototypeOf(SVGGElement.prototype);
-    var parentInterface = parentInterfacePrototype.constructor;
-    function SVGUseElement(impl) {
-      parentInterface.call(this, impl);
-    }
-    SVGUseElement.prototype = Object.create(parentInterfacePrototype);
-    if ("instanceRoot" in useElement) {
-      mixin(SVGUseElement.prototype, {
-        get instanceRoot() {
-          return wrap(unwrap(this).instanceRoot);
-        },
-        get animatedInstanceRoot() {
-          return wrap(unwrap(this).animatedInstanceRoot);
-        }
-      });
-    }
-    registerWrapper(OriginalSVGUseElement, SVGUseElement, useElement);
-    scope.wrappers.SVGUseElement = SVGUseElement;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var EventTarget = scope.wrappers.EventTarget;
-    var mixin = scope.mixin;
-    var registerWrapper = scope.registerWrapper;
-    var unsafeUnwrap = scope.unsafeUnwrap;
-    var wrap = scope.wrap;
-    var OriginalSVGElementInstance = window.SVGElementInstance;
-    if (!OriginalSVGElementInstance) return;
-    function SVGElementInstance(impl) {
-      EventTarget.call(this, impl);
-    }
-    SVGElementInstance.prototype = Object.create(EventTarget.prototype);
-    mixin(SVGElementInstance.prototype, {
-      get correspondingElement() {
-        return wrap(unsafeUnwrap(this).correspondingElement);
-      },
-      get correspondingUseElement() {
-        return wrap(unsafeUnwrap(this).correspondingUseElement);
-      },
-      get parentNode() {
-        return wrap(unsafeUnwrap(this).parentNode);
-      },
-      get childNodes() {
-        throw new Error("Not implemented");
-      },
-      get firstChild() {
-        return wrap(unsafeUnwrap(this).firstChild);
-      },
-      get lastChild() {
-        return wrap(unsafeUnwrap(this).lastChild);
-      },
-      get previousSibling() {
-        return wrap(unsafeUnwrap(this).previousSibling);
-      },
-      get nextSibling() {
-        return wrap(unsafeUnwrap(this).nextSibling);
-      }
-    });
-    registerWrapper(OriginalSVGElementInstance, SVGElementInstance);
-    scope.wrappers.SVGElementInstance = SVGElementInstance;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var mixin = scope.mixin;
-    var registerWrapper = scope.registerWrapper;
-    var setWrapper = scope.setWrapper;
-    var unsafeUnwrap = scope.unsafeUnwrap;
-    var unwrap = scope.unwrap;
-    var unwrapIfNeeded = scope.unwrapIfNeeded;
-    var wrap = scope.wrap;
-    var OriginalCanvasRenderingContext2D = window.CanvasRenderingContext2D;
-    function CanvasRenderingContext2D(impl) {
-      setWrapper(impl, this);
-    }
-    mixin(CanvasRenderingContext2D.prototype, {
-      get canvas() {
-        return wrap(unsafeUnwrap(this).canvas);
-      },
-      drawImage: function() {
-        arguments[0] = unwrapIfNeeded(arguments[0]);
-        unsafeUnwrap(this).drawImage.apply(unsafeUnwrap(this), arguments);
-      },
-      createPattern: function() {
-        arguments[0] = unwrap(arguments[0]);
-        return unsafeUnwrap(this).createPattern.apply(unsafeUnwrap(this), arguments);
-      }
-    });
-    registerWrapper(OriginalCanvasRenderingContext2D, CanvasRenderingContext2D, document.createElement("canvas").getContext("2d"));
-    scope.wrappers.CanvasRenderingContext2D = CanvasRenderingContext2D;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var mixin = scope.mixin;
-    var registerWrapper = scope.registerWrapper;
-    var setWrapper = scope.setWrapper;
-    var unsafeUnwrap = scope.unsafeUnwrap;
-    var unwrapIfNeeded = scope.unwrapIfNeeded;
-    var wrap = scope.wrap;
-    var OriginalWebGLRenderingContext = window.WebGLRenderingContext;
-    if (!OriginalWebGLRenderingContext) return;
-    function WebGLRenderingContext(impl) {
-      setWrapper(impl, this);
-    }
-    mixin(WebGLRenderingContext.prototype, {
-      get canvas() {
-        return wrap(unsafeUnwrap(this).canvas);
-      },
-      texImage2D: function() {
-        arguments[5] = unwrapIfNeeded(arguments[5]);
-        unsafeUnwrap(this).texImage2D.apply(unsafeUnwrap(this), arguments);
-      },
-      texSubImage2D: function() {
-        arguments[6] = unwrapIfNeeded(arguments[6]);
-        unsafeUnwrap(this).texSubImage2D.apply(unsafeUnwrap(this), arguments);
-      }
-    });
-    var instanceProperties = /WebKit/.test(navigator.userAgent) ? {
-      drawingBufferHeight: null,
-      drawingBufferWidth: null
-    } : {};
-    registerWrapper(OriginalWebGLRenderingContext, WebGLRenderingContext, instanceProperties);
-    scope.wrappers.WebGLRenderingContext = WebGLRenderingContext;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var registerWrapper = scope.registerWrapper;
-    var setWrapper = scope.setWrapper;
-    var unsafeUnwrap = scope.unsafeUnwrap;
-    var unwrap = scope.unwrap;
-    var unwrapIfNeeded = scope.unwrapIfNeeded;
-    var wrap = scope.wrap;
-    var OriginalRange = window.Range;
-    function Range(impl) {
-      setWrapper(impl, this);
-    }
-    Range.prototype = {
-      get startContainer() {
-        return wrap(unsafeUnwrap(this).startContainer);
-      },
-      get endContainer() {
-        return wrap(unsafeUnwrap(this).endContainer);
-      },
-      get commonAncestorContainer() {
-        return wrap(unsafeUnwrap(this).commonAncestorContainer);
-      },
-      setStart: function(refNode, offset) {
-        unsafeUnwrap(this).setStart(unwrapIfNeeded(refNode), offset);
-      },
-      setEnd: function(refNode, offset) {
-        unsafeUnwrap(this).setEnd(unwrapIfNeeded(refNode), offset);
-      },
-      setStartBefore: function(refNode) {
-        unsafeUnwrap(this).setStartBefore(unwrapIfNeeded(refNode));
-      },
-      setStartAfter: function(refNode) {
-        unsafeUnwrap(this).setStartAfter(unwrapIfNeeded(refNode));
-      },
-      setEndBefore: function(refNode) {
-        unsafeUnwrap(this).setEndBefore(unwrapIfNeeded(refNode));
-      },
-      setEndAfter: function(refNode) {
-        unsafeUnwrap(this).setEndAfter(unwrapIfNeeded(refNode));
-      },
-      selectNode: function(refNode) {
-        unsafeUnwrap(this).selectNode(unwrapIfNeeded(refNode));
-      },
-      selectNodeContents: function(refNode) {
-        unsafeUnwrap(this).selectNodeContents(unwrapIfNeeded(refNode));
-      },
-      compareBoundaryPoints: function(how, sourceRange) {
-        return unsafeUnwrap(this).compareBoundaryPoints(how, unwrap(sourceRange));
-      },
-      extractContents: function() {
-        return wrap(unsafeUnwrap(this).extractContents());
-      },
-      cloneContents: function() {
-        return wrap(unsafeUnwrap(this).cloneContents());
-      },
-      insertNode: function(node) {
-        unsafeUnwrap(this).insertNode(unwrapIfNeeded(node));
-      },
-      surroundContents: function(newParent) {
-        unsafeUnwrap(this).surroundContents(unwrapIfNeeded(newParent));
-      },
-      cloneRange: function() {
-        return wrap(unsafeUnwrap(this).cloneRange());
-      },
-      isPointInRange: function(node, offset) {
-        return unsafeUnwrap(this).isPointInRange(unwrapIfNeeded(node), offset);
-      },
-      comparePoint: function(node, offset) {
-        return unsafeUnwrap(this).comparePoint(unwrapIfNeeded(node), offset);
-      },
-      intersectsNode: function(node) {
-        return unsafeUnwrap(this).intersectsNode(unwrapIfNeeded(node));
-      },
-      toString: function() {
-        return unsafeUnwrap(this).toString();
-      }
-    };
-    if (OriginalRange.prototype.createContextualFragment) {
-      Range.prototype.createContextualFragment = function(html) {
-        return wrap(unsafeUnwrap(this).createContextualFragment(html));
-      };
-    }
-    registerWrapper(window.Range, Range, document.createRange());
-    scope.wrappers.Range = Range;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var GetElementsByInterface = scope.GetElementsByInterface;
-    var ParentNodeInterface = scope.ParentNodeInterface;
-    var SelectorsInterface = scope.SelectorsInterface;
-    var mixin = scope.mixin;
-    var registerObject = scope.registerObject;
-    var DocumentFragment = registerObject(document.createDocumentFragment());
-    mixin(DocumentFragment.prototype, ParentNodeInterface);
-    mixin(DocumentFragment.prototype, SelectorsInterface);
-    mixin(DocumentFragment.prototype, GetElementsByInterface);
-    var Comment = registerObject(document.createComment(""));
-    scope.wrappers.Comment = Comment;
-    scope.wrappers.DocumentFragment = DocumentFragment;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var DocumentFragment = scope.wrappers.DocumentFragment;
-    var TreeScope = scope.TreeScope;
-    var elementFromPoint = scope.elementFromPoint;
-    var getInnerHTML = scope.getInnerHTML;
-    var getTreeScope = scope.getTreeScope;
-    var mixin = scope.mixin;
-    var rewrap = scope.rewrap;
-    var setInnerHTML = scope.setInnerHTML;
-    var unsafeUnwrap = scope.unsafeUnwrap;
-    var unwrap = scope.unwrap;
-    var shadowHostTable = new WeakMap();
-    var nextOlderShadowTreeTable = new WeakMap();
-    var spaceCharRe = /[ \t\n\r\f]/;
-    function ShadowRoot(hostWrapper) {
-      var node = unwrap(unsafeUnwrap(hostWrapper).ownerDocument.createDocumentFragment());
-      DocumentFragment.call(this, node);
-      rewrap(node, this);
-      var oldShadowRoot = hostWrapper.shadowRoot;
-      nextOlderShadowTreeTable.set(this, oldShadowRoot);
-      this.treeScope_ = new TreeScope(this, getTreeScope(oldShadowRoot || hostWrapper));
-      shadowHostTable.set(this, hostWrapper);
-    }
-    ShadowRoot.prototype = Object.create(DocumentFragment.prototype);
-    mixin(ShadowRoot.prototype, {
-      constructor: ShadowRoot,
-      get innerHTML() {
-        return getInnerHTML(this);
-      },
-      set innerHTML(value) {
-        setInnerHTML(this, value);
-        this.invalidateShadowRenderer();
-      },
-      get olderShadowRoot() {
-        return nextOlderShadowTreeTable.get(this) || null;
-      },
-      get host() {
-        return shadowHostTable.get(this) || null;
-      },
-      invalidateShadowRenderer: function() {
-        return shadowHostTable.get(this).invalidateShadowRenderer();
-      },
-      elementFromPoint: function(x, y) {
-        return elementFromPoint(this, this.ownerDocument, x, y);
-      },
-      getElementById: function(id) {
-        if (spaceCharRe.test(id)) return null;
-        return this.querySelector('[id="' + id + '"]');
-      }
-    });
-    scope.wrappers.ShadowRoot = ShadowRoot;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var Element = scope.wrappers.Element;
-    var HTMLContentElement = scope.wrappers.HTMLContentElement;
-    var HTMLShadowElement = scope.wrappers.HTMLShadowElement;
-    var Node = scope.wrappers.Node;
-    var ShadowRoot = scope.wrappers.ShadowRoot;
-    var assert = scope.assert;
-    var getTreeScope = scope.getTreeScope;
-    var mixin = scope.mixin;
-    var oneOf = scope.oneOf;
-    var unsafeUnwrap = scope.unsafeUnwrap;
-    var unwrap = scope.unwrap;
-    var wrap = scope.wrap;
-    var ArraySplice = scope.ArraySplice;
-    function updateWrapperUpAndSideways(wrapper) {
-      wrapper.previousSibling_ = wrapper.previousSibling;
-      wrapper.nextSibling_ = wrapper.nextSibling;
-      wrapper.parentNode_ = wrapper.parentNode;
-    }
-    function updateWrapperDown(wrapper) {
-      wrapper.firstChild_ = wrapper.firstChild;
-      wrapper.lastChild_ = wrapper.lastChild;
-    }
-    function updateAllChildNodes(parentNodeWrapper) {
-      assert(parentNodeWrapper instanceof Node);
-      for (var childWrapper = parentNodeWrapper.firstChild; childWrapper; childWrapper = childWrapper.nextSibling) {
-        updateWrapperUpAndSideways(childWrapper);
-      }
-      updateWrapperDown(parentNodeWrapper);
-    }
-    function insertBefore(parentNodeWrapper, newChildWrapper, refChildWrapper) {
-      var parentNode = unwrap(parentNodeWrapper);
-      var newChild = unwrap(newChildWrapper);
-      var refChild = refChildWrapper ? unwrap(refChildWrapper) : null;
-      remove(newChildWrapper);
-      updateWrapperUpAndSideways(newChildWrapper);
-      if (!refChildWrapper) {
-        parentNodeWrapper.lastChild_ = parentNodeWrapper.lastChild;
-        if (parentNodeWrapper.lastChild === parentNodeWrapper.firstChild) parentNodeWrapper.firstChild_ = parentNodeWrapper.firstChild;
-        var lastChildWrapper = wrap(parentNode.lastChild);
-        if (lastChildWrapper) lastChildWrapper.nextSibling_ = lastChildWrapper.nextSibling;
-      } else {
-        if (parentNodeWrapper.firstChild === refChildWrapper) parentNodeWrapper.firstChild_ = refChildWrapper;
-        refChildWrapper.previousSibling_ = refChildWrapper.previousSibling;
-      }
-      scope.originalInsertBefore.call(parentNode, newChild, refChild);
-    }
-    function remove(nodeWrapper) {
-      var node = unwrap(nodeWrapper);
-      var parentNode = node.parentNode;
-      if (!parentNode) return;
-      var parentNodeWrapper = wrap(parentNode);
-      updateWrapperUpAndSideways(nodeWrapper);
-      if (nodeWrapper.previousSibling) nodeWrapper.previousSibling.nextSibling_ = nodeWrapper;
-      if (nodeWrapper.nextSibling) nodeWrapper.nextSibling.previousSibling_ = nodeWrapper;
-      if (parentNodeWrapper.lastChild === nodeWrapper) parentNodeWrapper.lastChild_ = nodeWrapper;
-      if (parentNodeWrapper.firstChild === nodeWrapper) parentNodeWrapper.firstChild_ = nodeWrapper;
-      scope.originalRemoveChild.call(parentNode, node);
-    }
-    var distributedNodesTable = new WeakMap();
-    var destinationInsertionPointsTable = new WeakMap();
-    var rendererForHostTable = new WeakMap();
-    function resetDistributedNodes(insertionPoint) {
-      distributedNodesTable.set(insertionPoint, []);
-    }
-    function getDistributedNodes(insertionPoint) {
-      var rv = distributedNodesTable.get(insertionPoint);
-      if (!rv) distributedNodesTable.set(insertionPoint, rv = []);
-      return rv;
-    }
-    function getChildNodesSnapshot(node) {
-      var result = [], i = 0;
-      for (var child = node.firstChild; child; child = child.nextSibling) {
-        result[i++] = child;
-      }
-      return result;
-    }
-    var request = oneOf(window, [ "requestAnimationFrame", "mozRequestAnimationFrame", "webkitRequestAnimationFrame", "setTimeout" ]);
-    var pendingDirtyRenderers = [];
-    var renderTimer;
-    function renderAllPending() {
-      for (var i = 0; i < pendingDirtyRenderers.length; i++) {
-        var renderer = pendingDirtyRenderers[i];
-        var parentRenderer = renderer.parentRenderer;
-        if (parentRenderer && parentRenderer.dirty) continue;
-        renderer.render();
-      }
-      pendingDirtyRenderers = [];
-    }
-    function handleRequestAnimationFrame() {
-      renderTimer = null;
-      renderAllPending();
-    }
-    function getRendererForHost(host) {
-      var renderer = rendererForHostTable.get(host);
-      if (!renderer) {
-        renderer = new ShadowRenderer(host);
-        rendererForHostTable.set(host, renderer);
-      }
-      return renderer;
-    }
-    function getShadowRootAncestor(node) {
-      var root = getTreeScope(node).root;
-      if (root instanceof ShadowRoot) return root;
-      return null;
-    }
-    function getRendererForShadowRoot(shadowRoot) {
-      return getRendererForHost(shadowRoot.host);
-    }
-    var spliceDiff = new ArraySplice();
-    spliceDiff.equals = function(renderNode, rawNode) {
-      return unwrap(renderNode.node) === rawNode;
-    };
-    function RenderNode(node) {
-      this.skip = false;
-      this.node = node;
-      this.childNodes = [];
-    }
-    RenderNode.prototype = {
-      append: function(node) {
-        var rv = new RenderNode(node);
-        this.childNodes.push(rv);
-        return rv;
-      },
-      sync: function(opt_added) {
-        if (this.skip) return;
-        var nodeWrapper = this.node;
-        var newChildren = this.childNodes;
-        var oldChildren = getChildNodesSnapshot(unwrap(nodeWrapper));
-        var added = opt_added || new WeakMap();
-        var splices = spliceDiff.calculateSplices(newChildren, oldChildren);
-        var newIndex = 0, oldIndex = 0;
-        var lastIndex = 0;
-        for (var i = 0; i < splices.length; i++) {
-          var splice = splices[i];
-          for (;lastIndex < splice.index; lastIndex++) {
-            oldIndex++;
-            newChildren[newIndex++].sync(added);
-          }
-          var removedCount = splice.removed.length;
-          for (var j = 0; j < removedCount; j++) {
-            var wrapper = wrap(oldChildren[oldIndex++]);
-            if (!added.get(wrapper)) remove(wrapper);
-          }
-          var addedCount = splice.addedCount;
-          var refNode = oldChildren[oldIndex] && wrap(oldChildren[oldIndex]);
-          for (var j = 0; j < addedCount; j++) {
-            var newChildRenderNode = newChildren[newIndex++];
-            var newChildWrapper = newChildRenderNode.node;
-            insertBefore(nodeWrapper, newChildWrapper, refNode);
-            added.set(newChildWrapper, true);
-            newChildRenderNode.sync(added);
-          }
-          lastIndex += addedCount;
-        }
-        for (var i = lastIndex; i < newChildren.length; i++) {
-          newChildren[i].sync(added);
-        }
-      }
-    };
-    function ShadowRenderer(host) {
-      this.host = host;
-      this.dirty = false;
-      this.invalidateAttributes();
-      this.associateNode(host);
-    }
-    ShadowRenderer.prototype = {
-      render: function(opt_renderNode) {
-        if (!this.dirty) return;
-        this.invalidateAttributes();
-        var host = this.host;
-        this.distribution(host);
-        var renderNode = opt_renderNode || new RenderNode(host);
-        this.buildRenderTree(renderNode, host);
-        var topMostRenderer = !opt_renderNode;
-        if (topMostRenderer) renderNode.sync();
-        this.dirty = false;
-      },
-      get parentRenderer() {
-        return getTreeScope(this.host).renderer;
-      },
-      invalidate: function() {
-        if (!this.dirty) {
-          this.dirty = true;
-          var parentRenderer = this.parentRenderer;
-          if (parentRenderer) parentRenderer.invalidate();
-          pendingDirtyRenderers.push(this);
-          if (renderTimer) return;
-          renderTimer = window[request](handleRequestAnimationFrame, 0);
-        }
-      },
-      distribution: function(root) {
-        this.resetAllSubtrees(root);
-        this.distributionResolution(root);
-      },
-      resetAll: function(node) {
-        if (isInsertionPoint(node)) resetDistributedNodes(node); else resetDestinationInsertionPoints(node);
-        this.resetAllSubtrees(node);
-      },
-      resetAllSubtrees: function(node) {
-        for (var child = node.firstChild; child; child = child.nextSibling) {
-          this.resetAll(child);
-        }
-        if (node.shadowRoot) this.resetAll(node.shadowRoot);
-        if (node.olderShadowRoot) this.resetAll(node.olderShadowRoot);
-      },
-      distributionResolution: function(node) {
-        if (isShadowHost(node)) {
-          var shadowHost = node;
-          var pool = poolPopulation(shadowHost);
-          var shadowTrees = getShadowTrees(shadowHost);
-          for (var i = 0; i < shadowTrees.length; i++) {
-            this.poolDistribution(shadowTrees[i], pool);
-          }
-          for (var i = shadowTrees.length - 1; i >= 0; i--) {
-            var shadowTree = shadowTrees[i];
-            var shadow = getShadowInsertionPoint(shadowTree);
-            if (shadow) {
-              var olderShadowRoot = shadowTree.olderShadowRoot;
-              if (olderShadowRoot) {
-                pool = poolPopulation(olderShadowRoot);
-              }
-              for (var j = 0; j < pool.length; j++) {
-                destributeNodeInto(pool[j], shadow);
-              }
-            }
-            this.distributionResolution(shadowTree);
-          }
-        }
-        for (var child = node.firstChild; child; child = child.nextSibling) {
-          this.distributionResolution(child);
-        }
-      },
-      poolDistribution: function(node, pool) {
-        if (node instanceof HTMLShadowElement) return;
-        if (node instanceof HTMLContentElement) {
-          var content = node;
-          this.updateDependentAttributes(content.getAttribute("select"));
-          var anyDistributed = false;
-          for (var i = 0; i < pool.length; i++) {
-            var node = pool[i];
-            if (!node) continue;
-            if (matches(node, content)) {
-              destributeNodeInto(node, content);
-              pool[i] = undefined;
-              anyDistributed = true;
-            }
-          }
-          if (!anyDistributed) {
-            for (var child = content.firstChild; child; child = child.nextSibling) {
-              destributeNodeInto(child, content);
-            }
-          }
-          return;
-        }
-        for (var child = node.firstChild; child; child = child.nextSibling) {
-          this.poolDistribution(child, pool);
-        }
-      },
-      buildRenderTree: function(renderNode, node) {
-        var children = this.compose(node);
-        for (var i = 0; i < children.length; i++) {
-          var child = children[i];
-          var childRenderNode = renderNode.append(child);
-          this.buildRenderTree(childRenderNode, child);
-        }
-        if (isShadowHost(node)) {
-          var renderer = getRendererForHost(node);
-          renderer.dirty = false;
-        }
-      },
-      compose: function(node) {
-        var children = [];
-        var p = node.shadowRoot || node;
-        for (var child = p.firstChild; child; child = child.nextSibling) {
-          if (isInsertionPoint(child)) {
-            this.associateNode(p);
-            var distributedNodes = getDistributedNodes(child);
-            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;
-      },
-      invalidateAttributes: function() {
-        this.attributes = Object.create(null);
-      },
-      updateDependentAttributes: function(selector) {
-        if (!selector) return;
-        var attributes = this.attributes;
-        if (/\.\w+/.test(selector)) attributes["class"] = true;
-        if (/#\w+/.test(selector)) attributes["id"] = true;
-        selector.replace(/\[\s*([^\s=\|~\]]+)/g, function(_, name) {
-          attributes[name] = true;
-        });
-      },
-      dependsOnAttribute: function(name) {
-        return this.attributes[name];
-      },
-      associateNode: function(node) {
-        unsafeUnwrap(node).polymerShadowRenderer_ = this;
-      }
-    };
-    function poolPopulation(node) {
-      var pool = [];
-      for (var child = node.firstChild; child; child = child.nextSibling) {
-        if (isInsertionPoint(child)) {
-          pool.push.apply(pool, getDistributedNodes(child));
-        } else {
-          pool.push(child);
-        }
-      }
-      return pool;
-    }
-    function getShadowInsertionPoint(node) {
-      if (node instanceof HTMLShadowElement) return node;
-      if (node instanceof HTMLContentElement) return null;
-      for (var child = node.firstChild; child; child = child.nextSibling) {
-        var res = getShadowInsertionPoint(child);
-        if (res) return res;
-      }
-      return null;
-    }
-    function destributeNodeInto(child, insertionPoint) {
-      getDistributedNodes(insertionPoint).push(child);
-      var points = destinationInsertionPointsTable.get(child);
-      if (!points) destinationInsertionPointsTable.set(child, [ insertionPoint ]); else points.push(insertionPoint);
-    }
-    function getDestinationInsertionPoints(node) {
-      return destinationInsertionPointsTable.get(node);
-    }
-    function resetDestinationInsertionPoints(node) {
-      destinationInsertionPointsTable.set(node, undefined);
-    }
-    var selectorStartCharRe = /^(:not\()?[*.#[a-zA-Z_|]/;
-    function matches(node, contentElement) {
-      var select = contentElement.getAttribute("select");
-      if (!select) return true;
-      select = select.trim();
-      if (!select) return true;
-      if (!(node instanceof Element)) return false;
-      if (!selectorStartCharRe.test(select)) return false;
-      try {
-        return node.matches(select);
-      } catch (ex) {
-        return false;
-      }
-    }
-    function isFinalDestination(insertionPoint, node) {
-      var points = getDestinationInsertionPoints(node);
-      return points && points[points.length - 1] === insertionPoint;
-    }
-    function isInsertionPoint(node) {
-      return node instanceof HTMLContentElement || node instanceof HTMLShadowElement;
-    }
-    function isShadowHost(shadowHost) {
-      return shadowHost.shadowRoot;
-    }
-    function getShadowTrees(host) {
-      var trees = [];
-      for (var tree = host.shadowRoot; tree; tree = tree.olderShadowRoot) {
-        trees.push(tree);
-      }
-      return trees;
-    }
-    function render(host) {
-      new ShadowRenderer(host).render();
-    }
-    Node.prototype.invalidateShadowRenderer = function(force) {
-      var renderer = unsafeUnwrap(this).polymerShadowRenderer_;
-      if (renderer) {
-        renderer.invalidate();
-        return true;
-      }
-      return false;
-    };
-    HTMLContentElement.prototype.getDistributedNodes = HTMLShadowElement.prototype.getDistributedNodes = function() {
-      renderAllPending();
-      return getDistributedNodes(this);
-    };
-    Element.prototype.getDestinationInsertionPoints = function() {
-      renderAllPending();
-      return getDestinationInsertionPoints(this) || [];
-    };
-    HTMLContentElement.prototype.nodeIsInserted_ = HTMLShadowElement.prototype.nodeIsInserted_ = function() {
-      this.invalidateShadowRenderer();
-      var shadowRoot = getShadowRootAncestor(this);
-      var renderer;
-      if (shadowRoot) renderer = getRendererForShadowRoot(shadowRoot);
-      unsafeUnwrap(this).polymerShadowRenderer_ = renderer;
-      if (renderer) renderer.invalidate();
-    };
-    scope.getRendererForHost = getRendererForHost;
-    scope.getShadowTrees = getShadowTrees;
-    scope.renderAllPending = renderAllPending;
-    scope.getDestinationInsertionPoints = getDestinationInsertionPoints;
-    scope.visual = {
-      insertBefore: insertBefore,
-      remove: remove
-    };
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var HTMLElement = scope.wrappers.HTMLElement;
-    var assert = scope.assert;
-    var mixin = scope.mixin;
-    var registerWrapper = scope.registerWrapper;
-    var unwrap = scope.unwrap;
-    var wrap = scope.wrap;
-    var elementsWithFormProperty = [ "HTMLButtonElement", "HTMLFieldSetElement", "HTMLInputElement", "HTMLKeygenElement", "HTMLLabelElement", "HTMLLegendElement", "HTMLObjectElement", "HTMLOutputElement", "HTMLTextAreaElement" ];
-    function createWrapperConstructor(name) {
-      if (!window[name]) return;
-      assert(!scope.wrappers[name]);
-      var GeneratedWrapper = function(node) {
-        HTMLElement.call(this, node);
-      };
-      GeneratedWrapper.prototype = Object.create(HTMLElement.prototype);
-      mixin(GeneratedWrapper.prototype, {
-        get form() {
-          return wrap(unwrap(this).form);
-        }
-      });
-      registerWrapper(window[name], GeneratedWrapper, document.createElement(name.slice(4, -7)));
-      scope.wrappers[name] = GeneratedWrapper;
-    }
-    elementsWithFormProperty.forEach(createWrapperConstructor);
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var registerWrapper = scope.registerWrapper;
-    var setWrapper = scope.setWrapper;
-    var unsafeUnwrap = scope.unsafeUnwrap;
-    var unwrap = scope.unwrap;
-    var unwrapIfNeeded = scope.unwrapIfNeeded;
-    var wrap = scope.wrap;
-    var OriginalSelection = window.Selection;
-    function Selection(impl) {
-      setWrapper(impl, this);
-    }
-    Selection.prototype = {
-      get anchorNode() {
-        return wrap(unsafeUnwrap(this).anchorNode);
-      },
-      get focusNode() {
-        return wrap(unsafeUnwrap(this).focusNode);
-      },
-      addRange: function(range) {
-        unsafeUnwrap(this).addRange(unwrap(range));
-      },
-      collapse: function(node, index) {
-        unsafeUnwrap(this).collapse(unwrapIfNeeded(node), index);
-      },
-      containsNode: function(node, allowPartial) {
-        return unsafeUnwrap(this).containsNode(unwrapIfNeeded(node), allowPartial);
-      },
-      extend: function(node, offset) {
-        unsafeUnwrap(this).extend(unwrapIfNeeded(node), offset);
-      },
-      getRangeAt: function(index) {
-        return wrap(unsafeUnwrap(this).getRangeAt(index));
-      },
-      removeRange: function(range) {
-        unsafeUnwrap(this).removeRange(unwrap(range));
-      },
-      selectAllChildren: function(node) {
-        unsafeUnwrap(this).selectAllChildren(unwrapIfNeeded(node));
-      },
-      toString: function() {
-        return unsafeUnwrap(this).toString();
-      }
-    };
-    registerWrapper(window.Selection, Selection, window.getSelection());
-    scope.wrappers.Selection = Selection;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var GetElementsByInterface = scope.GetElementsByInterface;
-    var Node = scope.wrappers.Node;
-    var ParentNodeInterface = scope.ParentNodeInterface;
-    var Selection = scope.wrappers.Selection;
-    var SelectorsInterface = scope.SelectorsInterface;
-    var ShadowRoot = scope.wrappers.ShadowRoot;
-    var TreeScope = scope.TreeScope;
-    var cloneNode = scope.cloneNode;
-    var defineWrapGetter = scope.defineWrapGetter;
-    var elementFromPoint = scope.elementFromPoint;
-    var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
-    var matchesNames = scope.matchesNames;
-    var mixin = scope.mixin;
-    var registerWrapper = scope.registerWrapper;
-    var renderAllPending = scope.renderAllPending;
-    var rewrap = scope.rewrap;
-    var setWrapper = scope.setWrapper;
-    var unsafeUnwrap = scope.unsafeUnwrap;
-    var unwrap = scope.unwrap;
-    var wrap = scope.wrap;
-    var wrapEventTargetMethods = scope.wrapEventTargetMethods;
-    var wrapNodeList = scope.wrapNodeList;
-    var implementationTable = new WeakMap();
-    function Document(node) {
-      Node.call(this, node);
-      this.treeScope_ = new TreeScope(this, null);
-    }
-    Document.prototype = Object.create(Node.prototype);
-    defineWrapGetter(Document, "documentElement");
-    defineWrapGetter(Document, "body");
-    defineWrapGetter(Document, "head");
-    function wrapMethod(name) {
-      var original = document[name];
-      Document.prototype[name] = function() {
-        return wrap(original.apply(unsafeUnwrap(this), arguments));
-      };
-    }
-    [ "createComment", "createDocumentFragment", "createElement", "createElementNS", "createEvent", "createEventNS", "createRange", "createTextNode", "getElementById" ].forEach(wrapMethod);
-    var originalAdoptNode = document.adoptNode;
-    function adoptNodeNoRemove(node, doc) {
-      originalAdoptNode.call(unsafeUnwrap(doc), unwrap(node));
-      adoptSubtree(node, doc);
-    }
-    function adoptSubtree(node, doc) {
-      if (node.shadowRoot) doc.adoptNode(node.shadowRoot);
-      if (node instanceof ShadowRoot) adoptOlderShadowRoots(node, doc);
-      for (var child = node.firstChild; child; child = child.nextSibling) {
-        adoptSubtree(child, doc);
-      }
-    }
-    function adoptOlderShadowRoots(shadowRoot, doc) {
-      var oldShadowRoot = shadowRoot.olderShadowRoot;
-      if (oldShadowRoot) doc.adoptNode(oldShadowRoot);
-    }
-    var originalGetSelection = document.getSelection;
-    mixin(Document.prototype, {
-      adoptNode: function(node) {
-        if (node.parentNode) node.parentNode.removeChild(node);
-        adoptNodeNoRemove(node, this);
-        return node;
-      },
-      elementFromPoint: function(x, y) {
-        return elementFromPoint(this, this, x, y);
-      },
-      importNode: function(node, deep) {
-        return cloneNode(node, deep, unsafeUnwrap(this));
-      },
-      getSelection: function() {
-        renderAllPending();
-        return new Selection(originalGetSelection.call(unwrap(this)));
-      },
-      getElementsByName: function(name) {
-        return SelectorsInterface.querySelectorAll.call(this, "[name=" + JSON.stringify(String(name)) + "]");
-      }
-    });
-    if (document.registerElement) {
-      var originalRegisterElement = document.registerElement;
-      Document.prototype.registerElement = function(tagName, object) {
-        var prototype, extendsOption;
-        if (object !== undefined) {
-          prototype = object.prototype;
-          extendsOption = object.extends;
-        }
-        if (!prototype) prototype = Object.create(HTMLElement.prototype);
-        if (scope.nativePrototypeTable.get(prototype)) {
-          throw new Error("NotSupportedError");
-        }
-        var proto = Object.getPrototypeOf(prototype);
-        var nativePrototype;
-        var prototypes = [];
-        while (proto) {
-          nativePrototype = scope.nativePrototypeTable.get(proto);
-          if (nativePrototype) break;
-          prototypes.push(proto);
-          proto = Object.getPrototypeOf(proto);
-        }
-        if (!nativePrototype) {
-          throw new Error("NotSupportedError");
-        }
-        var newPrototype = Object.create(nativePrototype);
-        for (var i = prototypes.length - 1; i >= 0; i--) {
-          newPrototype = Object.create(newPrototype);
-        }
-        [ "createdCallback", "attachedCallback", "detachedCallback", "attributeChangedCallback" ].forEach(function(name) {
-          var f = prototype[name];
-          if (!f) return;
-          newPrototype[name] = function() {
-            if (!(wrap(this) instanceof CustomElementConstructor)) {
-              rewrap(this);
-            }
-            f.apply(wrap(this), arguments);
-          };
-        });
-        var p = {
-          prototype: newPrototype
-        };
-        if (extendsOption) p.extends = extendsOption;
-        function CustomElementConstructor(node) {
-          if (!node) {
-            if (extendsOption) {
-              return document.createElement(extendsOption, tagName);
-            } else {
-              return document.createElement(tagName);
-            }
-          }
-          setWrapper(node, this);
-        }
-        CustomElementConstructor.prototype = prototype;
-        CustomElementConstructor.prototype.constructor = CustomElementConstructor;
-        scope.constructorTable.set(newPrototype, CustomElementConstructor);
-        scope.nativePrototypeTable.set(prototype, newPrototype);
-        var nativeConstructor = originalRegisterElement.call(unwrap(this), tagName, p);
-        return CustomElementConstructor;
-      };
-      forwardMethodsToWrapper([ window.HTMLDocument || window.Document ], [ "registerElement" ]);
-    }
-    forwardMethodsToWrapper([ window.HTMLBodyElement, window.HTMLDocument || window.Document, window.HTMLHeadElement, window.HTMLHtmlElement ], [ "appendChild", "compareDocumentPosition", "contains", "getElementsByClassName", "getElementsByTagName", "getElementsByTagNameNS", "insertBefore", "querySelector", "querySelectorAll", "removeChild", "replaceChild" ]);
-    forwardMethodsToWrapper([ window.HTMLBodyElement, window.HTMLHeadElement, window.HTMLHtmlElement ], matchesNames);
-    forwardMethodsToWrapper([ window.HTMLDocument || window.Document ], [ "adoptNode", "importNode", "contains", "createComment", "createDocumentFragment", "createElement", "createElementNS", "createEvent", "createEventNS", "createRange", "createTextNode", "elementFromPoint", "getElementById", "getElementsByName", "getSelection" ]);
-    mixin(Document.prototype, GetElementsByInterface);
-    mixin(Document.prototype, ParentNodeInterface);
-    mixin(Document.prototype, SelectorsInterface);
-    mixin(Document.prototype, {
-      get implementation() {
-        var implementation = implementationTable.get(this);
-        if (implementation) return implementation;
-        implementation = new DOMImplementation(unwrap(this).implementation);
-        implementationTable.set(this, implementation);
-        return implementation;
-      },
-      get defaultView() {
-        return wrap(unwrap(this).defaultView);
-      }
-    });
-    registerWrapper(window.Document, Document, document.implementation.createHTMLDocument(""));
-    if (window.HTMLDocument) registerWrapper(window.HTMLDocument, Document);
-    wrapEventTargetMethods([ window.HTMLBodyElement, window.HTMLDocument || window.Document, window.HTMLHeadElement ]);
-    function DOMImplementation(impl) {
-      setWrapper(impl, this);
-    }
-    function wrapImplMethod(constructor, name) {
-      var original = document.implementation[name];
-      constructor.prototype[name] = function() {
-        return wrap(original.apply(unsafeUnwrap(this), arguments));
-      };
-    }
-    function forwardImplMethod(constructor, name) {
-      var original = document.implementation[name];
-      constructor.prototype[name] = function() {
-        return original.apply(unsafeUnwrap(this), arguments);
-      };
-    }
-    wrapImplMethod(DOMImplementation, "createDocumentType");
-    wrapImplMethod(DOMImplementation, "createDocument");
-    wrapImplMethod(DOMImplementation, "createHTMLDocument");
-    forwardImplMethod(DOMImplementation, "hasFeature");
-    registerWrapper(window.DOMImplementation, DOMImplementation);
-    forwardMethodsToWrapper([ window.DOMImplementation ], [ "createDocumentType", "createDocument", "createHTMLDocument", "hasFeature" ]);
-    scope.adoptNodeNoRemove = adoptNodeNoRemove;
-    scope.wrappers.DOMImplementation = DOMImplementation;
-    scope.wrappers.Document = Document;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var EventTarget = scope.wrappers.EventTarget;
-    var Selection = scope.wrappers.Selection;
-    var mixin = scope.mixin;
-    var registerWrapper = scope.registerWrapper;
-    var renderAllPending = scope.renderAllPending;
-    var unwrap = scope.unwrap;
-    var unwrapIfNeeded = scope.unwrapIfNeeded;
-    var wrap = scope.wrap;
-    var OriginalWindow = window.Window;
-    var originalGetComputedStyle = window.getComputedStyle;
-    var originalGetDefaultComputedStyle = window.getDefaultComputedStyle;
-    var originalGetSelection = window.getSelection;
-    function Window(impl) {
-      EventTarget.call(this, impl);
-    }
-    Window.prototype = Object.create(EventTarget.prototype);
-    OriginalWindow.prototype.getComputedStyle = function(el, pseudo) {
-      return wrap(this || window).getComputedStyle(unwrapIfNeeded(el), pseudo);
-    };
-    if (originalGetDefaultComputedStyle) {
-      OriginalWindow.prototype.getDefaultComputedStyle = function(el, pseudo) {
-        return wrap(this || window).getDefaultComputedStyle(unwrapIfNeeded(el), pseudo);
-      };
-    }
-    OriginalWindow.prototype.getSelection = function() {
-      return wrap(this || window).getSelection();
-    };
-    delete window.getComputedStyle;
-    delete window.getDefaultComputedStyle;
-    delete window.getSelection;
-    [ "addEventListener", "removeEventListener", "dispatchEvent" ].forEach(function(name) {
-      OriginalWindow.prototype[name] = function() {
-        var w = wrap(this || window);
-        return w[name].apply(w, arguments);
-      };
-      delete window[name];
-    });
-    mixin(Window.prototype, {
-      getComputedStyle: function(el, pseudo) {
-        renderAllPending();
-        return originalGetComputedStyle.call(unwrap(this), unwrapIfNeeded(el), pseudo);
-      },
-      getSelection: function() {
-        renderAllPending();
-        return new Selection(originalGetSelection.call(unwrap(this)));
-      },
-      get document() {
-        return wrap(unwrap(this).document);
-      }
-    });
-    if (originalGetDefaultComputedStyle) {
-      Window.prototype.getDefaultComputedStyle = function(el, pseudo) {
-        renderAllPending();
-        return originalGetDefaultComputedStyle.call(unwrap(this), unwrapIfNeeded(el), pseudo);
-      };
-    }
-    registerWrapper(OriginalWindow, Window, window);
-    scope.wrappers.Window = Window;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var unwrap = scope.unwrap;
-    var OriginalDataTransfer = window.DataTransfer || window.Clipboard;
-    var OriginalDataTransferSetDragImage = OriginalDataTransfer.prototype.setDragImage;
-    if (OriginalDataTransferSetDragImage) {
-      OriginalDataTransfer.prototype.setDragImage = function(image, x, y) {
-        OriginalDataTransferSetDragImage.call(this, unwrap(image), x, y);
-      };
-    }
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var registerWrapper = scope.registerWrapper;
-    var setWrapper = scope.setWrapper;
-    var unwrap = scope.unwrap;
-    var OriginalFormData = window.FormData;
-    if (!OriginalFormData) return;
-    function FormData(formElement) {
-      var impl;
-      if (formElement instanceof OriginalFormData) {
-        impl = formElement;
-      } else {
-        impl = new OriginalFormData(formElement && unwrap(formElement));
-      }
-      setWrapper(impl, this);
-    }
-    registerWrapper(OriginalFormData, FormData, new OriginalFormData());
-    scope.wrappers.FormData = FormData;
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var unwrapIfNeeded = scope.unwrapIfNeeded;
-    var originalSend = XMLHttpRequest.prototype.send;
-    XMLHttpRequest.prototype.send = function(obj) {
-      return originalSend.call(this, unwrapIfNeeded(obj));
-    };
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    "use strict";
-    var isWrapperFor = scope.isWrapperFor;
-    var elements = {
-      a: "HTMLAnchorElement",
-      area: "HTMLAreaElement",
-      audio: "HTMLAudioElement",
-      base: "HTMLBaseElement",
-      body: "HTMLBodyElement",
-      br: "HTMLBRElement",
-      button: "HTMLButtonElement",
-      canvas: "HTMLCanvasElement",
-      caption: "HTMLTableCaptionElement",
-      col: "HTMLTableColElement",
-      content: "HTMLContentElement",
-      data: "HTMLDataElement",
-      datalist: "HTMLDataListElement",
-      del: "HTMLModElement",
-      dir: "HTMLDirectoryElement",
-      div: "HTMLDivElement",
-      dl: "HTMLDListElement",
-      embed: "HTMLEmbedElement",
-      fieldset: "HTMLFieldSetElement",
-      font: "HTMLFontElement",
-      form: "HTMLFormElement",
-      frame: "HTMLFrameElement",
-      frameset: "HTMLFrameSetElement",
-      h1: "HTMLHeadingElement",
-      head: "HTMLHeadElement",
-      hr: "HTMLHRElement",
-      html: "HTMLHtmlElement",
-      iframe: "HTMLIFrameElement",
-      img: "HTMLImageElement",
-      input: "HTMLInputElement",
-      keygen: "HTMLKeygenElement",
-      label: "HTMLLabelElement",
-      legend: "HTMLLegendElement",
-      li: "HTMLLIElement",
-      link: "HTMLLinkElement",
-      map: "HTMLMapElement",
-      marquee: "HTMLMarqueeElement",
-      menu: "HTMLMenuElement",
-      menuitem: "HTMLMenuItemElement",
-      meta: "HTMLMetaElement",
-      meter: "HTMLMeterElement",
-      object: "HTMLObjectElement",
-      ol: "HTMLOListElement",
-      optgroup: "HTMLOptGroupElement",
-      option: "HTMLOptionElement",
-      output: "HTMLOutputElement",
-      p: "HTMLParagraphElement",
-      param: "HTMLParamElement",
-      pre: "HTMLPreElement",
-      progress: "HTMLProgressElement",
-      q: "HTMLQuoteElement",
-      script: "HTMLScriptElement",
-      select: "HTMLSelectElement",
-      shadow: "HTMLShadowElement",
-      source: "HTMLSourceElement",
-      span: "HTMLSpanElement",
-      style: "HTMLStyleElement",
-      table: "HTMLTableElement",
-      tbody: "HTMLTableSectionElement",
-      template: "HTMLTemplateElement",
-      textarea: "HTMLTextAreaElement",
-      thead: "HTMLTableSectionElement",
-      time: "HTMLTimeElement",
-      title: "HTMLTitleElement",
-      tr: "HTMLTableRowElement",
-      track: "HTMLTrackElement",
-      ul: "HTMLUListElement",
-      video: "HTMLVideoElement"
-    };
-    function overrideConstructor(tagName) {
-      var nativeConstructorName = elements[tagName];
-      var nativeConstructor = window[nativeConstructorName];
-      if (!nativeConstructor) return;
-      var element = document.createElement(tagName);
-      var wrapperConstructor = element.constructor;
-      window[nativeConstructorName] = wrapperConstructor;
-    }
-    Object.keys(elements).forEach(overrideConstructor);
-    Object.getOwnPropertyNames(scope.wrappers).forEach(function(name) {
-      window[name] = scope.wrappers[name];
-    });
-  })(window.ShadowDOMPolyfill);
-  (function(scope) {
-    var ShadowCSS = {
-      strictStyling: false,
-      registry: {},
-      shimStyling: function(root, name, extendsName) {
-        var scopeStyles = this.prepareRoot(root, name, extendsName);
-        var typeExtension = this.isTypeExtension(extendsName);
-        var scopeSelector = this.makeScopeSelector(name, typeExtension);
-        var cssText = stylesToCssText(scopeStyles, true);
-        cssText = this.scopeCssText(cssText, scopeSelector);
-        if (root) {
-          root.shimmedStyle = cssText;
-        }
-        this.addCssToDocument(cssText, name);
-      },
-      shimStyle: function(style, selector) {
-        return this.shimCssText(style.textContent, selector);
-      },
-      shimCssText: function(cssText, selector) {
-        cssText = this.insertDirectives(cssText);
-        return this.scopeCssText(cssText, selector);
-      },
-      makeScopeSelector: function(name, typeExtension) {
-        if (name) {
-          return typeExtension ? "[is=" + name + "]" : name;
-        }
-        return "";
-      },
-      isTypeExtension: function(extendsName) {
-        return extendsName && extendsName.indexOf("-") < 0;
-      },
-      prepareRoot: function(root, name, extendsName) {
-        var def = this.registerRoot(root, name, extendsName);
-        this.replaceTextInStyles(def.rootStyles, this.insertDirectives);
-        this.removeStyles(root, def.rootStyles);
-        if (this.strictStyling) {
-          this.applyScopeToContent(root, name);
-        }
-        return def.scopeStyles;
-      },
-      removeStyles: function(root, styles) {
-        for (var i = 0, l = styles.length, s; i < l && (s = styles[i]); i++) {
-          s.parentNode.removeChild(s);
-        }
-      },
-      registerRoot: function(root, name, extendsName) {
-        var def = this.registry[name] = {
-          root: root,
-          name: name,
-          extendsName: extendsName
-        };
-        var styles = this.findStyles(root);
-        def.rootStyles = styles;
-        def.scopeStyles = def.rootStyles;
-        var extendee = this.registry[def.extendsName];
-        if (extendee) {
-          def.scopeStyles = extendee.scopeStyles.concat(def.scopeStyles);
-        }
-        return def;
-      },
-      findStyles: function(root) {
-        if (!root) {
-          return [];
-        }
-        var styles = root.querySelectorAll("style");
-        return Array.prototype.filter.call(styles, function(s) {
-          return !s.hasAttribute(NO_SHIM_ATTRIBUTE);
-        });
-      },
-      applyScopeToContent: function(root, name) {
-        if (root) {
-          Array.prototype.forEach.call(root.querySelectorAll("*"), function(node) {
-            node.setAttribute(name, "");
-          });
-          Array.prototype.forEach.call(root.querySelectorAll("template"), function(template) {
-            this.applyScopeToContent(template.content, name);
-          }, this);
-        }
-      },
-      insertDirectives: function(cssText) {
-        cssText = this.insertPolyfillDirectivesInCssText(cssText);
-        return this.insertPolyfillRulesInCssText(cssText);
-      },
-      insertPolyfillDirectivesInCssText: function(cssText) {
-        cssText = cssText.replace(cssCommentNextSelectorRe, function(match, p1) {
-          return p1.slice(0, -2) + "{";
-        });
-        return cssText.replace(cssContentNextSelectorRe, function(match, p1) {
-          return p1 + " {";
-        });
-      },
-      insertPolyfillRulesInCssText: function(cssText) {
-        cssText = cssText.replace(cssCommentRuleRe, function(match, p1) {
-          return p1.slice(0, -1);
-        });
-        return cssText.replace(cssContentRuleRe, function(match, p1, p2, p3) {
-          var rule = match.replace(p1, "").replace(p2, "");
-          return p3 + rule;
-        });
-      },
-      scopeCssText: function(cssText, scopeSelector) {
-        var unscoped = this.extractUnscopedRulesFromCssText(cssText);
-        cssText = this.insertPolyfillHostInCssText(cssText);
-        cssText = this.convertColonHost(cssText);
-        cssText = this.convertColonHostContext(cssText);
-        cssText = this.convertShadowDOMSelectors(cssText);
-        if (scopeSelector) {
-          var self = this, cssText;
-          withCssRules(cssText, function(rules) {
-            cssText = self.scopeRules(rules, scopeSelector);
-          });
-        }
-        cssText = cssText + "\n" + unscoped;
-        return cssText.trim();
-      },
-      extractUnscopedRulesFromCssText: function(cssText) {
-        var r = "", m;
-        while (m = cssCommentUnscopedRuleRe.exec(cssText)) {
-          r += m[1].slice(0, -1) + "\n\n";
-        }
-        while (m = cssContentUnscopedRuleRe.exec(cssText)) {
-          r += m[0].replace(m[2], "").replace(m[1], m[3]) + "\n\n";
-        }
-        return r;
-      },
-      convertColonHost: function(cssText) {
-        return this.convertColonRule(cssText, cssColonHostRe, this.colonHostPartReplacer);
-      },
-      convertColonHostContext: function(cssText) {
-        return this.convertColonRule(cssText, cssColonHostContextRe, this.colonHostContextPartReplacer);
-      },
-      convertColonRule: function(cssText, regExp, partReplacer) {
-        return cssText.replace(regExp, function(m, p1, p2, p3) {
-          p1 = polyfillHostNoCombinator;
-          if (p2) {
-            var parts = p2.split(","), r = [];
-            for (var i = 0, l = parts.length, p; i < l && (p = parts[i]); i++) {
-              p = p.trim();
-              r.push(partReplacer(p1, p, p3));
-            }
-            return r.join(",");
-          } else {
-            return p1 + p3;
-          }
-        });
-      },
-      colonHostContextPartReplacer: function(host, part, suffix) {
-        if (part.match(polyfillHost)) {
-          return this.colonHostPartReplacer(host, part, suffix);
-        } else {
-          return host + part + suffix + ", " + part + " " + host + suffix;
-        }
-      },
-      colonHostPartReplacer: function(host, part, suffix) {
-        return host + part.replace(polyfillHost, "") + suffix;
-      },
-      convertShadowDOMSelectors: function(cssText) {
-        for (var i = 0; i < shadowDOMSelectorsRe.length; i++) {
-          cssText = cssText.replace(shadowDOMSelectorsRe[i], " ");
-        }
-        return cssText;
-      },
-      scopeRules: function(cssRules, scopeSelector) {
-        var cssText = "";
-        if (cssRules) {
-          Array.prototype.forEach.call(cssRules, function(rule) {
-            if (rule.selectorText && (rule.style && rule.style.cssText !== undefined)) {
-              cssText += this.scopeSelector(rule.selectorText, scopeSelector, this.strictStyling) + " {\n	";
-              cssText += this.propertiesFromRule(rule) + "\n}\n\n";
-            } else if (rule.type === CSSRule.MEDIA_RULE) {
-              cssText += "@media " + rule.media.mediaText + " {\n";
-              cssText += this.scopeRules(rule.cssRules, scopeSelector);
-              cssText += "\n}\n\n";
-            } else {
-              try {
-                if (rule.cssText) {
-                  cssText += rule.cssText + "\n\n";
-                }
-              } catch (x) {
-                if (rule.type === CSSRule.KEYFRAMES_RULE && rule.cssRules) {
-                  cssText += this.ieSafeCssTextFromKeyFrameRule(rule);
-                }
-              }
-            }
-          }, this);
-        }
-        return cssText;
-      },
-      ieSafeCssTextFromKeyFrameRule: function(rule) {
-        var cssText = "@keyframes " + rule.name + " {";
-        Array.prototype.forEach.call(rule.cssRules, function(rule) {
-          cssText += " " + rule.keyText + " {" + rule.style.cssText + "}";
-        });
-        cssText += " }";
-        return cssText;
-      },
-      scopeSelector: function(selector, scopeSelector, strict) {
-        var r = [], parts = selector.split(",");
-        parts.forEach(function(p) {
-          p = p.trim();
-          if (this.selectorNeedsScoping(p, scopeSelector)) {
-            p = strict && !p.match(polyfillHostNoCombinator) ? this.applyStrictSelectorScope(p, scopeSelector) : this.applySelectorScope(p, scopeSelector);
-          }
-          r.push(p);
-        }, this);
-        return r.join(", ");
-      },
-      selectorNeedsScoping: function(selector, scopeSelector) {
-        if (Array.isArray(scopeSelector)) {
-          return true;
-        }
-        var re = this.makeScopeMatcher(scopeSelector);
-        return !selector.match(re);
-      },
-      makeScopeMatcher: function(scopeSelector) {
-        scopeSelector = scopeSelector.replace(/\[/g, "\\[").replace(/\]/g, "\\]");
-        return new RegExp("^(" + scopeSelector + ")" + selectorReSuffix, "m");
-      },
-      applySelectorScope: function(selector, selectorScope) {
-        return Array.isArray(selectorScope) ? this.applySelectorScopeList(selector, selectorScope) : this.applySimpleSelectorScope(selector, selectorScope);
-      },
-      applySelectorScopeList: function(selector, scopeSelectorList) {
-        var r = [];
-        for (var i = 0, s; s = scopeSelectorList[i]; i++) {
-          r.push(this.applySimpleSelectorScope(selector, s));
-        }
-        return r.join(", ");
-      },
-      applySimpleSelectorScope: function(selector, scopeSelector) {
-        if (selector.match(polyfillHostRe)) {
-          selector = selector.replace(polyfillHostNoCombinator, scopeSelector);
-          return selector.replace(polyfillHostRe, scopeSelector + " ");
-        } else {
-          return scopeSelector + " " + selector;
-        }
-      },
-      applyStrictSelectorScope: function(selector, scopeSelector) {
-        scopeSelector = scopeSelector.replace(/\[is=([^\]]*)\]/g, "$1");
-        var splits = [ " ", ">", "+", "~" ], scoped = selector, attrName = "[" + scopeSelector + "]";
-        splits.forEach(function(sep) {
-          var parts = scoped.split(sep);
-          scoped = parts.map(function(p) {
-            var t = p.trim().replace(polyfillHostRe, "");
-            if (t && splits.indexOf(t) < 0 && t.indexOf(attrName) < 0) {
-              p = t.replace(/([^:]*)(:*)(.*)/, "$1" + attrName + "$2$3");
-            }
-            return p;
-          }).join(sep);
-        });
-        return scoped;
-      },
-      insertPolyfillHostInCssText: function(selector) {
-        return selector.replace(colonHostContextRe, polyfillHostContext).replace(colonHostRe, polyfillHost);
-      },
-      propertiesFromRule: function(rule) {
-        var cssText = rule.style.cssText;
-        if (rule.style.content && !rule.style.content.match(/['"]+|attr/)) {
-          cssText = cssText.replace(/content:[^;]*;/g, "content: '" + rule.style.content + "';");
-        }
-        var style = rule.style;
-        for (var i in style) {
-          if (style[i] === "initial") {
-            cssText += i + ": initial; ";
-          }
-        }
-        return cssText;
-      },
-      replaceTextInStyles: function(styles, action) {
-        if (styles && action) {
-          if (!(styles instanceof Array)) {
-            styles = [ styles ];
-          }
-          Array.prototype.forEach.call(styles, function(s) {
-            s.textContent = action.call(this, s.textContent);
-          }, this);
-        }
-      },
-      addCssToDocument: function(cssText, name) {
-        if (cssText.match("@import")) {
-          addOwnSheet(cssText, name);
-        } else {
-          addCssToDocument(cssText);
-        }
-      }
-    };
-    var selectorRe = /([^{]*)({[\s\S]*?})/gim, cssCommentRe = /\/\*[^*]*\*+([^/*][^*]*\*+)*\//gim, cssCommentNextSelectorRe = /\/\*\s*@polyfill ([^*]*\*+([^/*][^*]*\*+)*\/)([^{]*?){/gim, cssContentNextSelectorRe = /polyfill-next-selector[^}]*content\:[\s]*?['"](.*?)['"][;\s]*}([^{]*?){/gim, cssCommentRuleRe = /\/\*\s@polyfill-rule([^*]*\*+([^/*][^*]*\*+)*)\//gim, cssContentRuleRe = /(polyfill-rule)[^}]*(content\:[\s]*['"](.*?)['"])[;\s]*[^}]*}/gim, cssCommentUnscopedRuleRe = /\/\*\s@polyfill-unscoped-rule([^*]*\*+([^/*][^*]*\*+)*)\//gim, cssContentUnscopedRuleRe = /(polyfill-unscoped-rule)[^}]*(content\:[\s]*['"](.*?)['"])[;\s]*[^}]*}/gim, cssPseudoRe = /::(x-[^\s{,(]*)/gim, cssPartRe = /::part\(([^)]*)\)/gim, polyfillHost = "-shadowcsshost", polyfillHostContext = "-shadowcsscontext", parenSuffix = ")(?:\\((" + "(?:\\([^)(]*\\)|[^)(]*)+?" + ")\\))?([^,{]*)";
-    var cssColonHostRe = new RegExp("(" + polyfillHost + parenSuffix, "gim"), cssColonHostContextRe = new RegExp("(" + polyfillHostContext + parenSuffix, "gim"), selectorReSuffix = "([>\\s~+[.,{:][\\s\\S]*)?$", colonHostRe = /\:host/gim, colonHostContextRe = /\:host-context/gim, polyfillHostNoCombinator = polyfillHost + "-no-combinator", polyfillHostRe = new RegExp(polyfillHost, "gim"), polyfillHostContextRe = new RegExp(polyfillHostContext, "gim"), shadowDOMSelectorsRe = [ /\^\^/g, /\^/g, /\/shadow\//g, /\/shadow-deep\//g, /::shadow/g, /\/deep\//g, /::content/g ];
-    function stylesToCssText(styles, preserveComments) {
-      var cssText = "";
-      Array.prototype.forEach.call(styles, function(s) {
-        cssText += s.textContent + "\n\n";
-      });
-      if (!preserveComments) {
-        cssText = cssText.replace(cssCommentRe, "");
-      }
-      return cssText;
-    }
-    function cssTextToStyle(cssText) {
-      var style = document.createElement("style");
-      style.textContent = cssText;
-      return style;
-    }
-    function cssToRules(cssText) {
-      var style = cssTextToStyle(cssText);
-      document.head.appendChild(style);
-      var rules = [];
-      if (style.sheet) {
-        try {
-          rules = style.sheet.cssRules;
-        } catch (e) {}
-      } else {
-        console.warn("sheet not found", style);
-      }
-      style.parentNode.removeChild(style);
-      return rules;
-    }
-    var frame = document.createElement("iframe");
-    frame.style.display = "none";
-    function initFrame() {
-      frame.initialized = true;
-      document.body.appendChild(frame);
-      var doc = frame.contentDocument;
-      var base = doc.createElement("base");
-      base.href = document.baseURI;
-      doc.head.appendChild(base);
-    }
-    function inFrame(fn) {
-      if (!frame.initialized) {
-        initFrame();
-      }
-      document.body.appendChild(frame);
-      fn(frame.contentDocument);
-      document.body.removeChild(frame);
-    }
-    var isChrome = navigator.userAgent.match("Chrome");
-    function withCssRules(cssText, callback) {
-      if (!callback) {
-        return;
-      }
-      var rules;
-      if (cssText.match("@import") && isChrome) {
-        var style = cssTextToStyle(cssText);
-        inFrame(function(doc) {
-          doc.head.appendChild(style.impl);
-          rules = Array.prototype.slice.call(style.sheet.cssRules, 0);
-          callback(rules);
-        });
-      } else {
-        rules = cssToRules(cssText);
-        callback(rules);
-      }
-    }
-    function rulesToCss(cssRules) {
-      for (var i = 0, css = []; i < cssRules.length; i++) {
-        css.push(cssRules[i].cssText);
-      }
-      return css.join("\n\n");
-    }
-    function addCssToDocument(cssText) {
-      if (cssText) {
-        getSheet().appendChild(document.createTextNode(cssText));
-      }
-    }
-    function addOwnSheet(cssText, name) {
-      var style = cssTextToStyle(cssText);
-      style.setAttribute(name, "");
-      style.setAttribute(SHIMMED_ATTRIBUTE, "");
-      document.head.appendChild(style);
-    }
-    var SHIM_ATTRIBUTE = "shim-shadowdom";
-    var SHIMMED_ATTRIBUTE = "shim-shadowdom-css";
-    var NO_SHIM_ATTRIBUTE = "no-shim";
-    var sheet;
-    function getSheet() {
-      if (!sheet) {
-        sheet = document.createElement("style");
-        sheet.setAttribute(SHIMMED_ATTRIBUTE, "");
-        sheet[SHIMMED_ATTRIBUTE] = true;
-      }
-      return sheet;
-    }
-    if (window.ShadowDOMPolyfill) {
-      addCssToDocument("style { display: none !important; }\n");
-      var doc = ShadowDOMPolyfill.wrap(document);
-      var head = doc.querySelector("head");
-      head.insertBefore(getSheet(), head.childNodes[0]);
-      document.addEventListener("DOMContentLoaded", function() {
-        var urlResolver = scope.urlResolver;
-        if (window.HTMLImports && !HTMLImports.useNative) {
-          var SHIM_SHEET_SELECTOR = "link[rel=stylesheet]" + "[" + SHIM_ATTRIBUTE + "]";
-          var SHIM_STYLE_SELECTOR = "style[" + SHIM_ATTRIBUTE + "]";
-          HTMLImports.importer.documentPreloadSelectors += "," + SHIM_SHEET_SELECTOR;
-          HTMLImports.importer.importsPreloadSelectors += "," + SHIM_SHEET_SELECTOR;
-          HTMLImports.parser.documentSelectors = [ HTMLImports.parser.documentSelectors, SHIM_SHEET_SELECTOR, SHIM_STYLE_SELECTOR ].join(",");
-          var originalParseGeneric = HTMLImports.parser.parseGeneric;
-          HTMLImports.parser.parseGeneric = function(elt) {
-            if (elt[SHIMMED_ATTRIBUTE]) {
-              return;
-            }
-            var style = elt.__importElement || elt;
-            if (!style.hasAttribute(SHIM_ATTRIBUTE)) {
-              originalParseGeneric.call(this, elt);
-              return;
-            }
-            if (elt.__resource) {
-              style = elt.ownerDocument.createElement("style");
-              style.textContent = elt.__resource;
-            }
-            HTMLImports.path.resolveUrlsInStyle(style);
-            style.textContent = ShadowCSS.shimStyle(style);
-            style.removeAttribute(SHIM_ATTRIBUTE, "");
-            style.setAttribute(SHIMMED_ATTRIBUTE, "");
-            style[SHIMMED_ATTRIBUTE] = true;
-            if (style.parentNode !== head) {
-              if (elt.parentNode === head) {
-                head.replaceChild(style, elt);
-              } else {
-                this.addElementToDocument(style);
-              }
-            }
-            style.__importParsed = true;
-            this.markParsingComplete(elt);
-            this.parseNext();
-          };
-          var hasResource = HTMLImports.parser.hasResource;
-          HTMLImports.parser.hasResource = function(node) {
-            if (node.localName === "link" && node.rel === "stylesheet" && node.hasAttribute(SHIM_ATTRIBUTE)) {
-              return node.__resource;
-            } else {
-              return hasResource.call(this, node);
-            }
-          };
-        }
-      });
-    }
-    scope.ShadowCSS = ShadowCSS;
-  })(window.WebComponents);
-}
-
-(function(scope) {
-  if (window.ShadowDOMPolyfill) {
-    window.wrap = ShadowDOMPolyfill.wrapIfNeeded;
-    window.unwrap = ShadowDOMPolyfill.unwrapIfNeeded;
-  } else {
-    window.wrap = window.unwrap = function(n) {
-      return n;
-    };
-  }
-})(window.WebComponents);
-
-window.HTMLImports = window.HTMLImports || {
-  flags: {}
-};
-
-(function(scope) {
-  var IMPORT_LINK_TYPE = "import";
-  var useNative = Boolean(IMPORT_LINK_TYPE in document.createElement("link"));
-  var hasShadowDOMPolyfill = Boolean(window.ShadowDOMPolyfill);
-  var wrap = function(node) {
-    return hasShadowDOMPolyfill ? ShadowDOMPolyfill.wrapIfNeeded(node) : node;
-  };
-  var rootDocument = wrap(document);
-  var currentScriptDescriptor = {
-    get: function() {
-      var script = HTMLImports.currentScript || document.currentScript || (document.readyState !== "complete" ? document.scripts[document.scripts.length - 1] : null);
-      return wrap(script);
-    },
-    configurable: true
-  };
-  Object.defineProperty(document, "_currentScript", currentScriptDescriptor);
-  Object.defineProperty(rootDocument, "_currentScript", currentScriptDescriptor);
-  var isIE = /Trident|Edge/.test(navigator.userAgent);
-  function whenReady(callback, doc) {
-    doc = doc || rootDocument;
-    whenDocumentReady(function() {
-      watchImportsLoad(callback, doc);
-    }, doc);
-  }
-  var requiredReadyState = isIE ? "complete" : "interactive";
-  var READY_EVENT = "readystatechange";
-  function isDocumentReady(doc) {
-    return doc.readyState === "complete" || doc.readyState === requiredReadyState;
-  }
-  function whenDocumentReady(callback, doc) {
-    if (!isDocumentReady(doc)) {
-      var checkReady = function() {
-        if (doc.readyState === "complete" || doc.readyState === requiredReadyState) {
-          doc.removeEventListener(READY_EVENT, checkReady);
-          whenDocumentReady(callback, doc);
-        }
-      };
-      doc.addEventListener(READY_EVENT, checkReady);
-    } else if (callback) {
-      callback();
-    }
-  }
-  function markTargetLoaded(event) {
-    event.target.__loaded = true;
-  }
-  function watchImportsLoad(callback, doc) {
-    var imports = doc.querySelectorAll("link[rel=import]");
-    var loaded = 0, l = imports.length;
-    function checkDone(d) {
-      if (loaded == l && callback) {
-        callback();
-      }
-    }
-    function loadedImport(e) {
-      markTargetLoaded(e);
-      loaded++;
-      checkDone();
-    }
-    if (l) {
-      for (var i = 0, imp; i < l && (imp = imports[i]); i++) {
-        if (isImportLoaded(imp)) {
-          loadedImport.call(imp, {
-            target: imp
-          });
-        } else {
-          imp.addEventListener("load", loadedImport);
-          imp.addEventListener("error", loadedImport);
-        }
-      }
-    } else {
-      checkDone();
-    }
-  }
-  function isImportLoaded(link) {
-    return useNative ? link.__loaded || link.import && link.import.readyState !== "loading" : link.__importParsed;
-  }
-  if (useNative) {
-    new MutationObserver(function(mxns) {
-      for (var i = 0, l = mxns.length, m; i < l && (m = mxns[i]); i++) {
-        if (m.addedNodes) {
-          handleImports(m.addedNodes);
-        }
-      }
-    }).observe(document.head, {
-      childList: true
-    });
-    function handleImports(nodes) {
-      for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {
-        if (isImport(n)) {
-          handleImport(n);
-        }
-      }
-    }
-    function isImport(element) {
-      return element.localName === "link" && element.rel === "import";
-    }
-    function handleImport(element) {
-      var loaded = element.import;
-      if (loaded) {
-        markTargetLoaded({
-          target: element
-        });
-      } else {
-        element.addEventListener("load", markTargetLoaded);
-        element.addEventListener("error", markTargetLoaded);
-      }
-    }
-    (function() {
-      if (document.readyState === "loading") {
-        var imports = document.querySelectorAll("link[rel=import]");
-        for (var i = 0, l = imports.length, imp; i < l && (imp = imports[i]); i++) {
-          handleImport(imp);
-        }
-      }
-    })();
-  }
-  whenReady(function() {
-    HTMLImports.ready = true;
-    HTMLImports.readyTime = new Date().getTime();
-    var evt = rootDocument.createEvent("CustomEvent");
-    evt.initCustomEvent("HTMLImportsLoaded", true, true, {});
-    rootDocument.dispatchEvent(evt);
-  });
-  scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;
-  scope.useNative = useNative;
-  scope.rootDocument = rootDocument;
-  scope.whenReady = whenReady;
-  scope.isIE = isIE;
-})(HTMLImports);
-
-(function(scope) {
-  var modules = [];
-  var addModule = function(module) {
-    modules.push(module);
-  };
-  var initializeModules = function() {
-    modules.forEach(function(module) {
-      module(scope);
-    });
-  };
-  scope.addModule = addModule;
-  scope.initializeModules = initializeModules;
-})(HTMLImports);
-
-HTMLImports.addModule(function(scope) {
-  var CSS_URL_REGEXP = /(url\()([^)]*)(\))/g;
-  var CSS_IMPORT_REGEXP = /(@import[\s]+(?!url\())([^;]*)(;)/g;
-  var path = {
-    resolveUrlsInStyle: function(style) {
-      var doc = style.ownerDocument;
-      var resolver = doc.createElement("a");
-      style.textContent = this.resolveUrlsInCssText(style.textContent, resolver);
-      return style;
-    },
-    resolveUrlsInCssText: function(cssText, urlObj) {
-      var r = this.replaceUrls(cssText, urlObj, CSS_URL_REGEXP);
-      r = this.replaceUrls(r, urlObj, CSS_IMPORT_REGEXP);
-      return r;
-    },
-    replaceUrls: function(text, urlObj, regexp) {
-      return text.replace(regexp, function(m, pre, url, post) {
-        var urlPath = url.replace(/["']/g, "");
-        urlObj.href = urlPath;
-        urlPath = urlObj.href;
-        return pre + "'" + urlPath + "'" + post;
-      });
-    }
-  };
-  scope.path = path;
-});
-
-HTMLImports.addModule(function(scope) {
-  var xhr = {
-    async: true,
-    ok: function(request) {
-      return request.status >= 200 && request.status < 300 || request.status === 304 || request.status === 0;
-    },
-    load: function(url, next, nextContext) {
-      var request = new XMLHttpRequest();
-      if (scope.flags.debug || scope.flags.bust) {
-        url += "?" + Math.random();
-      }
-      request.open("GET", url, xhr.async);
-      request.addEventListener("readystatechange", function(e) {
-        if (request.readyState === 4) {
-          var locationHeader = request.getResponseHeader("Location");
-          var redirectedUrl = null;
-          if (locationHeader) {
-            var redirectedUrl = locationHeader.substr(0, 1) === "/" ? location.origin + locationHeader : locationHeader;
-          }
-          next.call(nextContext, !xhr.ok(request) && request, request.response || request.responseText, redirectedUrl);
-        }
-      });
-      request.send();
-      return request;
-    },
-    loadDocument: function(url, next, nextContext) {
-      this.load(url, next, nextContext).responseType = "document";
-    }
-  };
-  scope.xhr = xhr;
-});
-
-HTMLImports.addModule(function(scope) {
-  var xhr = scope.xhr;
-  var flags = scope.flags;
-  var Loader = function(onLoad, onComplete) {
-    this.cache = {};
-    this.onload = onLoad;
-    this.oncomplete = onComplete;
-    this.inflight = 0;
-    this.pending = {};
-  };
-  Loader.prototype = {
-    addNodes: function(nodes) {
-      this.inflight += nodes.length;
-      for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {
-        this.require(n);
-      }
-      this.checkDone();
-    },
-    addNode: function(node) {
-      this.inflight++;
-      this.require(node);
-      this.checkDone();
-    },
-    require: function(elt) {
-      var url = elt.src || elt.href;
-      elt.__nodeUrl = url;
-      if (!this.dedupe(url, elt)) {
-        this.fetch(url, elt);
-      }
-    },
-    dedupe: function(url, elt) {
-      if (this.pending[url]) {
-        this.pending[url].push(elt);
-        return true;
-      }
-      var resource;
-      if (this.cache[url]) {
-        this.onload(url, elt, this.cache[url]);
-        this.tail();
-        return true;
-      }
-      this.pending[url] = [ elt ];
-      return false;
-    },
-    fetch: function(url, elt) {
-      flags.load && console.log("fetch", url, elt);
-      if (!url) {
-        setTimeout(function() {
-          this.receive(url, elt, {
-            error: "href must be specified"
-          }, null);
-        }.bind(this), 0);
-      } else if (url.match(/^data:/)) {
-        var pieces = url.split(",");
-        var header = pieces[0];
-        var body = pieces[1];
-        if (header.indexOf(";base64") > -1) {
-          body = atob(body);
-        } else {
-          body = decodeURIComponent(body);
-        }
-        setTimeout(function() {
-          this.receive(url, elt, null, body);
-        }.bind(this), 0);
-      } else {
-        var receiveXhr = function(err, resource, redirectedUrl) {
-          this.receive(url, elt, err, resource, redirectedUrl);
-        }.bind(this);
-        xhr.load(url, receiveXhr);
-      }
-    },
-    receive: function(url, elt, err, resource, redirectedUrl) {
-      this.cache[url] = resource;
-      var $p = this.pending[url];
-      for (var i = 0, l = $p.length, p; i < l && (p = $p[i]); i++) {
-        this.onload(url, p, resource, err, redirectedUrl);
-        this.tail();
-      }
-      this.pending[url] = null;
-    },
-    tail: function() {
-      --this.inflight;
-      this.checkDone();
-    },
-    checkDone: function() {
-      if (!this.inflight) {
-        this.oncomplete();
-      }
-    }
-  };
-  scope.Loader = Loader;
-});
-
-HTMLImports.addModule(function(scope) {
-  var Observer = function(addCallback) {
-    this.addCallback = addCallback;
-    this.mo = new MutationObserver(this.handler.bind(this));
-  };
-  Observer.prototype = {
-    handler: function(mutations) {
-      for (var i = 0, l = mutations.length, m; i < l && (m = mutations[i]); i++) {
-        if (m.type === "childList" && m.addedNodes.length) {
-          this.addedNodes(m.addedNodes);
-        }
-      }
-    },
-    addedNodes: function(nodes) {
-      if (this.addCallback) {
-        this.addCallback(nodes);
-      }
-      for (var i = 0, l = nodes.length, n, loading; i < l && (n = nodes[i]); i++) {
-        if (n.children && n.children.length) {
-          this.addedNodes(n.children);
-        }
-      }
-    },
-    observe: function(root) {
-      this.mo.observe(root, {
-        childList: true,
-        subtree: true
-      });
-    }
-  };
-  scope.Observer = Observer;
-});
-
-HTMLImports.addModule(function(scope) {
-  var path = scope.path;
-  var rootDocument = scope.rootDocument;
-  var flags = scope.flags;
-  var isIE = scope.isIE;
-  var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;
-  var IMPORT_SELECTOR = "link[rel=" + IMPORT_LINK_TYPE + "]";
-  var importParser = {
-    documentSelectors: IMPORT_SELECTOR,
-    importsSelectors: [ IMPORT_SELECTOR, "link[rel=stylesheet]", "style", "script:not([type])", 'script[type="text/javascript"]' ].join(","),
-    map: {
-      link: "parseLink",
-      script: "parseScript",
-      style: "parseStyle"
-    },
-    dynamicElements: [],
-    parseNext: function() {
-      var next = this.nextToParse();
-      if (next) {
-        this.parse(next);
-      }
-    },
-    parse: function(elt) {
-      if (this.isParsed(elt)) {
-        flags.parse && console.log("[%s] is already parsed", elt.localName);
-        return;
-      }
-      var fn = this[this.map[elt.localName]];
-      if (fn) {
-        this.markParsing(elt);
-        fn.call(this, elt);
-      }
-    },
-    parseDynamic: function(elt, quiet) {
-      this.dynamicElements.push(elt);
-      if (!quiet) {
-        this.parseNext();
-      }
-    },
-    markParsing: function(elt) {
-      flags.parse && console.log("parsing", elt);
-      this.parsingElement = elt;
-    },
-    markParsingComplete: function(elt) {
-      elt.__importParsed = true;
-      this.markDynamicParsingComplete(elt);
-      if (elt.__importElement) {
-        elt.__importElement.__importParsed = true;
-        this.markDynamicParsingComplete(elt.__importElement);
-      }
-      this.parsingElement = null;
-      flags.parse && console.log("completed", elt);
-    },
-    markDynamicParsingComplete: function(elt) {
-      var i = this.dynamicElements.indexOf(elt);
-      if (i >= 0) {
-        this.dynamicElements.splice(i, 1);
-      }
-    },
-    parseImport: function(elt) {
-      if (HTMLImports.__importsParsingHook) {
-        HTMLImports.__importsParsingHook(elt);
-      }
-      if (elt.import) {
-        elt.import.__importParsed = true;
-      }
-      this.markParsingComplete(elt);
-      if (elt.__resource && !elt.__error) {
-        elt.dispatchEvent(new CustomEvent("load", {
-          bubbles: false
-        }));
-      } else {
-        elt.dispatchEvent(new CustomEvent("error", {
-          bubbles: false
-        }));
-      }
-      if (elt.__pending) {
-        var fn;
-        while (elt.__pending.length) {
-          fn = elt.__pending.shift();
-          if (fn) {
-            fn({
-              target: elt
-            });
-          }
-        }
-      }
-      this.parseNext();
-    },
-    parseLink: function(linkElt) {
-      if (nodeIsImport(linkElt)) {
-        this.parseImport(linkElt);
-      } else {
-        linkElt.href = linkElt.href;
-        this.parseGeneric(linkElt);
-      }
-    },
-    parseStyle: function(elt) {
-      var src = elt;
-      elt = cloneStyle(elt);
-      elt.__importElement = src;
-      this.parseGeneric(elt);
-    },
-    parseGeneric: function(elt) {
-      this.trackElement(elt);
-      this.addElementToDocument(elt);
-    },
-    rootImportForElement: function(elt) {
-      var n = elt;
-      while (n.ownerDocument.__importLink) {
-        n = n.ownerDocument.__importLink;
-      }
-      return n;
-    },
-    addElementToDocument: function(elt) {
-      var port = this.rootImportForElement(elt.__importElement || elt);
-      port.parentNode.insertBefore(elt, port);
-    },
-    trackElement: function(elt, callback) {
-      var self = this;
-      var done = function(e) {
-        if (callback) {
-          callback(e);
-        }
-        self.markParsingComplete(elt);
-        self.parseNext();
-      };
-      elt.addEventListener("load", done);
-      elt.addEventListener("error", done);
-      if (isIE && elt.localName === "style") {
-        var fakeLoad = false;
-        if (elt.textContent.indexOf("@import") == -1) {
-          fakeLoad = true;
-        } else if (elt.sheet) {
-          fakeLoad = true;
-          var csr = elt.sheet.cssRules;
-          var len = csr ? csr.length : 0;
-          for (var i = 0, r; i < len && (r = csr[i]); i++) {
-            if (r.type === CSSRule.IMPORT_RULE) {
-              fakeLoad = fakeLoad && Boolean(r.styleSheet);
-            }
-          }
-        }
-        if (fakeLoad) {
-          elt.dispatchEvent(new CustomEvent("load", {
-            bubbles: false
-          }));
-        }
-      }
-    },
-    parseScript: function(scriptElt) {
-      var script = document.createElement("script");
-      script.__importElement = scriptElt;
-      script.src = scriptElt.src ? scriptElt.src : generateScriptDataUrl(scriptElt);
-      scope.currentScript = scriptElt;
-      this.trackElement(script, function(e) {
-        script.parentNode.removeChild(script);
-        scope.currentScript = null;
-      });
-      this.addElementToDocument(script);
-    },
-    nextToParse: function() {
-      this._mayParse = [];
-      return !this.parsingElement && (this.nextToParseInDoc(rootDocument) || this.nextToParseDynamic());
-    },
-    nextToParseInDoc: function(doc, link) {
-      if (doc && this._mayParse.indexOf(doc) < 0) {
-        this._mayParse.push(doc);
-        var nodes = doc.querySelectorAll(this.parseSelectorsForNode(doc));
-        for (var i = 0, l = nodes.length, p = 0, n; i < l && (n = nodes[i]); i++) {
-          if (!this.isParsed(n)) {
-            if (this.hasResource(n)) {
-              return nodeIsImport(n) ? this.nextToParseInDoc(n.import, n) : n;
-            } else {
-              return;
-            }
-          }
-        }
-      }
-      return link;
-    },
-    nextToParseDynamic: function() {
-      return this.dynamicElements[0];
-    },
-    parseSelectorsForNode: function(node) {
-      var doc = node.ownerDocument || node;
-      return doc === rootDocument ? this.documentSelectors : this.importsSelectors;
-    },
-    isParsed: function(node) {
-      return node.__importParsed;
-    },
-    needsDynamicParsing: function(elt) {
-      return this.dynamicElements.indexOf(elt) >= 0;
-    },
-    hasResource: function(node) {
-      if (nodeIsImport(node) && node.import === undefined) {
-        return false;
-      }
-      return true;
-    }
-  };
-  function nodeIsImport(elt) {
-    return elt.localName === "link" && elt.rel === IMPORT_LINK_TYPE;
-  }
-  function generateScriptDataUrl(script) {
-    var scriptContent = generateScriptContent(script);
-    return "data:text/javascript;charset=utf-8," + encodeURIComponent(scriptContent);
-  }
-  function generateScriptContent(script) {
-    return script.textContent + generateSourceMapHint(script);
-  }
-  function generateSourceMapHint(script) {
-    var owner = script.ownerDocument;
-    owner.__importedScripts = owner.__importedScripts || 0;
-    var moniker = script.ownerDocument.baseURI;
-    var num = owner.__importedScripts ? "-" + owner.__importedScripts : "";
-    owner.__importedScripts++;
-    return "\n//# sourceURL=" + moniker + num + ".js\n";
-  }
-  function cloneStyle(style) {
-    var clone = style.ownerDocument.createElement("style");
-    clone.textContent = style.textContent;
-    path.resolveUrlsInStyle(clone);
-    return clone;
-  }
-  scope.parser = importParser;
-  scope.IMPORT_SELECTOR = IMPORT_SELECTOR;
-});
-
-HTMLImports.addModule(function(scope) {
-  var flags = scope.flags;
-  var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;
-  var IMPORT_SELECTOR = scope.IMPORT_SELECTOR;
-  var rootDocument = scope.rootDocument;
-  var Loader = scope.Loader;
-  var Observer = scope.Observer;
-  var parser = scope.parser;
-  var importer = {
-    documents: {},
-    documentPreloadSelectors: IMPORT_SELECTOR,
-    importsPreloadSelectors: [ IMPORT_SELECTOR ].join(","),
-    loadNode: function(node) {
-      importLoader.addNode(node);
-    },
-    loadSubtree: function(parent) {
-      var nodes = this.marshalNodes(parent);
-      importLoader.addNodes(nodes);
-    },
-    marshalNodes: function(parent) {
-      return parent.querySelectorAll(this.loadSelectorsForNode(parent));
-    },
-    loadSelectorsForNode: function(node) {
-      var doc = node.ownerDocument || node;
-      return doc === rootDocument ? this.documentPreloadSelectors : this.importsPreloadSelectors;
-    },
-    loaded: function(url, elt, resource, err, redirectedUrl) {
-      flags.load && console.log("loaded", url, elt);
-      elt.__resource = resource;
-      elt.__error = err;
-      if (isImportLink(elt)) {
-        var doc = this.documents[url];
-        if (doc === undefined) {
-          doc = err ? null : makeDocument(resource, redirectedUrl || url);
-          if (doc) {
-            doc.__importLink = elt;
-            this.bootDocument(doc);
-          }
-          this.documents[url] = doc;
-        }
-        elt.import = doc;
-      }
-      parser.parseNext();
-    },
-    bootDocument: function(doc) {
-      this.loadSubtree(doc);
-      this.observer.observe(doc);
-      parser.parseNext();
-    },
-    loadedAll: function() {
-      parser.parseNext();
-    }
-  };
-  var importLoader = new Loader(importer.loaded.bind(importer), importer.loadedAll.bind(importer));
-  importer.observer = new Observer();
-  function isImportLink(elt) {
-    return isLinkRel(elt, IMPORT_LINK_TYPE);
-  }
-  function isLinkRel(elt, rel) {
-    return elt.localName === "link" && elt.getAttribute("rel") === rel;
-  }
-  function hasBaseURIAccessor(doc) {
-    return !!Object.getOwnPropertyDescriptor(doc, "baseURI");
-  }
-  function makeDocument(resource, url) {
-    var doc = document.implementation.createHTMLDocument(IMPORT_LINK_TYPE);
-    doc._URL = url;
-    var base = doc.createElement("base");
-    base.setAttribute("href", url);
-    if (!doc.baseURI && !hasBaseURIAccessor(doc)) {
-      Object.defineProperty(doc, "baseURI", {
-        value: url
-      });
-    }
-    var meta = doc.createElement("meta");
-    meta.setAttribute("charset", "utf-8");
-    doc.head.appendChild(meta);
-    doc.head.appendChild(base);
-    doc.body.innerHTML = resource;
-    if (window.HTMLTemplateElement && HTMLTemplateElement.bootstrap) {
-      HTMLTemplateElement.bootstrap(doc);
-    }
-    return doc;
-  }
-  if (!document.baseURI) {
-    var baseURIDescriptor = {
-      get: function() {
-        var base = document.querySelector("base");
-        return base ? base.href : window.location.href;
-      },
-      configurable: true
-    };
-    Object.defineProperty(document, "baseURI", baseURIDescriptor);
-    Object.defineProperty(rootDocument, "baseURI", baseURIDescriptor);
-  }
-  scope.importer = importer;
-  scope.importLoader = importLoader;
-});
-
-HTMLImports.addModule(function(scope) {
-  var parser = scope.parser;
-  var importer = scope.importer;
-  var dynamic = {
-    added: function(nodes) {
-      var owner, parsed, loading;
-      for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {
-        if (!owner) {
-          owner = n.ownerDocument;
-          parsed = parser.isParsed(owner);
-        }
-        loading = this.shouldLoadNode(n);
-        if (loading) {
-          importer.loadNode(n);
-        }
-        if (this.shouldParseNode(n) && parsed) {
-          parser.parseDynamic(n, loading);
-        }
-      }
-    },
-    shouldLoadNode: function(node) {
-      return node.nodeType === 1 && matches.call(node, importer.loadSelectorsForNode(node));
-    },
-    shouldParseNode: function(node) {
-      return node.nodeType === 1 && matches.call(node, parser.parseSelectorsForNode(node));
-    }
-  };
-  importer.observer.addCallback = dynamic.added.bind(dynamic);
-  var matches = HTMLElement.prototype.matches || HTMLElement.prototype.matchesSelector || HTMLElement.prototype.webkitMatchesSelector || HTMLElement.prototype.mozMatchesSelector || HTMLElement.prototype.msMatchesSelector;
-});
-
-(function(scope) {
-  var initializeModules = scope.initializeModules;
-  var isIE = scope.isIE;
-  if (scope.useNative) {
-    return;
-  }
-  if (isIE && typeof window.CustomEvent !== "function") {
-    window.CustomEvent = function(inType, params) {
-      params = params || {};
-      var e = document.createEvent("CustomEvent");
-      e.initCustomEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable), params.detail);
-      return e;
-    };
-    window.CustomEvent.prototype = window.Event.prototype;
-  }
-  initializeModules();
-  var rootDocument = scope.rootDocument;
-  function bootstrap() {
-    HTMLImports.importer.bootDocument(rootDocument);
-  }
-  if (document.readyState === "complete" || document.readyState === "interactive" && !window.attachEvent) {
-    bootstrap();
-  } else {
-    document.addEventListener("DOMContentLoaded", bootstrap);
-  }
-})(HTMLImports);
-
-window.CustomElements = window.CustomElements || {
-  flags: {}
-};
-
-(function(scope) {
-  var flags = scope.flags;
-  var modules = [];
-  var addModule = function(module) {
-    modules.push(module);
-  };
-  var initializeModules = function() {
-    modules.forEach(function(module) {
-      module(scope);
-    });
-  };
-  scope.addModule = addModule;
-  scope.initializeModules = initializeModules;
-  scope.hasNative = Boolean(document.registerElement);
-  scope.useNative = !flags.register && scope.hasNative && !window.ShadowDOMPolyfill && (!window.HTMLImports || HTMLImports.useNative);
-})(CustomElements);
-
-CustomElements.addModule(function(scope) {
-  var IMPORT_LINK_TYPE = window.HTMLImports ? HTMLImports.IMPORT_LINK_TYPE : "none";
-  function forSubtree(node, cb) {
-    findAllElements(node, function(e) {
-      if (cb(e)) {
-        return true;
-      }
-      forRoots(e, cb);
-    });
-    forRoots(node, cb);
-  }
-  function findAllElements(node, find, data) {
-    var e = node.firstElementChild;
-    if (!e) {
-      e = node.firstChild;
-      while (e && e.nodeType !== Node.ELEMENT_NODE) {
-        e = e.nextSibling;
-      }
-    }
-    while (e) {
-      if (find(e, data) !== true) {
-        findAllElements(e, find, data);
-      }
-      e = e.nextElementSibling;
-    }
-    return null;
-  }
-  function forRoots(node, cb) {
-    var root = node.shadowRoot;
-    while (root) {
-      forSubtree(root, cb);
-      root = root.olderShadowRoot;
-    }
-  }
-  var processingDocuments;
-  function forDocumentTree(doc, cb) {
-    processingDocuments = [];
-    _forDocumentTree(doc, cb);
-    processingDocuments = null;
-  }
-  function _forDocumentTree(doc, cb) {
-    doc = wrap(doc);
-    if (processingDocuments.indexOf(doc) >= 0) {
-      return;
-    }
-    processingDocuments.push(doc);
-    var imports = doc.querySelectorAll("link[rel=" + IMPORT_LINK_TYPE + "]");
-    for (var i = 0, l = imports.length, n; i < l && (n = imports[i]); i++) {
-      if (n.import) {
-        _forDocumentTree(n.import, cb);
-      }
-    }
-    cb(doc);
-  }
-  scope.forDocumentTree = forDocumentTree;
-  scope.forSubtree = forSubtree;
-});
-
-CustomElements.addModule(function(scope) {
-  var flags = scope.flags;
-  var forSubtree = scope.forSubtree;
-  var forDocumentTree = scope.forDocumentTree;
-  function addedNode(node) {
-    return added(node) || addedSubtree(node);
-  }
-  function added(node) {
-    if (scope.upgrade(node)) {
-      return true;
-    }
-    attached(node);
-  }
-  function addedSubtree(node) {
-    forSubtree(node, function(e) {
-      if (added(e)) {
-        return true;
-      }
-    });
-  }
-  function attachedNode(node) {
-    attached(node);
-    if (inDocument(node)) {
-      forSubtree(node, function(e) {
-        attached(e);
-      });
-    }
-  }
-  var hasPolyfillMutations = !window.MutationObserver || window.MutationObserver === window.JsMutationObserver;
-  scope.hasPolyfillMutations = hasPolyfillMutations;
-  var isPendingMutations = false;
-  var pendingMutations = [];
-  function deferMutation(fn) {
-    pendingMutations.push(fn);
-    if (!isPendingMutations) {
-      isPendingMutations = true;
-      setTimeout(takeMutations);
-    }
-  }
-  function takeMutations() {
-    isPendingMutations = false;
-    var $p = pendingMutations;
-    for (var i = 0, l = $p.length, p; i < l && (p = $p[i]); i++) {
-      p();
-    }
-    pendingMutations = [];
-  }
-  function attached(element) {
-    if (hasPolyfillMutations) {
-      deferMutation(function() {
-        _attached(element);
-      });
-    } else {
-      _attached(element);
-    }
-  }
-  function _attached(element) {
-    if (element.__upgraded__ && (element.attachedCallback || element.detachedCallback)) {
-      if (!element.__attached && inDocument(element)) {
-        element.__attached = true;
-        if (element.attachedCallback) {
-          element.attachedCallback();
-        }
-      }
-    }
-  }
-  function detachedNode(node) {
-    detached(node);
-    forSubtree(node, function(e) {
-      detached(e);
-    });
-  }
-  function detached(element) {
-    if (hasPolyfillMutations) {
-      deferMutation(function() {
-        _detached(element);
-      });
-    } else {
-      _detached(element);
-    }
-  }
-  function _detached(element) {
-    if (element.__upgraded__ && (element.attachedCallback || element.detachedCallback)) {
-      if (element.__attached && !inDocument(element)) {
-        element.__attached = false;
-        if (element.detachedCallback) {
-          element.detachedCallback();
-        }
-      }
-    }
-  }
-  function inDocument(element) {
-    var p = element;
-    var doc = wrap(document);
-    while (p) {
-      if (p == doc) {
-        return true;
-      }
-      p = p.parentNode || p.host;
-    }
-  }
-  function watchShadow(node) {
-    if (node.shadowRoot && !node.shadowRoot.__watched) {
-      flags.dom && console.log("watching shadow-root for: ", node.localName);
-      var root = node.shadowRoot;
-      while (root) {
-        observe(root);
-        root = root.olderShadowRoot;
-      }
-    }
-  }
-  function handler(mutations) {
-    if (flags.dom) {
-      var mx = mutations[0];
-      if (mx && mx.type === "childList" && mx.addedNodes) {
-        if (mx.addedNodes) {
-          var d = mx.addedNodes[0];
-          while (d && d !== document && !d.host) {
-            d = d.parentNode;
-          }
-          var u = d && (d.URL || d._URL || d.host && d.host.localName) || "";
-          u = u.split("/?").shift().split("/").pop();
-        }
-      }
-      console.group("mutations (%d) [%s]", mutations.length, u || "");
-    }
-    mutations.forEach(function(mx) {
-      if (mx.type === "childList") {
-        forEach(mx.addedNodes, function(n) {
-          if (!n.localName) {
-            return;
-          }
-          addedNode(n);
-        });
-        forEach(mx.removedNodes, function(n) {
-          if (!n.localName) {
-            return;
-          }
-          detachedNode(n);
-        });
-      }
-    });
-    flags.dom && console.groupEnd();
-  }
-  function takeRecords(node) {
-    node = wrap(node);
-    if (!node) {
-      node = wrap(document);
-    }
-    while (node.parentNode) {
-      node = node.parentNode;
-    }
-    var observer = node.__observer;
-    if (observer) {
-      handler(observer.takeRecords());
-      takeMutations();
-    }
-  }
-  var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);
-  function observe(inRoot) {
-    if (inRoot.__observer) {
-      return;
-    }
-    var observer = new MutationObserver(handler);
-    observer.observe(inRoot, {
-      childList: true,
-      subtree: true
-    });
-    inRoot.__observer = observer;
-  }
-  function upgradeDocument(doc) {
-    doc = wrap(doc);
-    flags.dom && console.group("upgradeDocument: ", doc.baseURI.split("/").pop());
-    addedNode(doc);
-    observe(doc);
-    flags.dom && console.groupEnd();
-  }
-  function upgradeDocumentTree(doc) {
-    forDocumentTree(doc, upgradeDocument);
-  }
-  var originalCreateShadowRoot = Element.prototype.createShadowRoot;
-  if (originalCreateShadowRoot) {
-    Element.prototype.createShadowRoot = function() {
-      var root = originalCreateShadowRoot.call(this);
-      CustomElements.watchShadow(this);
-      return root;
-    };
-  }
-  scope.watchShadow = watchShadow;
-  scope.upgradeDocumentTree = upgradeDocumentTree;
-  scope.upgradeSubtree = addedSubtree;
-  scope.upgradeAll = addedNode;
-  scope.attachedNode = attachedNode;
-  scope.takeRecords = takeRecords;
-});
-
-CustomElements.addModule(function(scope) {
-  var flags = scope.flags;
-  function upgrade(node) {
-    if (!node.__upgraded__ && node.nodeType === Node.ELEMENT_NODE) {
-      var is = node.getAttribute("is");
-      var definition = scope.getRegisteredDefinition(is || node.localName);
-      if (definition) {
-        if (is && definition.tag == node.localName) {
-          return upgradeWithDefinition(node, definition);
-        } else if (!is && !definition.extends) {
-          return upgradeWithDefinition(node, definition);
-        }
-      }
-    }
-  }
-  function upgradeWithDefinition(element, definition) {
-    flags.upgrade && console.group("upgrade:", element.localName);
-    if (definition.is) {
-      element.setAttribute("is", definition.is);
-    }
-    implementPrototype(element, definition);
-    element.__upgraded__ = true;
-    created(element);
-    scope.attachedNode(element);
-    scope.upgradeSubtree(element);
-    flags.upgrade && console.groupEnd();
-    return element;
-  }
-  function implementPrototype(element, definition) {
-    if (Object.__proto__) {
-      element.__proto__ = definition.prototype;
-    } else {
-      customMixin(element, definition.prototype, definition.native);
-      element.__proto__ = definition.prototype;
-    }
-  }
-  function customMixin(inTarget, inSrc, inNative) {
-    var used = {};
-    var p = inSrc;
-    while (p !== inNative && p !== HTMLElement.prototype) {
-      var keys = Object.getOwnPropertyNames(p);
-      for (var i = 0, k; k = keys[i]; i++) {
-        if (!used[k]) {
-          Object.defineProperty(inTarget, k, Object.getOwnPropertyDescriptor(p, k));
-          used[k] = 1;
-        }
-      }
-      p = Object.getPrototypeOf(p);
-    }
-  }
-  function created(element) {
-    if (element.createdCallback) {
-      element.createdCallback();
-    }
-  }
-  scope.upgrade = upgrade;
-  scope.upgradeWithDefinition = upgradeWithDefinition;
-  scope.implementPrototype = implementPrototype;
-});
-
-CustomElements.addModule(function(scope) {
-  var upgradeDocumentTree = scope.upgradeDocumentTree;
-  var upgrade = scope.upgrade;
-  var upgradeWithDefinition = scope.upgradeWithDefinition;
-  var implementPrototype = scope.implementPrototype;
-  var useNative = scope.useNative;
-  function register(name, options) {
-    var definition = options || {};
-    if (!name) {
-      throw new Error("document.registerElement: first argument `name` must not be empty");
-    }
-    if (name.indexOf("-") < 0) {
-      throw new Error("document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '" + String(name) + "'.");
-    }
-    if (isReservedTag(name)) {
-      throw new Error("Failed to execute 'registerElement' on 'Document': Registration failed for type '" + String(name) + "'. The type name is invalid.");
-    }
-    if (getRegisteredDefinition(name)) {
-      throw new Error("DuplicateDefinitionError: a type with name '" + String(name) + "' is already registered");
-    }
-    if (!definition.prototype) {
-      definition.prototype = Object.create(HTMLElement.prototype);
-    }
-    definition.__name = name.toLowerCase();
-    definition.lifecycle = definition.lifecycle || {};
-    definition.ancestry = ancestry(definition.extends);
-    resolveTagName(definition);
-    resolvePrototypeChain(definition);
-    overrideAttributeApi(definition.prototype);
-    registerDefinition(definition.__name, definition);
-    definition.ctor = generateConstructor(definition);
-    definition.ctor.prototype = definition.prototype;
-    definition.prototype.constructor = definition.ctor;
-    if (scope.ready) {
-      upgradeDocumentTree(document);
-    }
-    return definition.ctor;
-  }
-  function overrideAttributeApi(prototype) {
-    if (prototype.setAttribute._polyfilled) {
-      return;
-    }
-    var setAttribute = prototype.setAttribute;
-    prototype.setAttribute = function(name, value) {
-      changeAttribute.call(this, name, value, setAttribute);
-    };
-    var removeAttribute = prototype.removeAttribute;
-    prototype.removeAttribute = function(name) {
-      changeAttribute.call(this, name, null, removeAttribute);
-    };
-    prototype.setAttribute._polyfilled = true;
-  }
-  function changeAttribute(name, value, operation) {
-    name = name.toLowerCase();
-    var oldValue = this.getAttribute(name);
-    operation.apply(this, arguments);
-    var newValue = this.getAttribute(name);
-    if (this.attributeChangedCallback && newValue !== oldValue) {
-      this.attributeChangedCallback(name, oldValue, newValue);
-    }
-  }
-  function isReservedTag(name) {
-    for (var i = 0; i < reservedTagList.length; i++) {
-      if (name === reservedTagList[i]) {
-        return true;
-      }
-    }
-  }
-  var reservedTagList = [ "annotation-xml", "color-profile", "font-face", "font-face-src", "font-face-uri", "font-face-format", "font-face-name", "missing-glyph" ];
-  function ancestry(extnds) {
-    var extendee = getRegisteredDefinition(extnds);
-    if (extendee) {
-      return ancestry(extendee.extends).concat([ extendee ]);
-    }
-    return [];
-  }
-  function resolveTagName(definition) {
-    var baseTag = definition.extends;
-    for (var i = 0, a; a = definition.ancestry[i]; i++) {
-      baseTag = a.is && a.tag;
-    }
-    definition.tag = baseTag || definition.__name;
-    if (baseTag) {
-      definition.is = definition.__name;
-    }
-  }
-  function resolvePrototypeChain(definition) {
-    if (!Object.__proto__) {
-      var nativePrototype = HTMLElement.prototype;
-      if (definition.is) {
-        var inst = document.createElement(definition.tag);
-        var expectedPrototype = Object.getPrototypeOf(inst);
-        if (expectedPrototype === definition.prototype) {
-          nativePrototype = expectedPrototype;
-        }
-      }
-      var proto = definition.prototype, ancestor;
-      while (proto && proto !== nativePrototype) {
-        ancestor = Object.getPrototypeOf(proto);
-        proto.__proto__ = ancestor;
-        proto = ancestor;
-      }
-      definition.native = nativePrototype;
-    }
-  }
-  function instantiate(definition) {
-    return upgradeWithDefinition(domCreateElement(definition.tag), definition);
-  }
-  var registry = {};
-  function getRegisteredDefinition(name) {
-    if (name) {
-      return registry[name.toLowerCase()];
-    }
-  }
-  function registerDefinition(name, definition) {
-    registry[name] = definition;
-  }
-  function generateConstructor(definition) {
-    return function() {
-      return instantiate(definition);
-    };
-  }
-  var HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
-  function createElementNS(namespace, tag, typeExtension) {
-    if (namespace === HTML_NAMESPACE) {
-      return createElement(tag, typeExtension);
-    } else {
-      return domCreateElementNS(namespace, tag);
-    }
-  }
-  function createElement(tag, typeExtension) {
-    var definition = getRegisteredDefinition(typeExtension || tag);
-    if (definition) {
-      if (tag == definition.tag && typeExtension == definition.is) {
-        return new definition.ctor();
-      }
-      if (!typeExtension && !definition.is) {
-        return new definition.ctor();
-      }
-    }
-    var element;
-    if (typeExtension) {
-      element = createElement(tag);
-      element.setAttribute("is", typeExtension);
-      return element;
-    }
-    element = domCreateElement(tag);
-    if (tag.indexOf("-") >= 0) {
-      implementPrototype(element, HTMLElement);
-    }
-    return element;
-  }
-  function cloneNode(deep) {
-    var n = domCloneNode.call(this, deep);
-    upgrade(n);
-    return n;
-  }
-  var domCreateElement = document.createElement.bind(document);
-  var domCreateElementNS = document.createElementNS.bind(document);
-  var domCloneNode = Node.prototype.cloneNode;
-  var isInstance;
-  if (!Object.__proto__ && !useNative) {
-    isInstance = function(obj, ctor) {
-      var p = obj;
-      while (p) {
-        if (p === ctor.prototype) {
-          return true;
-        }
-        p = p.__proto__;
-      }
-      return false;
-    };
-  } else {
-    isInstance = function(obj, base) {
-      return obj instanceof base;
-    };
-  }
-  document.registerElement = register;
-  document.createElement = createElement;
-  document.createElementNS = createElementNS;
-  Node.prototype.cloneNode = cloneNode;
-  scope.registry = registry;
-  scope.instanceof = isInstance;
-  scope.reservedTagList = reservedTagList;
-  scope.getRegisteredDefinition = getRegisteredDefinition;
-  document.register = document.registerElement;
-});
-
-(function(scope) {
-  var useNative = scope.useNative;
-  var initializeModules = scope.initializeModules;
-  var isIE11OrOlder = /Trident/.test(navigator.userAgent);
-  if (useNative) {
-    var nop = function() {};
-    scope.watchShadow = nop;
-    scope.upgrade = nop;
-    scope.upgradeAll = nop;
-    scope.upgradeDocumentTree = nop;
-    scope.upgradeSubtree = nop;
-    scope.takeRecords = nop;
-    scope.instanceof = function(obj, base) {
-      return obj instanceof base;
-    };
-  } else {
-    initializeModules();
-  }
-  var upgradeDocumentTree = scope.upgradeDocumentTree;
-  if (!window.wrap) {
-    if (window.ShadowDOMPolyfill) {
-      window.wrap = ShadowDOMPolyfill.wrapIfNeeded;
-      window.unwrap = ShadowDOMPolyfill.unwrapIfNeeded;
-    } else {
-      window.wrap = window.unwrap = function(node) {
-        return node;
-      };
-    }
-  }
-  function bootstrap() {
-    upgradeDocumentTree(wrap(document));
-    if (window.HTMLImports) {
-      HTMLImports.__importsParsingHook = function(elt) {
-        upgradeDocumentTree(wrap(elt.import));
-      };
-    }
-    CustomElements.ready = true;
-    setTimeout(function() {
-      CustomElements.readyTime = Date.now();
-      if (window.HTMLImports) {
-        CustomElements.elapsed = CustomElements.readyTime - HTMLImports.readyTime;
-      }
-      document.dispatchEvent(new CustomEvent("WebComponentsReady", {
-        bubbles: true
-      }));
-    });
-  }
-  if (isIE11OrOlder && typeof window.CustomEvent !== "function") {
-    window.CustomEvent = function(inType, params) {
-      params = params || {};
-      var e = document.createEvent("CustomEvent");
-      e.initCustomEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable), params.detail);
-      return e;
-    };
-    window.CustomEvent.prototype = window.Event.prototype;
-  }
-  if (document.readyState === "complete" || scope.flags.eager) {
-    bootstrap();
-  } else if (document.readyState === "interactive" && !window.attachEvent && (!window.HTMLImports || window.HTMLImports.ready)) {
-    bootstrap();
-  } else {
-    var loadEvent = window.HTMLImports && !HTMLImports.ready ? "HTMLImportsLoaded" : "DOMContentLoaded";
-    window.addEventListener(loadEvent, bootstrap);
-  }
-})(window.CustomElements);
-
-(function(scope) {
-  if (!Function.prototype.bind) {
-    Function.prototype.bind = function(scope) {
-      var self = this;
-      var args = Array.prototype.slice.call(arguments, 1);
-      return function() {
-        var args2 = args.slice();
-        args2.push.apply(args2, arguments);
-        return self.apply(scope, args2);
-      };
-    };
-  }
-})(window.WebComponents);
-
-(function(scope) {
-  "use strict";
-  if (!window.performance) {
-    var start = Date.now();
-    window.performance = {
-      now: function() {
-        return Date.now() - start;
-      }
-    };
-  }
-  if (!window.requestAnimationFrame) {
-    window.requestAnimationFrame = function() {
-      var nativeRaf = window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame;
-      return nativeRaf ? function(callback) {
-        return nativeRaf(function() {
-          callback(performance.now());
-        });
-      } : function(callback) {
-        return window.setTimeout(callback, 1e3 / 60);
-      };
-    }();
-  }
-  if (!window.cancelAnimationFrame) {
-    window.cancelAnimationFrame = function() {
-      return window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || function(id) {
-        clearTimeout(id);
-      };
-    }();
-  }
-  var elementDeclarations = [];
-  var polymerStub = function(name, dictionary) {
-    if (typeof name !== "string" && arguments.length === 1) {
-      Array.prototype.push.call(arguments, document._currentScript);
-    }
-    elementDeclarations.push(arguments);
-  };
-  window.Polymer = polymerStub;
-  scope.consumeDeclarations = function(callback) {
-    scope.consumeDeclarations = function() {
-      throw "Possible attempt to load Polymer twice";
-    };
-    if (callback) {
-      callback(elementDeclarations);
-    }
-    elementDeclarations = null;
-  };
-  function installPolymerWarning() {
-    if (window.Polymer === polymerStub) {
-      window.Polymer = function() {
-        throw new Error("You tried to use polymer without loading it first. To " + 'load polymer, ');
-      };
-    }
-  }
-  if (HTMLImports.useNative) {
-    installPolymerWarning();
-  } else {
-    addEventListener("DOMContentLoaded", installPolymerWarning);
-  }
-})(window.WebComponents);
-
-(function(scope) {
-  var style = document.createElement("style");
-  style.textContent = "" + "body {" + "transition: opacity ease-in 0.2s;" + " } \n" + "body[unresolved] {" + "opacity: 0; display: block; overflow: hidden; position: relative;" + " } \n";
-  var head = document.querySelector("head");
-  head.insertBefore(style, head.firstChild);
-})(window.WebComponents);
-
-(function(scope) {
-  window.Platform = scope;
-})(window.WebComponents);
\ No newline at end of file
diff --git a/example/bower_components/webcomponentsjs/webcomponents.min.js b/example/bower_components/webcomponentsjs/webcomponents.min.js
deleted file mode 100644
index 474305f73..000000000
--- a/example/bower_components/webcomponentsjs/webcomponents.min.js
+++ /dev/null
@@ -1,14 +0,0 @@
-/**
- * @license
- * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
- * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
- * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
- * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
- * Code distributed by Google as part of the polymer project is also
- * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
- */
-// @version 0.5.5
-window.WebComponents=window.WebComponents||{},function(e){var t=e.flags||{},n="webcomponents.js",r=document.querySelector('script[src*="'+n+'"]');if(!t.noOpts){if(location.search.slice(1).split("&").forEach(function(e){e=e.split("="),e[0]&&(t[e[0]]=e[1]||!0)}),r)for(var o,i=0;o=r.attributes[i];i++)"src"!==o.name&&(t[o.name]=o.value||!0);if(t.log){var a=t.log.split(",");t.log={},a.forEach(function(e){t.log[e]=!0})}else t.log={}}t.shadow=t.shadow||t.shadowdom||t.polyfill,t.shadow="native"===t.shadow?!1:t.shadow||!HTMLElement.prototype.createShadowRoot,t.register&&(window.CustomElements=window.CustomElements||{flags:{}},window.CustomElements.flags.register=t.register),e.flags=t}(WebComponents),WebComponents.flags.shadow&&("undefined"==typeof WeakMap&&!function(){var e=Object.defineProperty,t=Date.now()%1e9,n=function(){this.name="__st"+(1e9*Math.random()>>>0)+(t++ +"__")};n.prototype={set:function(t,n){var r=t[this.name];return r&&r[0]===t?r[1]=n:e(t,this.name,{value:[t,n],writable:!0}),this},get:function(e){var t;return(t=e[this.name])&&t[0]===e?t[1]:void 0},"delete":function(e){var t=e[this.name];return t&&t[0]===e?(t[0]=t[1]=void 0,!0):!1},has:function(e){var t=e[this.name];return t?t[0]===e:!1}},window.WeakMap=n}(),window.ShadowDOMPolyfill={},function(e){"use strict";function t(){if("undefined"!=typeof chrome&&chrome.app&&chrome.app.runtime)return!1;if(navigator.getDeviceStorage)return!1;try{var e=new Function("return true;");return e()}catch(t){return!1}}function n(e){if(!e)throw new Error("Assertion failed")}function r(e,t){for(var n=W(t),r=0;rl;l++)c[l]=new Array(s),c[l][0]=l;for(var u=0;s>u;u++)c[0][u]=u;for(var l=1;a>l;l++)for(var u=1;s>u;u++)if(this.equals(e[t+u-1],r[o+l-1]))c[l][u]=c[l-1][u-1];else{var d=c[l-1][u]+1,p=c[l][u-1]+1;c[l][u]=p>d?d:p}return c},spliceOperationsFromEditDistances:function(e){for(var t=e.length-1,n=e[0].length-1,s=e[t][n],c=[];t>0||n>0;)if(0!=t)if(0!=n){var l,u=e[t-1][n-1],d=e[t-1][n],p=e[t][n-1];l=p>d?u>d?d:u:u>p?p:u,l==u?(u==s?c.push(r):(c.push(o),s=u),t--,n--):l==d?(c.push(a),t--,s=d):(c.push(i),n--,s=p)}else c.push(a),t--;else c.push(i),n--;return c.reverse(),c},calcSplices:function(e,n,s,c,l,u){var d=0,p=0,f=Math.min(s-n,u-l);if(0==n&&0==l&&(d=this.sharedPrefix(e,c,f)),s==e.length&&u==c.length&&(p=this.sharedSuffix(e,c,f-d)),n+=d,l+=d,s-=p,u-=p,s-n==0&&u-l==0)return[];if(n==s){for(var h=t(n,[],0);u>l;)h.removed.push(c[l++]);return[h]}if(l==u)return[t(n,[],s-n)];for(var m=this.spliceOperationsFromEditDistances(this.calcEditDistances(e,n,s,c,l,u)),h=void 0,w=[],v=n,g=l,b=0;br;r++)if(!this.equals(e[r],t[r]))return r;return n},sharedSuffix:function(e,t,n){for(var r=e.length,o=t.length,i=0;n>i&&this.equals(e[--r],t[--o]);)i++;return i},calculateSplices:function(e,t){return this.calcSplices(e,0,e.length,t,0,t.length)},equals:function(e,t){return e===t}},e.ArraySplice=n}(window.ShadowDOMPolyfill),function(e){"use strict";function t(){a=!1;var e=i.slice(0);i=[];for(var t=0;t0){for(var u=0;u0&&r.length>0;){var i=n.pop(),a=r.pop();if(i!==a)break;o=i}return o}function u(e,t,n){t instanceof G.Window&&(t=t.document);var o,i=k(t),a=k(n),s=r(n,e),o=l(i,a);o||(o=a.root);for(var c=o;c;c=c.parent)for(var u=0;u0;i--)if(!g(t[i],e,o,t,r))return!1;return!0}function w(e,t,n,r){var o=it,i=t[0]||n;return g(i,e,o,t,r)}function v(e,t,n,r){for(var o=at,i=1;i0&&g(n,e,o,t,r)}function g(e,t,n,r,o){var i=z.get(e);if(!i)return!0;var a=o||s(r,e);if(a===e){if(n===ot)return!0;n===at&&(n=it)}else if(n===at&&!t.bubbles)return!0;if("relatedTarget"in t){var c=q(t),l=c.relatedTarget;if(l){if(l instanceof Object&&l.addEventListener){var d=V(l),p=u(t,e,d);if(p===a)return!0}else p=null;J.set(t,p)}}Z.set(t,n);var f=t.type,h=!1;X.set(t,a),$.set(t,e),i.depth++;for(var m=0,w=i.length;w>m;m++){var v=i[m];if(v.removed)h=!0;else if(!(v.type!==f||!v.capture&&n===ot||v.capture&&n===at))try{if("function"==typeof v.handler?v.handler.call(e,t):v.handler.handleEvent(t),et.get(t))return!1}catch(g){I||(I=g)}}if(i.depth--,h&&0===i.depth){var b=i.slice();i.length=0;for(var m=0;mr;r++)t[r]=a(e[r]);return t.length=o,t}function o(e,t){e.prototype[t]=function(){return r(i(this)[t].apply(i(this),arguments))}}var i=e.unsafeUnwrap,a=e.wrap,s={enumerable:!1};n.prototype={item:function(e){return this[e]}},t(n.prototype,"item"),e.wrappers.NodeList=n,e.addWrapNodeListMethod=o,e.wrapNodeList=r}(window.ShadowDOMPolyfill),function(e){"use strict";e.wrapHTMLCollection=e.wrapNodeList,e.wrappers.HTMLCollection=e.wrappers.NodeList}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){L(e instanceof S)}function n(e){var t=new M;return t[0]=e,t.length=1,t}function r(e,t,n){C(t,"childList",{removedNodes:n,previousSibling:e.previousSibling,nextSibling:e.nextSibling})}function o(e,t){C(e,"childList",{removedNodes:t})}function i(e,t,r,o){if(e instanceof DocumentFragment){var i=s(e);B=!0;for(var a=i.length-1;a>=0;a--)e.removeChild(i[a]),i[a].parentNode_=t;B=!1;for(var a=0;ao;o++)r.appendChild(I(t[o]));return r}function w(e){if(void 0!==e.firstChild_)for(var t=e.firstChild_;t;){var n=t;t=t.nextSibling_,n.parentNode_=n.previousSibling_=n.nextSibling_=void 0}e.firstChild_=e.lastChild_=void 0}function v(e){if(e.invalidateShadowRenderer()){for(var t=e.firstChild;t;){L(t.parentNode===e);var n=t.nextSibling,r=I(t),o=r.parentNode;o&&Y.call(o,r),t.previousSibling_=t.nextSibling_=t.parentNode_=null,t=n}e.firstChild_=e.lastChild_=null}else for(var n,i=I(e),a=i.firstChild;a;)n=a.nextSibling,Y.call(i,a),a=n}function g(e){var t=e.parentNode;return t&&t.invalidateShadowRenderer()}function b(e){for(var t,n=0;ns;s++)i=b(t[s]),!o&&(a=v(i).root)&&a instanceof e.wrappers.ShadowRoot||(r[n++]=i);return n}function n(e){return String(e).replace(/\/deep\/|::shadow/g," ")}function r(e){return String(e).replace(/:host\(([^\s]+)\)/g,"$1").replace(/([^\s]):host/g,"$1").replace(":host","*").replace(/\^|\/shadow\/|\/shadow-deep\/|::shadow|\/deep\/|::content/g," ")}function o(e,t){for(var n,r=e.firstElementChild;r;){if(r.matches(t))return r;if(n=o(r,t))return n;r=r.nextElementSibling}return null}function i(e,t){return e.matches(t)}function a(e,t,n){var r=e.localName;return r===t||r===n&&e.namespaceURI===D}function s(){return!0}function c(e,t,n){return e.localName===n}function l(e,t){return e.namespaceURI===t}function u(e,t,n){return e.namespaceURI===t&&e.localName===n}function d(e,t,n,r,o,i){for(var a=e.firstElementChild;a;)r(a,o,i)&&(n[t++]=a),t=d(a,t,n,r,o,i),a=a.nextElementSibling;return t}function p(n,r,o,i,a){var s,c=g(this),l=v(this).root;if(l instanceof e.wrappers.ShadowRoot)return d(this,r,o,n,i,null);if(c instanceof C)s=T.call(c,i);else{if(!(c instanceof N))return d(this,r,o,n,i,null);s=S.call(c,i)}return t(s,r,o,a)}function f(n,r,o,i,a){var s,c=g(this),l=v(this).root;if(l instanceof e.wrappers.ShadowRoot)return d(this,r,o,n,i,a);if(c instanceof C)s=_.call(c,i,a);else{if(!(c instanceof N))return d(this,r,o,n,i,a);s=M.call(c,i,a)}return t(s,r,o,!1)}function h(n,r,o,i,a){var s,c=g(this),l=v(this).root;if(l instanceof e.wrappers.ShadowRoot)return d(this,r,o,n,i,a);if(c instanceof C)s=O.call(c,i,a);else{if(!(c instanceof N))return d(this,r,o,n,i,a);s=L.call(c,i,a)}return t(s,r,o,!1)}var m=e.wrappers.HTMLCollection,w=e.wrappers.NodeList,v=e.getTreeScope,g=e.unsafeUnwrap,b=e.wrap,y=document.querySelector,E=document.documentElement.querySelector,S=document.querySelectorAll,T=document.documentElement.querySelectorAll,M=document.getElementsByTagName,_=document.documentElement.getElementsByTagName,L=document.getElementsByTagNameNS,O=document.documentElement.getElementsByTagNameNS,C=window.Element,N=window.HTMLDocument||window.Document,D="http://www.w3.org/1999/xhtml",j={querySelector:function(t){var r=n(t),i=r!==t;t=r;var a,s=g(this),c=v(this).root;if(c instanceof e.wrappers.ShadowRoot)return o(this,t);if(s instanceof C)a=b(E.call(s,t));else{if(!(s instanceof N))return o(this,t);a=b(y.call(s,t))}return a&&!i&&(c=v(a).root)&&c instanceof e.wrappers.ShadowRoot?o(this,t):a},querySelectorAll:function(e){var t=n(e),r=t!==e;e=t;var o=new w;return o.length=p.call(this,i,0,o,e,r),o
-}},H={matches:function(t){return t=r(t),e.originalMatches.call(g(this),t)}},x={getElementsByTagName:function(e){var t=new m,n="*"===e?s:a;return t.length=f.call(this,n,0,t,e,e.toLowerCase()),t},getElementsByClassName:function(e){return this.querySelectorAll("."+e)},getElementsByTagNameNS:function(e,t){var n=new m,r=null;return r="*"===e?"*"===t?s:c:"*"===t?l:u,n.length=h.call(this,r,0,n,e||null,t),n}};e.GetElementsByInterface=x,e.SelectorsInterface=j,e.MatchesInterface=H}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){for(;e&&e.nodeType!==Node.ELEMENT_NODE;)e=e.nextSibling;return e}function n(e){for(;e&&e.nodeType!==Node.ELEMENT_NODE;)e=e.previousSibling;return e}var r=e.wrappers.NodeList,o={get firstElementChild(){return t(this.firstChild)},get lastElementChild(){return n(this.lastChild)},get childElementCount(){for(var e=0,t=this.firstElementChild;t;t=t.nextElementSibling)e++;return e},get children(){for(var e=new r,t=0,n=this.firstElementChild;n;n=n.nextElementSibling)e[t++]=n;return e.length=t,e},remove:function(){var e=this.parentNode;e&&e.removeChild(this)}},i={get nextElementSibling(){return t(this.nextSibling)},get previousElementSibling(){return n(this.previousSibling)}};e.ChildNodeInterface=i,e.ParentNodeInterface=o}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){r.call(this,e)}var n=e.ChildNodeInterface,r=e.wrappers.Node,o=e.enqueueMutation,i=e.mixin,a=e.registerWrapper,s=e.unsafeUnwrap,c=window.CharacterData;t.prototype=Object.create(r.prototype),i(t.prototype,{get textContent(){return this.data},set textContent(e){this.data=e},get data(){return s(this).data},set data(e){var t=s(this).data;o(this,"characterData",{oldValue:t}),s(this).data=e}}),i(t.prototype,n),a(c,t,document.createTextNode("")),e.wrappers.CharacterData=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){return e>>>0}function n(e){r.call(this,e)}var r=e.wrappers.CharacterData,o=(e.enqueueMutation,e.mixin),i=e.registerWrapper,a=window.Text;n.prototype=Object.create(r.prototype),o(n.prototype,{splitText:function(e){e=t(e);var n=this.data;if(e>n.length)throw new Error("IndexSizeError");var r=n.slice(0,e),o=n.slice(e);this.data=r;var i=this.ownerDocument.createTextNode(o);return this.parentNode&&this.parentNode.insertBefore(i,this.nextSibling),i}}),i(a,n,document.createTextNode("")),e.wrappers.Text=n}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){return i(e).getAttribute("class")}function n(e,t){a(e,"attributes",{name:"class",namespace:null,oldValue:t})}function r(t){e.invalidateRendererBasedOnAttribute(t,"class")}function o(e,o,i){var a=e.ownerElement_;if(null==a)return o.apply(e,i);var s=t(a),c=o.apply(e,i);return t(a)!==s&&(n(a,s),r(a)),c}if(!window.DOMTokenList)return void console.warn("Missing DOMTokenList prototype, please include a compatible classList polyfill such as http://goo.gl/uTcepH.");var i=e.unsafeUnwrap,a=e.enqueueMutation,s=DOMTokenList.prototype.add;DOMTokenList.prototype.add=function(){o(this,s,arguments)};var c=DOMTokenList.prototype.remove;DOMTokenList.prototype.remove=function(){o(this,c,arguments)};var l=DOMTokenList.prototype.toggle;DOMTokenList.prototype.toggle=function(){return o(this,l,arguments)}}(window.ShadowDOMPolyfill),function(e){"use strict";function t(t,n){var r=t.parentNode;if(r&&r.shadowRoot){var o=e.getRendererForHost(r);o.dependsOnAttribute(n)&&o.invalidate()}}function n(e,t,n){u(e,"attributes",{name:t,namespace:null,oldValue:n})}function r(e){a.call(this,e)}var o=e.ChildNodeInterface,i=e.GetElementsByInterface,a=e.wrappers.Node,s=e.ParentNodeInterface,c=e.SelectorsInterface,l=e.MatchesInterface,u=(e.addWrapNodeListMethod,e.enqueueMutation),d=e.mixin,p=(e.oneOf,e.registerWrapper),f=e.unsafeUnwrap,h=e.wrappers,m=window.Element,w=["matches","mozMatchesSelector","msMatchesSelector","webkitMatchesSelector"].filter(function(e){return m.prototype[e]}),v=w[0],g=m.prototype[v],b=new WeakMap;r.prototype=Object.create(a.prototype),d(r.prototype,{createShadowRoot:function(){var t=new h.ShadowRoot(this);f(this).polymerShadowRoot_=t;var n=e.getRendererForHost(this);return n.invalidate(),t},get shadowRoot(){return f(this).polymerShadowRoot_||null},setAttribute:function(e,r){var o=f(this).getAttribute(e);f(this).setAttribute(e,r),n(this,e,o),t(this,e)},removeAttribute:function(e){var r=f(this).getAttribute(e);f(this).removeAttribute(e),n(this,e,r),t(this,e)},get classList(){var e=b.get(this);if(!e){if(e=f(this).classList,!e)return;e.ownerElement_=this,b.set(this,e)}return e},get className(){return f(this).className},set className(e){this.setAttribute("class",e)},get id(){return f(this).id},set id(e){this.setAttribute("id",e)}}),w.forEach(function(e){"matches"!==e&&(r.prototype[e]=function(e){return this.matches(e)})}),m.prototype.webkitCreateShadowRoot&&(r.prototype.webkitCreateShadowRoot=r.prototype.createShadowRoot),d(r.prototype,o),d(r.prototype,i),d(r.prototype,s),d(r.prototype,c),d(r.prototype,l),p(m,r,document.createElementNS(null,"x")),e.invalidateRendererBasedOnAttribute=t,e.matchesNames=w,e.originalMatches=g,e.wrappers.Element=r}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){switch(e){case"&":return"&";case"<":return"<";case">":return">";case'"':return""";case" ":return" "}}function n(e){return e.replace(L,t)}function r(e){return e.replace(O,t)}function o(e){for(var t={},n=0;n";case Node.TEXT_NODE:var u=e.data;return t&&N[t.localName]?u:r(u);case Node.COMMENT_NODE:return"";default:throw console.error(e),new Error("not implemented")}}function a(e){e instanceof _.HTMLTemplateElement&&(e=e.content);for(var t="",n=e.firstChild;n;n=n.nextSibling)t+=i(n,e);return t}function s(e,t,n){var r=n||"div";e.textContent="";var o=T(e.ownerDocument.createElement(r));o.innerHTML=t;for(var i;i=o.firstChild;)e.appendChild(M(i))}function c(e){h.call(this,e)}function l(e,t){var n=T(e.cloneNode(!1));n.innerHTML=t;for(var r,o=T(document.createDocumentFragment());r=n.firstChild;)o.appendChild(r);return M(o)}function u(t){return function(){return e.renderAllPending(),S(this)[t]}}function d(e){m(c,e,u(e))}function p(t){Object.defineProperty(c.prototype,t,{get:u(t),set:function(n){e.renderAllPending(),S(this)[t]=n},configurable:!0,enumerable:!0})}function f(t){Object.defineProperty(c.prototype,t,{value:function(){return e.renderAllPending(),S(this)[t].apply(S(this),arguments)},configurable:!0,enumerable:!0})}var h=e.wrappers.Element,m=e.defineGetter,w=e.enqueueMutation,v=e.mixin,g=e.nodesWereAdded,b=e.nodesWereRemoved,y=e.registerWrapper,E=e.snapshotNodeList,S=e.unsafeUnwrap,T=e.unwrap,M=e.wrap,_=e.wrappers,L=/[&\u00A0"]/g,O=/[&\u00A0<>]/g,C=o(["area","base","br","col","command","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"]),N=o(["style","script","xmp","iframe","noembed","noframes","plaintext","noscript"]),D=/MSIE/.test(navigator.userAgent),j=window.HTMLElement,H=window.HTMLTemplateElement;c.prototype=Object.create(h.prototype),v(c.prototype,{get innerHTML(){return a(this)},set innerHTML(e){if(D&&N[this.localName])return void(this.textContent=e);var t=E(this.childNodes);this.invalidateShadowRenderer()?this instanceof _.HTMLTemplateElement?s(this.content,e):s(this,e,this.tagName):!H&&this instanceof _.HTMLTemplateElement?s(this.content,e):S(this).innerHTML=e;var n=E(this.childNodes);w(this,"childList",{addedNodes:n,removedNodes:t}),b(t),g(n,this)},get outerHTML(){return i(this,this.parentNode)},set outerHTML(e){var t=this.parentNode;if(t){t.invalidateShadowRenderer();var n=l(t,e);t.replaceChild(n,this)}},insertAdjacentHTML:function(e,t){var n,r;switch(String(e).toLowerCase()){case"beforebegin":n=this.parentNode,r=this;break;case"afterend":n=this.parentNode,r=this.nextSibling;break;case"afterbegin":n=this,r=this.firstChild;break;case"beforeend":n=this,r=null;break;default:return}var o=l(n,t);n.insertBefore(o,r)},get hidden(){return this.hasAttribute("hidden")},set hidden(e){e?this.setAttribute("hidden",""):this.removeAttribute("hidden")}}),["clientHeight","clientLeft","clientTop","clientWidth","offsetHeight","offsetLeft","offsetTop","offsetWidth","scrollHeight","scrollWidth"].forEach(d),["scrollLeft","scrollTop"].forEach(p),["getBoundingClientRect","getClientRects","scrollIntoView"].forEach(f),y(j,c,document.createElement("b")),e.wrappers.HTMLElement=c,e.getInnerHTML=a,e.setInnerHTML=s}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.unsafeUnwrap,a=e.wrap,s=window.HTMLCanvasElement;t.prototype=Object.create(n.prototype),r(t.prototype,{getContext:function(){var e=i(this).getContext.apply(i(this),arguments);return e&&a(e)}}),o(s,t,document.createElement("canvas")),e.wrappers.HTMLCanvasElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=window.HTMLContentElement;t.prototype=Object.create(n.prototype),r(t.prototype,{constructor:t,get select(){return this.getAttribute("select")},set select(e){this.setAttribute("select",e)},setAttribute:function(e,t){n.prototype.setAttribute.call(this,e,t),"select"===String(e).toLowerCase()&&this.invalidateShadowRenderer(!0)}}),i&&o(i,t),e.wrappers.HTMLContentElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.wrapHTMLCollection,a=e.unwrap,s=window.HTMLFormElement;t.prototype=Object.create(n.prototype),r(t.prototype,{get elements(){return i(a(this).elements)}}),o(s,t,document.createElement("form")),e.wrappers.HTMLFormElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){r.call(this,e)}function n(e,t){if(!(this instanceof n))throw new TypeError("DOM object constructor cannot be called as a function.");var o=i(document.createElement("img"));r.call(this,o),a(o,this),void 0!==e&&(o.width=e),void 0!==t&&(o.height=t)}var r=e.wrappers.HTMLElement,o=e.registerWrapper,i=e.unwrap,a=e.rewrap,s=window.HTMLImageElement;t.prototype=Object.create(r.prototype),o(s,t,document.createElement("img")),n.prototype=t.prototype,e.wrappers.HTMLImageElement=t,e.wrappers.Image=n}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=(e.mixin,e.wrappers.NodeList,e.registerWrapper),o=window.HTMLShadowElement;t.prototype=Object.create(n.prototype),t.prototype.constructor=t,o&&r(o,t),e.wrappers.HTMLShadowElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){if(!e.defaultView)return e;var t=d.get(e);if(!t){for(t=e.implementation.createHTMLDocument("");t.lastChild;)t.removeChild(t.lastChild);d.set(e,t)}return t}function n(e){for(var n,r=t(e.ownerDocument),o=c(r.createDocumentFragment());n=e.firstChild;)o.appendChild(n);return o}function r(e){if(o.call(this,e),!p){var t=n(e);u.set(this,l(t))}}var o=e.wrappers.HTMLElement,i=e.mixin,a=e.registerWrapper,s=e.unsafeUnwrap,c=e.unwrap,l=e.wrap,u=new WeakMap,d=new WeakMap,p=window.HTMLTemplateElement;r.prototype=Object.create(o.prototype),i(r.prototype,{constructor:r,get content(){return p?l(s(this).content):u.get(this)}}),p&&a(p,r),e.wrappers.HTMLTemplateElement=r}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.registerWrapper,o=window.HTMLMediaElement;o&&(t.prototype=Object.create(n.prototype),r(o,t,document.createElement("audio")),e.wrappers.HTMLMediaElement=t)}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){r.call(this,e)}function n(e){if(!(this instanceof n))throw new TypeError("DOM object constructor cannot be called as a function.");var t=i(document.createElement("audio"));r.call(this,t),a(t,this),t.setAttribute("preload","auto"),void 0!==e&&t.setAttribute("src",e)}var r=e.wrappers.HTMLMediaElement,o=e.registerWrapper,i=e.unwrap,a=e.rewrap,s=window.HTMLAudioElement;s&&(t.prototype=Object.create(r.prototype),o(s,t,document.createElement("audio")),n.prototype=t.prototype,e.wrappers.HTMLAudioElement=t,e.wrappers.Audio=n)}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){return e.replace(/\s+/g," ").trim()}function n(e){o.call(this,e)}function r(e,t,n,i){if(!(this instanceof r))throw new TypeError("DOM object constructor cannot be called as a function.");var a=c(document.createElement("option"));o.call(this,a),s(a,this),void 0!==e&&(a.text=e),void 0!==t&&a.setAttribute("value",t),n===!0&&a.setAttribute("selected",""),a.selected=i===!0}var o=e.wrappers.HTMLElement,i=e.mixin,a=e.registerWrapper,s=e.rewrap,c=e.unwrap,l=e.wrap,u=window.HTMLOptionElement;n.prototype=Object.create(o.prototype),i(n.prototype,{get text(){return t(this.textContent)},set text(e){this.textContent=t(String(e))},get form(){return l(c(this).form)}}),a(u,n,document.createElement("option")),r.prototype=n.prototype,e.wrappers.HTMLOptionElement=n,e.wrappers.Option=r}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.unwrap,a=e.wrap,s=window.HTMLSelectElement;t.prototype=Object.create(n.prototype),r(t.prototype,{add:function(e,t){"object"==typeof t&&(t=i(t)),i(this).add(i(e),t)},remove:function(e){return void 0===e?void n.prototype.remove.call(this):("object"==typeof e&&(e=i(e)),void i(this).remove(e))},get form(){return a(i(this).form)}}),o(s,t,document.createElement("select")),e.wrappers.HTMLSelectElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.unwrap,a=e.wrap,s=e.wrapHTMLCollection,c=window.HTMLTableElement;t.prototype=Object.create(n.prototype),r(t.prototype,{get caption(){return a(i(this).caption)},createCaption:function(){return a(i(this).createCaption())},get tHead(){return a(i(this).tHead)},createTHead:function(){return a(i(this).createTHead())},createTFoot:function(){return a(i(this).createTFoot())},get tFoot(){return a(i(this).tFoot)},get tBodies(){return s(i(this).tBodies)},createTBody:function(){return a(i(this).createTBody())},get rows(){return s(i(this).rows)},insertRow:function(e){return a(i(this).insertRow(e))}}),o(c,t,document.createElement("table")),e.wrappers.HTMLTableElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.wrapHTMLCollection,a=e.unwrap,s=e.wrap,c=window.HTMLTableSectionElement;t.prototype=Object.create(n.prototype),r(t.prototype,{constructor:t,get rows(){return i(a(this).rows)},insertRow:function(e){return s(a(this).insertRow(e))}}),o(c,t,document.createElement("thead")),e.wrappers.HTMLTableSectionElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.HTMLElement,r=e.mixin,o=e.registerWrapper,i=e.wrapHTMLCollection,a=e.unwrap,s=e.wrap,c=window.HTMLTableRowElement;t.prototype=Object.create(n.prototype),r(t.prototype,{get cells(){return i(a(this).cells)},insertCell:function(e){return s(a(this).insertCell(e))}}),o(c,t,document.createElement("tr")),e.wrappers.HTMLTableRowElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){switch(e.localName){case"content":return new n(e);case"shadow":return new o(e);case"template":return new i(e)}r.call(this,e)}var n=e.wrappers.HTMLContentElement,r=e.wrappers.HTMLElement,o=e.wrappers.HTMLShadowElement,i=e.wrappers.HTMLTemplateElement,a=(e.mixin,e.registerWrapper),s=window.HTMLUnknownElement;t.prototype=Object.create(r.prototype),a(s,t),e.wrappers.HTMLUnknownElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";var t=e.wrappers.Element,n=e.wrappers.HTMLElement,r=e.registerObject,o=e.defineWrapGetter,i="http://www.w3.org/2000/svg",a=document.createElementNS(i,"title"),s=r(a),c=Object.getPrototypeOf(s.prototype).constructor;if(!("classList"in a)){var l=Object.getOwnPropertyDescriptor(t.prototype,"classList");Object.defineProperty(n.prototype,"classList",l),delete t.prototype.classList}o(c,"ownerSVGElement"),e.wrappers.SVGElement=c}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){p.call(this,e)}var n=e.mixin,r=e.registerWrapper,o=e.unwrap,i=e.wrap,a=window.SVGUseElement,s="http://www.w3.org/2000/svg",c=i(document.createElementNS(s,"g")),l=document.createElementNS(s,"use"),u=c.constructor,d=Object.getPrototypeOf(u.prototype),p=d.constructor;t.prototype=Object.create(d),"instanceRoot"in l&&n(t.prototype,{get instanceRoot(){return i(o(this).instanceRoot)},get animatedInstanceRoot(){return i(o(this).animatedInstanceRoot)}}),r(a,t,l),e.wrappers.SVGUseElement=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.EventTarget,r=e.mixin,o=e.registerWrapper,i=e.unsafeUnwrap,a=e.wrap,s=window.SVGElementInstance;s&&(t.prototype=Object.create(n.prototype),r(t.prototype,{get correspondingElement(){return a(i(this).correspondingElement)},get correspondingUseElement(){return a(i(this).correspondingUseElement)},get parentNode(){return a(i(this).parentNode)},get childNodes(){throw new Error("Not implemented")},get firstChild(){return a(i(this).firstChild)},get lastChild(){return a(i(this).lastChild)},get previousSibling(){return a(i(this).previousSibling)},get nextSibling(){return a(i(this).nextSibling)}}),o(s,t),e.wrappers.SVGElementInstance=t)}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){o(e,this)}var n=e.mixin,r=e.registerWrapper,o=e.setWrapper,i=e.unsafeUnwrap,a=e.unwrap,s=e.unwrapIfNeeded,c=e.wrap,l=window.CanvasRenderingContext2D;n(t.prototype,{get canvas(){return c(i(this).canvas)},drawImage:function(){arguments[0]=s(arguments[0]),i(this).drawImage.apply(i(this),arguments)},createPattern:function(){return arguments[0]=a(arguments[0]),i(this).createPattern.apply(i(this),arguments)}}),r(l,t,document.createElement("canvas").getContext("2d")),e.wrappers.CanvasRenderingContext2D=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){o(e,this)}var n=e.mixin,r=e.registerWrapper,o=e.setWrapper,i=e.unsafeUnwrap,a=e.unwrapIfNeeded,s=e.wrap,c=window.WebGLRenderingContext;if(c){n(t.prototype,{get canvas(){return s(i(this).canvas)},texImage2D:function(){arguments[5]=a(arguments[5]),i(this).texImage2D.apply(i(this),arguments)},texSubImage2D:function(){arguments[6]=a(arguments[6]),i(this).texSubImage2D.apply(i(this),arguments)}});var l=/WebKit/.test(navigator.userAgent)?{drawingBufferHeight:null,drawingBufferWidth:null}:{};r(c,t,l),e.wrappers.WebGLRenderingContext=t}}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){r(e,this)}var n=e.registerWrapper,r=e.setWrapper,o=e.unsafeUnwrap,i=e.unwrap,a=e.unwrapIfNeeded,s=e.wrap,c=window.Range;t.prototype={get startContainer(){return s(o(this).startContainer)},get endContainer(){return s(o(this).endContainer)},get commonAncestorContainer(){return s(o(this).commonAncestorContainer)},setStart:function(e,t){o(this).setStart(a(e),t)},setEnd:function(e,t){o(this).setEnd(a(e),t)},setStartBefore:function(e){o(this).setStartBefore(a(e))},setStartAfter:function(e){o(this).setStartAfter(a(e))},setEndBefore:function(e){o(this).setEndBefore(a(e))},setEndAfter:function(e){o(this).setEndAfter(a(e))},selectNode:function(e){o(this).selectNode(a(e))},selectNodeContents:function(e){o(this).selectNodeContents(a(e))},compareBoundaryPoints:function(e,t){return o(this).compareBoundaryPoints(e,i(t))},extractContents:function(){return s(o(this).extractContents())},cloneContents:function(){return s(o(this).cloneContents())},insertNode:function(e){o(this).insertNode(a(e))},surroundContents:function(e){o(this).surroundContents(a(e))},cloneRange:function(){return s(o(this).cloneRange())},isPointInRange:function(e,t){return o(this).isPointInRange(a(e),t)},comparePoint:function(e,t){return o(this).comparePoint(a(e),t)},intersectsNode:function(e){return o(this).intersectsNode(a(e))},toString:function(){return o(this).toString()}},c.prototype.createContextualFragment&&(t.prototype.createContextualFragment=function(e){return s(o(this).createContextualFragment(e))}),n(window.Range,t,document.createRange()),e.wrappers.Range=t}(window.ShadowDOMPolyfill),function(e){"use strict";var t=e.GetElementsByInterface,n=e.ParentNodeInterface,r=e.SelectorsInterface,o=e.mixin,i=e.registerObject,a=i(document.createDocumentFragment());o(a.prototype,n),o(a.prototype,r),o(a.prototype,t);var s=i(document.createComment(""));e.wrappers.Comment=s,e.wrappers.DocumentFragment=a}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){var t=d(u(e).ownerDocument.createDocumentFragment());n.call(this,t),c(t,this);var o=e.shadowRoot;f.set(this,o),this.treeScope_=new r(this,a(o||e)),p.set(this,e)}var n=e.wrappers.DocumentFragment,r=e.TreeScope,o=e.elementFromPoint,i=e.getInnerHTML,a=e.getTreeScope,s=e.mixin,c=e.rewrap,l=e.setInnerHTML,u=e.unsafeUnwrap,d=e.unwrap,p=new WeakMap,f=new WeakMap,h=/[ \t\n\r\f]/;t.prototype=Object.create(n.prototype),s(t.prototype,{constructor:t,get innerHTML(){return i(this)},set innerHTML(e){l(this,e),this.invalidateShadowRenderer()},get olderShadowRoot(){return f.get(this)||null},get host(){return p.get(this)||null},invalidateShadowRenderer:function(){return p.get(this).invalidateShadowRenderer()},elementFromPoint:function(e,t){return o(this,this.ownerDocument,e,t)},getElementById:function(e){return h.test(e)?null:this.querySelector('[id="'+e+'"]')}}),e.wrappers.ShadowRoot=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){e.previousSibling_=e.previousSibling,e.nextSibling_=e.nextSibling,e.parentNode_=e.parentNode}function n(n,o,i){var a=x(n),s=x(o),c=i?x(i):null;if(r(o),t(o),i)n.firstChild===i&&(n.firstChild_=i),i.previousSibling_=i.previousSibling;else{n.lastChild_=n.lastChild,n.lastChild===n.firstChild&&(n.firstChild_=n.firstChild);var l=R(a.lastChild);l&&(l.nextSibling_=l.nextSibling)}e.originalInsertBefore.call(a,s,c)}function r(n){var r=x(n),o=r.parentNode;if(o){var i=R(o);t(n),n.previousSibling&&(n.previousSibling.nextSibling_=n),n.nextSibling&&(n.nextSibling.previousSibling_=n),i.lastChild===n&&(i.lastChild_=n),i.firstChild===n&&(i.firstChild_=n),e.originalRemoveChild.call(o,r)}}function o(e){I.set(e,[])}function i(e){var t=I.get(e);return t||I.set(e,t=[]),t}function a(e){for(var t=[],n=0,r=e.firstChild;r;r=r.nextSibling)t[n++]=r;return t}function s(){for(var e=0;em;m++){var w=R(i[u++]);s.get(w)||r(w)}for(var v=f.addedCount,g=i[u]&&R(i[u]),m=0;v>m;m++){var b=o[l++],y=b.node;n(t,y,g),s.set(y,!0),b.sync(s)}d+=v}for(var p=d;p=0;o--){var i=r[o],a=m(i);if(a){var s=i.olderShadowRoot;s&&(n=h(s));for(var c=0;c=0;u--)l=Object.create(l);["createdCallback","attachedCallback","detachedCallback","attributeChangedCallback"].forEach(function(e){var t=o[e];t&&(l[e]=function(){C(this)instanceof r||M(this),t.apply(C(this),arguments)})});var d={prototype:l};i&&(d["extends"]=i),r.prototype=o,r.prototype.constructor=r,e.constructorTable.set(l,r),e.nativePrototypeTable.set(o,l);x.call(O(this),t,d);return r},b([window.HTMLDocument||window.Document],["registerElement"])}b([window.HTMLBodyElement,window.HTMLDocument||window.Document,window.HTMLHeadElement,window.HTMLHtmlElement],["appendChild","compareDocumentPosition","contains","getElementsByClassName","getElementsByTagName","getElementsByTagNameNS","insertBefore","querySelector","querySelectorAll","removeChild","replaceChild"]),b([window.HTMLBodyElement,window.HTMLHeadElement,window.HTMLHtmlElement],y),b([window.HTMLDocument||window.Document],["adoptNode","importNode","contains","createComment","createDocumentFragment","createElement","createElementNS","createEvent","createEventNS","createRange","createTextNode","elementFromPoint","getElementById","getElementsByName","getSelection"]),E(t.prototype,l),E(t.prototype,d),E(t.prototype,f),E(t.prototype,{get implementation(){var e=D.get(this);
-return e?e:(e=new a(O(this).implementation),D.set(this,e),e)},get defaultView(){return C(O(this).defaultView)}}),S(window.Document,t,document.implementation.createHTMLDocument("")),window.HTMLDocument&&S(window.HTMLDocument,t),N([window.HTMLBodyElement,window.HTMLDocument||window.Document,window.HTMLHeadElement]),s(a,"createDocumentType"),s(a,"createDocument"),s(a,"createHTMLDocument"),c(a,"hasFeature"),S(window.DOMImplementation,a),b([window.DOMImplementation],["createDocumentType","createDocument","createHTMLDocument","hasFeature"]),e.adoptNodeNoRemove=r,e.wrappers.DOMImplementation=a,e.wrappers.Document=t}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){n.call(this,e)}var n=e.wrappers.EventTarget,r=e.wrappers.Selection,o=e.mixin,i=e.registerWrapper,a=e.renderAllPending,s=e.unwrap,c=e.unwrapIfNeeded,l=e.wrap,u=window.Window,d=window.getComputedStyle,p=window.getDefaultComputedStyle,f=window.getSelection;t.prototype=Object.create(n.prototype),u.prototype.getComputedStyle=function(e,t){return l(this||window).getComputedStyle(c(e),t)},p&&(u.prototype.getDefaultComputedStyle=function(e,t){return l(this||window).getDefaultComputedStyle(c(e),t)}),u.prototype.getSelection=function(){return l(this||window).getSelection()},delete window.getComputedStyle,delete window.getDefaultComputedStyle,delete window.getSelection,["addEventListener","removeEventListener","dispatchEvent"].forEach(function(e){u.prototype[e]=function(){var t=l(this||window);return t[e].apply(t,arguments)},delete window[e]}),o(t.prototype,{getComputedStyle:function(e,t){return a(),d.call(s(this),c(e),t)},getSelection:function(){return a(),new r(f.call(s(this)))},get document(){return l(s(this).document)}}),p&&(t.prototype.getDefaultComputedStyle=function(e,t){return a(),p.call(s(this),c(e),t)}),i(u,t,window),e.wrappers.Window=t}(window.ShadowDOMPolyfill),function(e){"use strict";var t=e.unwrap,n=window.DataTransfer||window.Clipboard,r=n.prototype.setDragImage;r&&(n.prototype.setDragImage=function(e,n,o){r.call(this,t(e),n,o)})}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){var t;t=e instanceof i?e:new i(e&&o(e)),r(t,this)}var n=e.registerWrapper,r=e.setWrapper,o=e.unwrap,i=window.FormData;i&&(n(i,t,new i),e.wrappers.FormData=t)}(window.ShadowDOMPolyfill),function(e){"use strict";var t=e.unwrapIfNeeded,n=XMLHttpRequest.prototype.send;XMLHttpRequest.prototype.send=function(e){return n.call(this,t(e))}}(window.ShadowDOMPolyfill),function(e){"use strict";function t(e){var t=n[e],r=window[t];if(r){var o=document.createElement(e),i=o.constructor;window[t]=i}}var n=(e.isWrapperFor,{a:"HTMLAnchorElement",area:"HTMLAreaElement",audio:"HTMLAudioElement",base:"HTMLBaseElement",body:"HTMLBodyElement",br:"HTMLBRElement",button:"HTMLButtonElement",canvas:"HTMLCanvasElement",caption:"HTMLTableCaptionElement",col:"HTMLTableColElement",content:"HTMLContentElement",data:"HTMLDataElement",datalist:"HTMLDataListElement",del:"HTMLModElement",dir:"HTMLDirectoryElement",div:"HTMLDivElement",dl:"HTMLDListElement",embed:"HTMLEmbedElement",fieldset:"HTMLFieldSetElement",font:"HTMLFontElement",form:"HTMLFormElement",frame:"HTMLFrameElement",frameset:"HTMLFrameSetElement",h1:"HTMLHeadingElement",head:"HTMLHeadElement",hr:"HTMLHRElement",html:"HTMLHtmlElement",iframe:"HTMLIFrameElement",img:"HTMLImageElement",input:"HTMLInputElement",keygen:"HTMLKeygenElement",label:"HTMLLabelElement",legend:"HTMLLegendElement",li:"HTMLLIElement",link:"HTMLLinkElement",map:"HTMLMapElement",marquee:"HTMLMarqueeElement",menu:"HTMLMenuElement",menuitem:"HTMLMenuItemElement",meta:"HTMLMetaElement",meter:"HTMLMeterElement",object:"HTMLObjectElement",ol:"HTMLOListElement",optgroup:"HTMLOptGroupElement",option:"HTMLOptionElement",output:"HTMLOutputElement",p:"HTMLParagraphElement",param:"HTMLParamElement",pre:"HTMLPreElement",progress:"HTMLProgressElement",q:"HTMLQuoteElement",script:"HTMLScriptElement",select:"HTMLSelectElement",shadow:"HTMLShadowElement",source:"HTMLSourceElement",span:"HTMLSpanElement",style:"HTMLStyleElement",table:"HTMLTableElement",tbody:"HTMLTableSectionElement",template:"HTMLTemplateElement",textarea:"HTMLTextAreaElement",thead:"HTMLTableSectionElement",time:"HTMLTimeElement",title:"HTMLTitleElement",tr:"HTMLTableRowElement",track:"HTMLTrackElement",ul:"HTMLUListElement",video:"HTMLVideoElement"});Object.keys(n).forEach(t),Object.getOwnPropertyNames(e.wrappers).forEach(function(t){window[t]=e.wrappers[t]})}(window.ShadowDOMPolyfill),function(e){function t(e,t){var n="";return Array.prototype.forEach.call(e,function(e){n+=e.textContent+"\n\n"}),t||(n=n.replace(d,"")),n}function n(e){var t=document.createElement("style");return t.textContent=e,t}function r(e){var t=n(e);document.head.appendChild(t);var r=[];if(t.sheet)try{r=t.sheet.cssRules}catch(o){}else console.warn("sheet not found",t);return t.parentNode.removeChild(t),r}function o(){N.initialized=!0,document.body.appendChild(N);var e=N.contentDocument,t=e.createElement("base");t.href=document.baseURI,e.head.appendChild(t)}function i(e){N.initialized||o(),document.body.appendChild(N),e(N.contentDocument),document.body.removeChild(N)}function a(e,t){if(t){var o;if(e.match("@import")&&j){var a=n(e);i(function(e){e.head.appendChild(a.impl),o=Array.prototype.slice.call(a.sheet.cssRules,0),t(o)})}else o=r(e),t(o)}}function s(e){e&&l().appendChild(document.createTextNode(e))}function c(e,t){var r=n(e);r.setAttribute(t,""),r.setAttribute(x,""),document.head.appendChild(r)}function l(){return D||(D=document.createElement("style"),D.setAttribute(x,""),D[x]=!0),D}var u={strictStyling:!1,registry:{},shimStyling:function(e,n,r){var o=this.prepareRoot(e,n,r),i=this.isTypeExtension(r),a=this.makeScopeSelector(n,i),s=t(o,!0);s=this.scopeCssText(s,a),e&&(e.shimmedStyle=s),this.addCssToDocument(s,n)},shimStyle:function(e,t){return this.shimCssText(e.textContent,t)},shimCssText:function(e,t){return e=this.insertDirectives(e),this.scopeCssText(e,t)},makeScopeSelector:function(e,t){return e?t?"[is="+e+"]":e:""},isTypeExtension:function(e){return e&&e.indexOf("-")<0},prepareRoot:function(e,t,n){var r=this.registerRoot(e,t,n);return this.replaceTextInStyles(r.rootStyles,this.insertDirectives),this.removeStyles(e,r.rootStyles),this.strictStyling&&this.applyScopeToContent(e,t),r.scopeStyles},removeStyles:function(e,t){for(var n,r=0,o=t.length;o>r&&(n=t[r]);r++)n.parentNode.removeChild(n)},registerRoot:function(e,t,n){var r=this.registry[t]={root:e,name:t,extendsName:n},o=this.findStyles(e);r.rootStyles=o,r.scopeStyles=r.rootStyles;var i=this.registry[r.extendsName];return i&&(r.scopeStyles=i.scopeStyles.concat(r.scopeStyles)),r},findStyles:function(e){if(!e)return[];var t=e.querySelectorAll("style");return Array.prototype.filter.call(t,function(e){return!e.hasAttribute(R)})},applyScopeToContent:function(e,t){e&&(Array.prototype.forEach.call(e.querySelectorAll("*"),function(e){e.setAttribute(t,"")}),Array.prototype.forEach.call(e.querySelectorAll("template"),function(e){this.applyScopeToContent(e.content,t)},this))},insertDirectives:function(e){return e=this.insertPolyfillDirectivesInCssText(e),this.insertPolyfillRulesInCssText(e)},insertPolyfillDirectivesInCssText:function(e){return e=e.replace(p,function(e,t){return t.slice(0,-2)+"{"}),e.replace(f,function(e,t){return t+" {"})},insertPolyfillRulesInCssText:function(e){return e=e.replace(h,function(e,t){return t.slice(0,-1)}),e.replace(m,function(e,t,n,r){var o=e.replace(t,"").replace(n,"");return r+o})},scopeCssText:function(e,t){var n=this.extractUnscopedRulesFromCssText(e);if(e=this.insertPolyfillHostInCssText(e),e=this.convertColonHost(e),e=this.convertColonHostContext(e),e=this.convertShadowDOMSelectors(e),t){var e,r=this;a(e,function(n){e=r.scopeRules(n,t)})}return e=e+"\n"+n,e.trim()},extractUnscopedRulesFromCssText:function(e){for(var t,n="";t=w.exec(e);)n+=t[1].slice(0,-1)+"\n\n";for(;t=v.exec(e);)n+=t[0].replace(t[2],"").replace(t[1],t[3])+"\n\n";return n},convertColonHost:function(e){return this.convertColonRule(e,E,this.colonHostPartReplacer)},convertColonHostContext:function(e){return this.convertColonRule(e,S,this.colonHostContextPartReplacer)},convertColonRule:function(e,t,n){return e.replace(t,function(e,t,r,o){if(t=L,r){for(var i,a=r.split(","),s=[],c=0,l=a.length;l>c&&(i=a[c]);c++)i=i.trim(),s.push(n(t,i,o));return s.join(",")}return t+o})},colonHostContextPartReplacer:function(e,t,n){return t.match(g)?this.colonHostPartReplacer(e,t,n):e+t+n+", "+t+" "+e+n},colonHostPartReplacer:function(e,t,n){return e+t.replace(g,"")+n},convertShadowDOMSelectors:function(e){for(var t=0;t","+","~"],r=e,o="["+t+"]";return n.forEach(function(e){var t=r.split(e);r=t.map(function(e){var t=e.trim().replace(O,"");return t&&n.indexOf(t)<0&&t.indexOf(o)<0&&(e=t.replace(/([^:]*)(:*)(.*)/,"$1"+o+"$2$3")),e}).join(e)}),r},insertPolyfillHostInCssText:function(e){return e.replace(_,b).replace(M,g)},propertiesFromRule:function(e){var t=e.style.cssText;e.style.content&&!e.style.content.match(/['"]+|attr/)&&(t=t.replace(/content:[^;]*;/g,"content: '"+e.style.content+"';"));var n=e.style;for(var r in n)"initial"===n[r]&&(t+=r+": initial; ");return t},replaceTextInStyles:function(e,t){e&&t&&(e instanceof Array||(e=[e]),Array.prototype.forEach.call(e,function(e){e.textContent=t.call(this,e.textContent)},this))},addCssToDocument:function(e,t){e.match("@import")?c(e,t):s(e)}},d=/\/\*[^*]*\*+([^/*][^*]*\*+)*\//gim,p=/\/\*\s*@polyfill ([^*]*\*+([^/*][^*]*\*+)*\/)([^{]*?){/gim,f=/polyfill-next-selector[^}]*content\:[\s]*?['"](.*?)['"][;\s]*}([^{]*?){/gim,h=/\/\*\s@polyfill-rule([^*]*\*+([^/*][^*]*\*+)*)\//gim,m=/(polyfill-rule)[^}]*(content\:[\s]*['"](.*?)['"])[;\s]*[^}]*}/gim,w=/\/\*\s@polyfill-unscoped-rule([^*]*\*+([^/*][^*]*\*+)*)\//gim,v=/(polyfill-unscoped-rule)[^}]*(content\:[\s]*['"](.*?)['"])[;\s]*[^}]*}/gim,g="-shadowcsshost",b="-shadowcsscontext",y=")(?:\\(((?:\\([^)(]*\\)|[^)(]*)+?)\\))?([^,{]*)",E=new RegExp("("+g+y,"gim"),S=new RegExp("("+b+y,"gim"),T="([>\\s~+[.,{:][\\s\\S]*)?$",M=/\:host/gim,_=/\:host-context/gim,L=g+"-no-combinator",O=new RegExp(g,"gim"),C=(new RegExp(b,"gim"),[/\^\^/g,/\^/g,/\/shadow\//g,/\/shadow-deep\//g,/::shadow/g,/\/deep\//g,/::content/g]),N=document.createElement("iframe");N.style.display="none";var D,j=navigator.userAgent.match("Chrome"),H="shim-shadowdom",x="shim-shadowdom-css",R="no-shim";if(window.ShadowDOMPolyfill){s("style { display: none !important; }\n");var P=ShadowDOMPolyfill.wrap(document),I=P.querySelector("head");I.insertBefore(l(),I.childNodes[0]),document.addEventListener("DOMContentLoaded",function(){e.urlResolver;if(window.HTMLImports&&!HTMLImports.useNative){var t="link[rel=stylesheet]["+H+"]",n="style["+H+"]";HTMLImports.importer.documentPreloadSelectors+=","+t,HTMLImports.importer.importsPreloadSelectors+=","+t,HTMLImports.parser.documentSelectors=[HTMLImports.parser.documentSelectors,t,n].join(",");var r=HTMLImports.parser.parseGeneric;HTMLImports.parser.parseGeneric=function(e){if(!e[x]){var t=e.__importElement||e;if(!t.hasAttribute(H))return void r.call(this,e);e.__resource&&(t=e.ownerDocument.createElement("style"),t.textContent=e.__resource),HTMLImports.path.resolveUrlsInStyle(t),t.textContent=u.shimStyle(t),t.removeAttribute(H,""),t.setAttribute(x,""),t[x]=!0,t.parentNode!==I&&(e.parentNode===I?I.replaceChild(t,e):this.addElementToDocument(t)),t.__importParsed=!0,this.markParsingComplete(e),this.parseNext()}};var o=HTMLImports.parser.hasResource;HTMLImports.parser.hasResource=function(e){return"link"===e.localName&&"stylesheet"===e.rel&&e.hasAttribute(H)?e.__resource:o.call(this,e)}}})}e.ShadowCSS=u}(window.WebComponents)),function(){window.ShadowDOMPolyfill?(window.wrap=ShadowDOMPolyfill.wrapIfNeeded,window.unwrap=ShadowDOMPolyfill.unwrapIfNeeded):window.wrap=window.unwrap=function(e){return e}}(window.WebComponents),window.HTMLImports=window.HTMLImports||{flags:{}},function(e){function t(e,t){t=t||h,r(function(){i(e,t)},t)}function n(e){return"complete"===e.readyState||e.readyState===v}function r(e,t){if(n(t))e&&e();else{var o=function(){("complete"===t.readyState||t.readyState===v)&&(t.removeEventListener(g,o),r(e,t))};t.addEventListener(g,o)}}function o(e){e.target.__loaded=!0}function i(e,t){function n(){s==c&&e&&e()}function r(e){o(e),s++,n()}var i=t.querySelectorAll("link[rel=import]"),s=0,c=i.length;if(c)for(var l,u=0;c>u&&(l=i[u]);u++)a(l)?r.call(l,{target:l}):(l.addEventListener("load",r),l.addEventListener("error",r));else n()}function a(e){return d?e.__loaded||e["import"]&&"loading"!==e["import"].readyState:e.__importParsed}function s(e){for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)c(t)&&l(t)}function c(e){return"link"===e.localName&&"import"===e.rel}function l(e){var t=e["import"];t?o({target:e}):(e.addEventListener("load",o),e.addEventListener("error",o))}var u="import",d=Boolean(u in document.createElement("link")),p=Boolean(window.ShadowDOMPolyfill),f=function(e){return p?ShadowDOMPolyfill.wrapIfNeeded(e):e},h=f(document),m={get:function(){var e=HTMLImports.currentScript||document.currentScript||("complete"!==document.readyState?document.scripts[document.scripts.length-1]:null);return f(e)},configurable:!0};Object.defineProperty(document,"_currentScript",m),Object.defineProperty(h,"_currentScript",m);var w=/Trident|Edge/.test(navigator.userAgent),v=w?"complete":"interactive",g="readystatechange";d&&(new MutationObserver(function(e){for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)t.addedNodes&&s(t.addedNodes)}).observe(document.head,{childList:!0}),function(){if("loading"===document.readyState)for(var e,t=document.querySelectorAll("link[rel=import]"),n=0,r=t.length;r>n&&(e=t[n]);n++)l(e)}()),t(function(){HTMLImports.ready=!0,HTMLImports.readyTime=(new Date).getTime();var e=h.createEvent("CustomEvent");e.initCustomEvent("HTMLImportsLoaded",!0,!0,{}),h.dispatchEvent(e)}),e.IMPORT_LINK_TYPE=u,e.useNative=d,e.rootDocument=h,e.whenReady=t,e.isIE=w}(HTMLImports),function(e){var t=[],n=function(e){t.push(e)},r=function(){t.forEach(function(t){t(e)})};e.addModule=n,e.initializeModules=r}(HTMLImports),HTMLImports.addModule(function(e){var t=/(url\()([^)]*)(\))/g,n=/(@import[\s]+(?!url\())([^;]*)(;)/g,r={resolveUrlsInStyle:function(e){var t=e.ownerDocument,n=t.createElement("a");return e.textContent=this.resolveUrlsInCssText(e.textContent,n),e},resolveUrlsInCssText:function(e,r){var o=this.replaceUrls(e,r,t);return o=this.replaceUrls(o,r,n)},replaceUrls:function(e,t,n){return e.replace(n,function(e,n,r,o){var i=r.replace(/["']/g,"");return t.href=i,i=t.href,n+"'"+i+"'"+o})}};e.path=r}),HTMLImports.addModule(function(e){var t={async:!0,ok:function(e){return e.status>=200&&e.status<300||304===e.status||0===e.status},load:function(n,r,o){var i=new XMLHttpRequest;return(e.flags.debug||e.flags.bust)&&(n+="?"+Math.random()),i.open("GET",n,t.async),i.addEventListener("readystatechange",function(){if(4===i.readyState){var e=i.getResponseHeader("Location"),n=null;if(e)var n="/"===e.substr(0,1)?location.origin+e:e;r.call(o,!t.ok(i)&&i,i.response||i.responseText,n)}}),i.send(),i},loadDocument:function(e,t,n){this.load(e,t,n).responseType="document"}};e.xhr=t}),HTMLImports.addModule(function(e){var t=e.xhr,n=e.flags,r=function(e,t){this.cache={},this.onload=e,this.oncomplete=t,this.inflight=0,this.pending={}};r.prototype={addNodes:function(e){this.inflight+=e.length;for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)this.require(t);this.checkDone()},addNode:function(e){this.inflight++,this.require(e),this.checkDone()},require:function(e){var t=e.src||e.href;e.__nodeUrl=t,this.dedupe(t,e)||this.fetch(t,e)},dedupe:function(e,t){if(this.pending[e])return this.pending[e].push(t),!0;return this.cache[e]?(this.onload(e,t,this.cache[e]),this.tail(),!0):(this.pending[e]=[t],!1)},fetch:function(e,r){if(n.load&&console.log("fetch",e,r),e)if(e.match(/^data:/)){var o=e.split(","),i=o[0],a=o[1];a=i.indexOf(";base64")>-1?atob(a):decodeURIComponent(a),setTimeout(function(){this.receive(e,r,null,a)}.bind(this),0)}else{var s=function(t,n,o){this.receive(e,r,t,n,o)}.bind(this);t.load(e,s)}else setTimeout(function(){this.receive(e,r,{error:"href must be specified"},null)}.bind(this),0)},receive:function(e,t,n,r,o){this.cache[e]=r;for(var i,a=this.pending[e],s=0,c=a.length;c>s&&(i=a[s]);s++)this.onload(e,i,r,n,o),this.tail();this.pending[e]=null},tail:function(){--this.inflight,this.checkDone()},checkDone:function(){this.inflight||this.oncomplete()}},e.Loader=r}),HTMLImports.addModule(function(e){var t=function(e){this.addCallback=e,this.mo=new MutationObserver(this.handler.bind(this))};t.prototype={handler:function(e){for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)"childList"===t.type&&t.addedNodes.length&&this.addedNodes(t.addedNodes)},addedNodes:function(e){this.addCallback&&this.addCallback(e);for(var t,n=0,r=e.length;r>n&&(t=e[n]);n++)t.children&&t.children.length&&this.addedNodes(t.children)},observe:function(e){this.mo.observe(e,{childList:!0,subtree:!0})}},e.Observer=t}),HTMLImports.addModule(function(e){function t(e){return"link"===e.localName&&e.rel===u}function n(e){var t=r(e);return"data:text/javascript;charset=utf-8,"+encodeURIComponent(t)}function r(e){return e.textContent+o(e)}function o(e){var t=e.ownerDocument;t.__importedScripts=t.__importedScripts||0;var n=e.ownerDocument.baseURI,r=t.__importedScripts?"-"+t.__importedScripts:"";return t.__importedScripts++,"\n//# sourceURL="+n+r+".js\n"}function i(e){var t=e.ownerDocument.createElement("style");return t.textContent=e.textContent,a.resolveUrlsInStyle(t),t}var a=e.path,s=e.rootDocument,c=e.flags,l=e.isIE,u=e.IMPORT_LINK_TYPE,d="link[rel="+u+"]",p={documentSelectors:d,importsSelectors:[d,"link[rel=stylesheet]","style","script:not([type])",'script[type="text/javascript"]'].join(","),map:{link:"parseLink",script:"parseScript",style:"parseStyle"},dynamicElements:[],parseNext:function(){var e=this.nextToParse();e&&this.parse(e)},parse:function(e){if(this.isParsed(e))return void(c.parse&&console.log("[%s] is already parsed",e.localName));var t=this[this.map[e.localName]];t&&(this.markParsing(e),t.call(this,e))},parseDynamic:function(e,t){this.dynamicElements.push(e),t||this.parseNext()},markParsing:function(e){c.parse&&console.log("parsing",e),this.parsingElement=e},markParsingComplete:function(e){e.__importParsed=!0,this.markDynamicParsingComplete(e),e.__importElement&&(e.__importElement.__importParsed=!0,this.markDynamicParsingComplete(e.__importElement)),this.parsingElement=null,c.parse&&console.log("completed",e)},markDynamicParsingComplete:function(e){var t=this.dynamicElements.indexOf(e);t>=0&&this.dynamicElements.splice(t,1)},parseImport:function(e){if(HTMLImports.__importsParsingHook&&HTMLImports.__importsParsingHook(e),e["import"]&&(e["import"].__importParsed=!0),this.markParsingComplete(e),e.dispatchEvent(e.__resource&&!e.__error?new CustomEvent("load",{bubbles:!1}):new CustomEvent("error",{bubbles:!1})),e.__pending)for(var t;e.__pending.length;)t=e.__pending.shift(),t&&t({target:e});this.parseNext()},parseLink:function(e){t(e)?this.parseImport(e):(e.href=e.href,this.parseGeneric(e))},parseStyle:function(e){var t=e;e=i(e),e.__importElement=t,this.parseGeneric(e)},parseGeneric:function(e){this.trackElement(e),this.addElementToDocument(e)},rootImportForElement:function(e){for(var t=e;t.ownerDocument.__importLink;)t=t.ownerDocument.__importLink;return t},addElementToDocument:function(e){var t=this.rootImportForElement(e.__importElement||e);t.parentNode.insertBefore(e,t)},trackElement:function(e,t){var n=this,r=function(r){t&&t(r),n.markParsingComplete(e),n.parseNext()};if(e.addEventListener("load",r),e.addEventListener("error",r),l&&"style"===e.localName){var o=!1;if(-1==e.textContent.indexOf("@import"))o=!0;else if(e.sheet){o=!0;for(var i,a=e.sheet.cssRules,s=a?a.length:0,c=0;s>c&&(i=a[c]);c++)i.type===CSSRule.IMPORT_RULE&&(o=o&&Boolean(i.styleSheet))}o&&e.dispatchEvent(new CustomEvent("load",{bubbles:!1}))}},parseScript:function(t){var r=document.createElement("script");r.__importElement=t,r.src=t.src?t.src:n(t),e.currentScript=t,this.trackElement(r,function(){r.parentNode.removeChild(r),e.currentScript=null}),this.addElementToDocument(r)},nextToParse:function(){return this._mayParse=[],!this.parsingElement&&(this.nextToParseInDoc(s)||this.nextToParseDynamic())},nextToParseInDoc:function(e,n){if(e&&this._mayParse.indexOf(e)<0){this._mayParse.push(e);for(var r,o=e.querySelectorAll(this.parseSelectorsForNode(e)),i=0,a=o.length;a>i&&(r=o[i]);i++)if(!this.isParsed(r))return this.hasResource(r)?t(r)?this.nextToParseInDoc(r["import"],r):r:void 0}return n},nextToParseDynamic:function(){return this.dynamicElements[0]},parseSelectorsForNode:function(e){var t=e.ownerDocument||e;return t===s?this.documentSelectors:this.importsSelectors},isParsed:function(e){return e.__importParsed},needsDynamicParsing:function(e){return this.dynamicElements.indexOf(e)>=0},hasResource:function(e){return t(e)&&void 0===e["import"]?!1:!0}};e.parser=p,e.IMPORT_SELECTOR=d}),HTMLImports.addModule(function(e){function t(e){return n(e,a)}function n(e,t){return"link"===e.localName&&e.getAttribute("rel")===t}function r(e){return!!Object.getOwnPropertyDescriptor(e,"baseURI")}function o(e,t){var n=document.implementation.createHTMLDocument(a);n._URL=t;var o=n.createElement("base");o.setAttribute("href",t),n.baseURI||r(n)||Object.defineProperty(n,"baseURI",{value:t});var i=n.createElement("meta");return i.setAttribute("charset","utf-8"),n.head.appendChild(i),n.head.appendChild(o),n.body.innerHTML=e,window.HTMLTemplateElement&&HTMLTemplateElement.bootstrap&&HTMLTemplateElement.bootstrap(n),n}var i=e.flags,a=e.IMPORT_LINK_TYPE,s=e.IMPORT_SELECTOR,c=e.rootDocument,l=e.Loader,u=e.Observer,d=e.parser,p={documents:{},documentPreloadSelectors:s,importsPreloadSelectors:[s].join(","),loadNode:function(e){f.addNode(e)},loadSubtree:function(e){var t=this.marshalNodes(e);f.addNodes(t)},marshalNodes:function(e){return e.querySelectorAll(this.loadSelectorsForNode(e))},loadSelectorsForNode:function(e){var t=e.ownerDocument||e;return t===c?this.documentPreloadSelectors:this.importsPreloadSelectors},loaded:function(e,n,r,a,s){if(i.load&&console.log("loaded",e,n),n.__resource=r,n.__error=a,t(n)){var c=this.documents[e];void 0===c&&(c=a?null:o(r,s||e),c&&(c.__importLink=n,this.bootDocument(c)),this.documents[e]=c),n["import"]=c}d.parseNext()},bootDocument:function(e){this.loadSubtree(e),this.observer.observe(e),d.parseNext()},loadedAll:function(){d.parseNext()}},f=new l(p.loaded.bind(p),p.loadedAll.bind(p));if(p.observer=new u,!document.baseURI){var h={get:function(){var e=document.querySelector("base");return e?e.href:window.location.href},configurable:!0};Object.defineProperty(document,"baseURI",h),Object.defineProperty(c,"baseURI",h)}e.importer=p,e.importLoader=f}),HTMLImports.addModule(function(e){var t=e.parser,n=e.importer,r={added:function(e){for(var r,o,i,a,s=0,c=e.length;c>s&&(a=e[s]);s++)r||(r=a.ownerDocument,o=t.isParsed(r)),i=this.shouldLoadNode(a),i&&n.loadNode(a),this.shouldParseNode(a)&&o&&t.parseDynamic(a,i)},shouldLoadNode:function(e){return 1===e.nodeType&&o.call(e,n.loadSelectorsForNode(e))},shouldParseNode:function(e){return 1===e.nodeType&&o.call(e,t.parseSelectorsForNode(e))}};n.observer.addCallback=r.added.bind(r);var o=HTMLElement.prototype.matches||HTMLElement.prototype.matchesSelector||HTMLElement.prototype.webkitMatchesSelector||HTMLElement.prototype.mozMatchesSelector||HTMLElement.prototype.msMatchesSelector}),function(e){function t(){HTMLImports.importer.bootDocument(o)}var n=e.initializeModules,r=e.isIE;if(!e.useNative){r&&"function"!=typeof window.CustomEvent&&(window.CustomEvent=function(e,t){t=t||{};var n=document.createEvent("CustomEvent");return n.initCustomEvent(e,Boolean(t.bubbles),Boolean(t.cancelable),t.detail),n},window.CustomEvent.prototype=window.Event.prototype),n();var o=e.rootDocument;"complete"===document.readyState||"interactive"===document.readyState&&!window.attachEvent?t():document.addEventListener("DOMContentLoaded",t)}}(HTMLImports),window.CustomElements=window.CustomElements||{flags:{}},function(e){var t=e.flags,n=[],r=function(e){n.push(e)},o=function(){n.forEach(function(t){t(e)})};e.addModule=r,e.initializeModules=o,e.hasNative=Boolean(document.registerElement),e.useNative=!t.register&&e.hasNative&&!window.ShadowDOMPolyfill&&(!window.HTMLImports||HTMLImports.useNative)}(CustomElements),CustomElements.addModule(function(e){function t(e,t){n(e,function(e){return t(e)?!0:void r(e,t)}),r(e,t)}function n(e,t,r){var o=e.firstElementChild;if(!o)for(o=e.firstChild;o&&o.nodeType!==Node.ELEMENT_NODE;)o=o.nextSibling;for(;o;)t(o,r)!==!0&&n(o,t,r),o=o.nextElementSibling;return null}function r(e,n){for(var r=e.shadowRoot;r;)t(r,n),r=r.olderShadowRoot}function o(e,t){a=[],i(e,t),a=null}function i(e,t){if(e=wrap(e),!(a.indexOf(e)>=0)){a.push(e);for(var n,r=e.querySelectorAll("link[rel="+s+"]"),o=0,c=r.length;c>o&&(n=r[o]);o++)n["import"]&&i(n["import"],t);t(e)}}var a,s=window.HTMLImports?HTMLImports.IMPORT_LINK_TYPE:"none";e.forDocumentTree=o,e.forSubtree=t}),CustomElements.addModule(function(e){function t(e){return n(e)||r(e)}function n(t){return e.upgrade(t)?!0:void s(t)}function r(e){y(e,function(e){return n(e)?!0:void 0})}function o(e){s(e),p(e)&&y(e,function(e){s(e)})}function i(e){M.push(e),T||(T=!0,setTimeout(a))}function a(){T=!1;for(var e,t=M,n=0,r=t.length;r>n&&(e=t[n]);n++)e();M=[]}function s(e){S?i(function(){c(e)}):c(e)}function c(e){e.__upgraded__&&(e.attachedCallback||e.detachedCallback)&&!e.__attached&&p(e)&&(e.__attached=!0,e.attachedCallback&&e.attachedCallback())}function l(e){u(e),y(e,function(e){u(e)})}function u(e){S?i(function(){d(e)}):d(e)}function d(e){e.__upgraded__&&(e.attachedCallback||e.detachedCallback)&&e.__attached&&!p(e)&&(e.__attached=!1,e.detachedCallback&&e.detachedCallback())}function p(e){for(var t=e,n=wrap(document);t;){if(t==n)return!0;t=t.parentNode||t.host}}function f(e){if(e.shadowRoot&&!e.shadowRoot.__watched){b.dom&&console.log("watching shadow-root for: ",e.localName);for(var t=e.shadowRoot;t;)w(t),t=t.olderShadowRoot}}function h(e){if(b.dom){var n=e[0];if(n&&"childList"===n.type&&n.addedNodes&&n.addedNodes){for(var r=n.addedNodes[0];r&&r!==document&&!r.host;)r=r.parentNode;var o=r&&(r.URL||r._URL||r.host&&r.host.localName)||"";o=o.split("/?").shift().split("/").pop()}console.group("mutations (%d) [%s]",e.length,o||"")}e.forEach(function(e){"childList"===e.type&&(_(e.addedNodes,function(e){e.localName&&t(e)}),_(e.removedNodes,function(e){e.localName&&l(e)}))}),b.dom&&console.groupEnd()}function m(e){for(e=wrap(e),e||(e=wrap(document));e.parentNode;)e=e.parentNode;var t=e.__observer;t&&(h(t.takeRecords()),a())}function w(e){if(!e.__observer){var t=new MutationObserver(h);t.observe(e,{childList:!0,subtree:!0}),e.__observer=t}}function v(e){e=wrap(e),b.dom&&console.group("upgradeDocument: ",e.baseURI.split("/").pop()),t(e),w(e),b.dom&&console.groupEnd()}function g(e){E(e,v)}var b=e.flags,y=e.forSubtree,E=e.forDocumentTree,S=!window.MutationObserver||window.MutationObserver===window.JsMutationObserver;e.hasPolyfillMutations=S;var T=!1,M=[],_=Array.prototype.forEach.call.bind(Array.prototype.forEach),L=Element.prototype.createShadowRoot;L&&(Element.prototype.createShadowRoot=function(){var e=L.call(this);return CustomElements.watchShadow(this),e}),e.watchShadow=f,e.upgradeDocumentTree=g,e.upgradeSubtree=r,e.upgradeAll=t,e.attachedNode=o,e.takeRecords=m}),CustomElements.addModule(function(e){function t(t){if(!t.__upgraded__&&t.nodeType===Node.ELEMENT_NODE){var r=t.getAttribute("is"),o=e.getRegisteredDefinition(r||t.localName);if(o){if(r&&o.tag==t.localName)return n(t,o);if(!r&&!o["extends"])return n(t,o)}}}function n(t,n){return a.upgrade&&console.group("upgrade:",t.localName),n.is&&t.setAttribute("is",n.is),r(t,n),t.__upgraded__=!0,i(t),e.attachedNode(t),e.upgradeSubtree(t),a.upgrade&&console.groupEnd(),t}function r(e,t){Object.__proto__?e.__proto__=t.prototype:(o(e,t.prototype,t["native"]),e.__proto__=t.prototype)}function o(e,t,n){for(var r={},o=t;o!==n&&o!==HTMLElement.prototype;){for(var i,a=Object.getOwnPropertyNames(o),s=0;i=a[s];s++)r[i]||(Object.defineProperty(e,i,Object.getOwnPropertyDescriptor(o,i)),r[i]=1);o=Object.getPrototypeOf(o)}}function i(e){e.createdCallback&&e.createdCallback()}var a=e.flags;e.upgrade=t,e.upgradeWithDefinition=n,e.implementPrototype=r}),CustomElements.addModule(function(e){function t(t,r){var c=r||{};if(!t)throw new Error("document.registerElement: first argument `name` must not be empty");if(t.indexOf("-")<0)throw new Error("document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '"+String(t)+"'.");if(o(t))throw new Error("Failed to execute 'registerElement' on 'Document': Registration failed for type '"+String(t)+"'. The type name is invalid.");if(l(t))throw new Error("DuplicateDefinitionError: a type with name '"+String(t)+"' is already registered");return c.prototype||(c.prototype=Object.create(HTMLElement.prototype)),c.__name=t.toLowerCase(),c.lifecycle=c.lifecycle||{},c.ancestry=i(c["extends"]),a(c),s(c),n(c.prototype),u(c.__name,c),c.ctor=d(c),c.ctor.prototype=c.prototype,c.prototype.constructor=c.ctor,e.ready&&w(document),c.ctor}function n(e){if(!e.setAttribute._polyfilled){var t=e.setAttribute;e.setAttribute=function(e,n){r.call(this,e,n,t)};var n=e.removeAttribute;e.removeAttribute=function(e){r.call(this,e,null,n)},e.setAttribute._polyfilled=!0}}function r(e,t,n){e=e.toLowerCase();var r=this.getAttribute(e);n.apply(this,arguments);var o=this.getAttribute(e);this.attributeChangedCallback&&o!==r&&this.attributeChangedCallback(e,r,o)}function o(e){for(var t=0;t=0&&b(r,HTMLElement),r)}function h(e){var t=L.call(this,e);return v(t),t}var m,w=e.upgradeDocumentTree,v=e.upgrade,g=e.upgradeWithDefinition,b=e.implementPrototype,y=e.useNative,E=["annotation-xml","color-profile","font-face","font-face-src","font-face-uri","font-face-format","font-face-name","missing-glyph"],S={},T="http://www.w3.org/1999/xhtml",M=document.createElement.bind(document),_=document.createElementNS.bind(document),L=Node.prototype.cloneNode;m=Object.__proto__||y?function(e,t){return e instanceof t}:function(e,t){for(var n=e;n;){if(n===t.prototype)return!0;n=n.__proto__}return!1},document.registerElement=t,document.createElement=f,document.createElementNS=p,Node.prototype.cloneNode=h,e.registry=S,e["instanceof"]=m,e.reservedTagList=E,e.getRegisteredDefinition=l,document.register=document.registerElement}),function(e){function t(){a(wrap(document)),window.HTMLImports&&(HTMLImports.__importsParsingHook=function(e){a(wrap(e["import"]))}),CustomElements.ready=!0,setTimeout(function(){CustomElements.readyTime=Date.now(),window.HTMLImports&&(CustomElements.elapsed=CustomElements.readyTime-HTMLImports.readyTime),document.dispatchEvent(new CustomEvent("WebComponentsReady",{bubbles:!0}))})}var n=e.useNative,r=e.initializeModules,o=/Trident/.test(navigator.userAgent);if(n){var i=function(){};e.watchShadow=i,e.upgrade=i,e.upgradeAll=i,e.upgradeDocumentTree=i,e.upgradeSubtree=i,e.takeRecords=i,e["instanceof"]=function(e,t){return e instanceof t}}else r();var a=e.upgradeDocumentTree;if(window.wrap||(window.ShadowDOMPolyfill?(window.wrap=ShadowDOMPolyfill.wrapIfNeeded,window.unwrap=ShadowDOMPolyfill.unwrapIfNeeded):window.wrap=window.unwrap=function(e){return e}),o&&"function"!=typeof window.CustomEvent&&(window.CustomEvent=function(e,t){t=t||{};var n=document.createEvent("CustomEvent");return n.initCustomEvent(e,Boolean(t.bubbles),Boolean(t.cancelable),t.detail),n},window.CustomEvent.prototype=window.Event.prototype),"complete"===document.readyState||e.flags.eager)t();else if("interactive"!==document.readyState||window.attachEvent||window.HTMLImports&&!window.HTMLImports.ready){var s=window.HTMLImports&&!HTMLImports.ready?"HTMLImportsLoaded":"DOMContentLoaded";window.addEventListener(s,t)}else t()}(window.CustomElements),function(){Function.prototype.bind||(Function.prototype.bind=function(e){var t=this,n=Array.prototype.slice.call(arguments,1);return function(){var r=n.slice();return r.push.apply(r,arguments),t.apply(e,r)}})}(window.WebComponents),function(e){"use strict";function t(){window.Polymer===o&&(window.Polymer=function(){throw new Error('You tried to use polymer without loading it first. To load polymer, ')})}if(!window.performance){var n=Date.now();window.performance={now:function(){return Date.now()-n}}}window.requestAnimationFrame||(window.requestAnimationFrame=function(){var e=window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame;return e?function(t){return e(function(){t(performance.now())})}:function(e){return window.setTimeout(e,1e3/60)}}()),window.cancelAnimationFrame||(window.cancelAnimationFrame=function(){return window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||function(e){clearTimeout(e)}}());var r=[],o=function(e){"string"!=typeof e&&1===arguments.length&&Array.prototype.push.call(arguments,document._currentScript),r.push(arguments)};window.Polymer=o,e.consumeDeclarations=function(t){e.consumeDeclarations=function(){throw"Possible attempt to load Polymer twice"},t&&t(r),r=null},HTMLImports.useNative?t():addEventListener("DOMContentLoaded",t)}(window.WebComponents),function(){var e=document.createElement("style");e.textContent="body {transition: opacity ease-in 0.2s; } \nbody[unresolved] {opacity: 0; display: block; overflow: hidden; position: relative; } \n";var t=document.querySelector("head");t.insertBefore(e,t.firstChild)}(window.WebComponents),function(e){window.Platform=e}(window.WebComponents);
\ No newline at end of file

From 15560ed347479fade242bf8e43ee39e65d3b0332 Mon Sep 17 00:00:00 2001
From: Daniel Freedman 
Date: Wed, 8 Apr 2015 13:27:20 -0700
Subject: [PATCH 0263/1006] Update README

---
 README.md | 53 +++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 41 insertions(+), 12 deletions(-)

diff --git a/README.md b/README.md
index 6b072c2e2..4f07a8327 100644
--- a/README.md
+++ b/README.md
@@ -16,6 +16,13 @@ materials.
 
 This will install `vulcanize` to `/usr/local/bin/vulcanize`.
 
+## Options
+- `-h`|`--help`: print this message
+- `-v`|`--version`: print version number
+- `-p `|`--abspath `: use  as the "webserver root", make all adjusted urls absolute
+- `--exclude `: exclude a subpath from root. Use multiple times to exclude multiple paths. Tags to excluded paths are kept.
+- `--strip-excludes`: Remove tags to external resources.
+
 ## Usage
 The command
 
@@ -31,29 +38,51 @@ The command
 will inline the HTML Imports of `target.html` and print the result to
 `build.html`.
 
+The command
+
+    vulcanize -p "path/to/target/" /target.html
+
+will inline the HTML Imports of `target.html`, treat `path/to/target/` as the
+webroot of target.html, and make all urls absolute to the provided webroot.
+
+The command
+
+    vulcanize --exclude "path/to/target/subpath/" --exclude "path/to/target/subpath2/" target.html
+
+will inline the HTML Imports of `target.html` that are not in the directory
+`path/to/target/subpath` nor `path/to/target/subpath2`.
+
+If the `--strip-excludes` flag is used, the HTML Import `` tags that
+point to resources in `path/totarget/subpath` and `path/to/target/subpath2/`
+will also be removed.
+
 ## Using vulcanize programmatically
 
-Vulcanize as a library has only one exported function.
+Vulcanize as a library has two exported function.
 
-`vulcanize.process` takes a `target` path to `target.html`, a `output directory`
-path for rebasing urls in the main document, a hydrolysis loader (more on that
-later), and a callback.
+`vulcanize.setOptions` takes an object of options similar to the command line
+options.
+- `abspath`: A folder to treat as "webroot".
+  - When specified, use an absolute path to `target`.
+- `excludes`: An array of RegExp objects to exclude paths from being inlined.
+- `stripExcludes`: Remove paths that were excluded by the regexes in `excludes`.
+
+`vulcanize.process` takes a `target` path to `target.html` and a callback.
 
 Example:
 ```js
 var vulcan = require('vulcanize');
 var hydrolysis = require('hydrolysis');
 
-var loader = new hydrolysis.Loader();
-loader.addResolver(new hydrolysis.FSResolver({}));
+vulcan.setOptions({
+  abspath: '',
+  excludes: [
+  ],
+  stripExcludes: false
+});
 
-vulcan.process(target, process.cwd(), loader, function(err, inlinedHtml) {
+vulcan.process(target, function(err, inlinedHtml) {
 });
 ```
 
-`vulcanize` depends on `hydrolysis` to crawl the tree of HTML Imports, and
-`vulcanize.process` depends on being given a `hydrolysis` loader to resolve
-files.
-**Note: fill this in later**
-
 [![Analytics](https://ga-beacon.appspot.com/UA-39334307-2/Polymer/vulcanize/README)](https://github.com/igrigorik/ga-beacon)

From 5dcc00586efa617c12e75d54134968c80a469ca7 Mon Sep 17 00:00:00 2001
From: Daniel Freedman 
Date: Wed, 8 Apr 2015 13:30:42 -0700
Subject: [PATCH 0264/1006] Make changelog a markdown file

---
 CHANGELOG => CHANGELOG.md | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
 rename CHANGELOG => CHANGELOG.md (95%)

diff --git a/CHANGELOG b/CHANGELOG.md
similarity index 95%
rename from CHANGELOG
rename to CHANGELOG.md
index b1b8d99ba..c966ea3f9 100644
--- a/CHANGELOG
+++ b/CHANGELOG.md
@@ -1,3 +1,20 @@
+### 1.0.0
+- Rewrite on top of [hydrolysis](https://github.com/PolymerLabs/hydrolysis) and
+[dom5](https://github.com/PolymerLabs/dom5)
+- Factor out `--csp` flag into [crisper](https://github.com/PolymerLabs/crisper)
+- Remove html and javascript minification
+### 0.7.10
+- Collapse whitespace instead of removing it
+- Keep unique license comments
+### 0.7.9
+- Honor  urls in inline styles
+### 0.7.8
+- Update to whacko 0.17.3
+### 0.7.7
+- Honor  tag
+- Make all schemas "absolute" urls
+### 0.7.6
+- Don't rewrite urls starting with '#'
 ### 0.7.5
 - Remove cssom, just use regexes
 ### 0.7.4

From e3d7f9ffe70cd90d1b3f3c176b48823c32a03446 Mon Sep 17 00:00:00 2001
From: Daniel Freedman 
Date: Wed, 8 Apr 2015 13:36:31 -0700
Subject: [PATCH 0265/1006] Fix markdown rendering of changelog

---
 CHANGELOG.md | 58 ++++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 52 insertions(+), 6 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index c966ea3f9..9a704d3d2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,42 +3,57 @@
 [dom5](https://github.com/PolymerLabs/dom5)
 - Factor out `--csp` flag into [crisper](https://github.com/PolymerLabs/crisper)
 - Remove html and javascript minification
+
 ### 0.7.10
 - Collapse whitespace instead of removing it
 - Keep unique license comments
+
 ### 0.7.9
-- Honor  urls in inline styles
+- Honor `` urls in inline styles
+
 ### 0.7.8
 - Update to whacko 0.17.3
+
 ### 0.7.7
-- Honor  tag
+- Honor `` tag
 - Make all schemas "absolute" urls
+
 ### 0.7.6
 - Don't rewrite urls starting with '#'
+
 ### 0.7.5
 - Remove cssom, just use regexes
+
 ### 0.7.4
-- Workaround for cssom not liking '{{ }}' bindings in ',
+      '',
+      '',
+      ''
+    ].join('\n');
+
+    var expectedBase = [
+      '',
+      '',
+      '',
+      '',
+      '',
+      '',
+      ''
+    ].join('\n');
+
+    var ast = parse(htmlBase);
+    pathresolver.acid(ast, inputPath);
+    pathresolver.resolvePaths(ast, inputPath, outputPath);
+
+    var actual = serialize(ast);
+    assert.equal(actual, expectedBase, 'base');
+  });
+
   test('Resolve ', function() {
     var htmlBase = [
       '',

From 7a4b83ade61c28774d5d2806da5cb9621759756f Mon Sep 17 00:00:00 2001
From: Daniel Freedman 
Date: Tue, 19 Jan 2016 17:19:59 -0800
Subject: [PATCH 0403/1006] [skip ci] update CHANGELOG

---
 CHANGELOG.md | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 91f2fe90c..a97bbaae1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+### 1.14.3
+- Fix for trailing slash in `` tag
+
 ### 1.14.2
 - Fix paths when preserving execution order moves scripts to body
 

From 31dd37fe08c5aefb00c8c54be8e9c11c3237fd68 Mon Sep 17 00:00:00 2001
From: Daniel Freedman 
Date: Tue, 19 Jan 2016 17:20:10 -0800
Subject: [PATCH 0404/1006] 1.14.3

---
 package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package.json b/package.json
index 08324b88c..60fc3c120 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "vulcanize",
-  "version": "1.14.2",
+  "version": "1.14.3",
   "description": "Process Web Components into one output file",
   "main": "lib/vulcan.js",
   "bin": {

From fbdf3e02d89b747d4abb81c8197b1e42a0301986 Mon Sep 17 00:00:00 2001
From: Daniel Freedman 
Date: Wed, 20 Jan 2016 17:16:38 -0800
Subject: [PATCH 0405/1006] Force a polymer style import to always go in a
 dom-module template

Fixes #301
---
 lib/matchers.js              |  1 +
 lib/vulcan.js                | 23 ++++++++++++++++++++++-
 test/html/inline-styles.html |  2 --
 test/test.js                 | 33 ++++++++++++++++++++++++++++++++-
 4 files changed, 55 insertions(+), 4 deletions(-)

diff --git a/lib/matchers.js b/lib/matchers.js
index d7bdcdb46..f780e768c 100644
--- a/lib/matchers.js
+++ b/lib/matchers.js
@@ -79,6 +79,7 @@ module.exports = {
   polymerElement: p.hasTagName('polymer-element'),
   urlAttrs: urlAttrs,
   targetMatcher: targetMatcher,
+  polymerExternalStyle: polymerExternalStyle,
   JS: jsMatcher,
   CSS: styleMatcher,
   CSS_LINK: externalStyle,
diff --git a/lib/vulcan.js b/lib/vulcan.js
index 784089358..44ed8c59b 100644
--- a/lib/vulcan.js
+++ b/lib/vulcan.js
@@ -311,6 +311,8 @@ Vulcan.prototype = {
       var src = dom5.getAttribute(tag, 'href');
       var media = dom5.getAttribute(tag, 'media');
       var uri = url.resolve(href, src);
+      var isPolymerExternalStyle = matchers.polymerExternalStyle(tag);
+
       // let the loader handle the requests
       if (this.isExcludedHref(src)) {
         return Promise.resolve(true);
@@ -324,7 +326,26 @@ Vulcan.prototype = {
           }
           var style = dom5.constructors.element('style');
           dom5.setTextContent(style, '\n' + content + '\n');
-          dom5.replace(tag, style);
+
+          if (isPolymerExternalStyle) {
+            // a polymer expternal style  must be
+            // in a  to be processed
+            var ownerDomModule = dom5.nodeWalkPrior(tag, dom5.predicates.hasTagName('dom-module'));
+            if (ownerDomModule) {
+              var domTemplate = dom5.query(ownerDomModule, dom5.predicates.hasTagName('template'));
+              if (!domTemplate) {
+                // create a