diff --git a/README.md b/README.md
index b3dd334..f1ec8cf 100644
--- a/README.md
+++ b/README.md
@@ -391,6 +391,7 @@
* [TCP](#tcp)
* [REST API](#rest-api)
* [CRUD](#crud)
+ * [OpenAPI](#openapi)
* [Express](#express)
* [GraphQL](#graphql)
* [GNU/Linux](#gnulinux)
@@ -3644,6 +3645,16 @@ Learn about the CRUD operations.
* [ ] [ Youtube - Introduction to CRUD Operations](https://www.youtube.com/watch?v=Lyi8SoVdkhM)
* [ ] [ REST was NEVER about CRUD](https://tyk.io/rest-never-crud/)
+#### OpenAPI
+
+Learn about the OpenAPI specification for describing RESTful APIs
+
+* [ ] [ OpenAPI specification](https://swagger.io/specification/)
+* [ ] [ Tutorial of OpenAPI Specification](https://medium.com/@amirm.lavasani/restful-apis-tutorial-of-openapi-specification-eeada0e3901d)
+* [ ] [ Improving the developer experience with OpenAPI Specification](https://medium.com/adyen/improving-the-developer-experience-with-openapi-specification-f90fbf8077cf)
+* [ ] [ SwaggerHub - Public list of available OpenAPI definitions](https://app.swaggerhub.com)
+* [ ] [ openapi.tools - List of available OpenAPI tools](https://openapi.tools)
+
### Express
Learn about the Node.js web application framework called Express.
diff --git a/assets/databases-and-servers/servers/openapi.svg b/assets/databases-and-servers/servers/openapi.svg
new file mode 100644
index 0000000..850720d
--- /dev/null
+++ b/assets/databases-and-servers/servers/openapi.svg
@@ -0,0 +1,18 @@
+
+
\ No newline at end of file
diff --git a/blueprint.md b/blueprint.md
index 306417b..03567a6 100644
--- a/blueprint.md
+++ b/blueprint.md
@@ -3216,6 +3216,16 @@ Learn about the CRUD operations.
* [ ] [ Youtube - Introduction to CRUD Operations](https://www.youtube.com/watch?v=Lyi8SoVdkhM)
* [ ] [ REST was NEVER about CRUD](https://tyk.io/rest-never-crud/)
+#### OpenAPI
+
+Learn about the OpenAPI specification for describing RESTful APIs
+
+* [ ] [ OpenAPI specification](https://swagger.io/specification/)
+* [ ] [ Tutorial of OpenAPI Specification](https://medium.com/@amirm.lavasani/restful-apis-tutorial-of-openapi-specification-eeada0e3901d)
+* [ ] [ Improving the developer experience with OpenAPI Specification](https://medium.com/adyen/improving-the-developer-experience-with-openapi-specification-f90fbf8077cf)
+* [ ] [ SwaggerHub - Public list of available OpenAPI definitions](https://app.swaggerhub.com)
+* [ ] [ openapi.tools - List of available OpenAPI tools](https://openapi.tools)
+
### Express
Learn about the Node.js web application framework called Express.
diff --git a/src/data/databases.js b/src/data/databases.js
index 26a2a76..b80ab72 100644
--- a/src/data/databases.js
+++ b/src/data/databases.js
@@ -456,6 +456,19 @@ export const databasesCollection = {
]
},
},
+ {
+ name: "OpenAPI",
+ description: {
+ text: "Learn about the OpenAPI specification for describing RESTful APIs",
+ links: [
+ ["OpenAPI specification", "https://swagger.io/specification/"],
+ ["Tutorial of OpenAPI Specification", "https://medium.com/@amirm.lavasani/restful-apis-tutorial-of-openapi-specification-eeada0e3901d"],
+ ["Improving the developer experience with OpenAPI Specification", "https://medium.com/adyen/improving-the-developer-experience-with-openapi-specification-f90fbf8077cf"],
+ ["SwaggerHub - Public list of available OpenAPI definitions", "https://app.swaggerhub.com"],
+ ["openapi.tools - List of available OpenAPI tools", "https://openapi.tools"],
+ ]
+ },
+ },
]
},
{
diff --git a/web_modules/lit-element.js b/web_modules/lit-element.js
index 6fefef3..95a1f2e 100644
--- a/web_modules/lit-element.js
+++ b/web_modules/lit-element.js
@@ -25,7 +25,7 @@ import{i as t,p as e,r as s,t as r,m as i,T as o,a as n,b as a}from"./common/lit
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
-const l=(t,e)=>`${t}--${e}`;let u=!0;void 0===window.ShadyCSS?u=!1:void 0===window.ShadyCSS.prepareTemplateDom&&(console.warn("Incompatible ShadyCSS version detected. Please update to at least @webcomponents/webcomponentsjs@2.0.2 and @webcomponents/shadycss@1.3.1."),u=!1);const y=t=>e=>{const s=l(e.type,t);let n=r.get(s);void 0===n&&(n={stringsArray:new WeakMap,keyString:new Map},r.set(s,n));let a=n.stringsArray.get(e.strings);if(void 0!==a)return a;const p=e.strings.join(i);if(a=n.keyString.get(p),void 0===a){const s=e.getTemplateElement();u&&window.ShadyCSS.prepareTemplateDom(s,t),a=new o(e,s),n.keyString.set(p,a)}return n.stringsArray.set(e.strings,a),a},S=["html","svg"],_=new Set,f=(t,e,s)=>{_.add(t);const i=s?s.element:document.createElement("template"),o=e.querySelectorAll("style"),{length:n}=o;if(0===n)return void window.ShadyCSS.prepareTemplateStyles(i,t);const a=document.createElement("style");for(let t=0;t{S.forEach(e=>{const s=r.get(l(e,t));void 0!==s&&s.keyString.forEach(t=>{const{element:{content:e}}=t,s=new Set;Array.from(e.querySelectorAll("style")).forEach(t=>{s.add(t)}),p(t,s)})})})(t);const h=i.content;s?function(t,e,s=null){const{element:{content:r},parts:i}=t;if(null==s)return void r.appendChild(e);const o=document.createTreeWalker(r,133,null,!1);let n=d(i),a=0,p=-1;for(;o.nextNode();){for(p++,o.currentNode===s&&(a=c(e),s.parentNode.insertBefore(e,s));-1!==n&&i[n].index===p;){if(a>0){for(;-1!==n;)i[n].index+=a,n=d(i,n);return}n=d(i,n)}}}(s,a,h.firstChild):h.insertBefore(a,h.firstChild),window.ShadyCSS.prepareTemplateStyles(i,t);const u=h.querySelector("style");if(window.ShadyCSS.nativeShadow&&null!==u)e.insertBefore(u.cloneNode(!0),e.firstChild);else if(s){h.insertBefore(a,h.firstChild);const t=new Set;t.add(a),p(s,t)}};window.JSCompiler_renameProperty=(t,e)=>t;const m={toAttribute(t,e){switch(e){case Boolean:return t?"":null;case Object:case Array:return null==t?t:JSON.stringify(t)}return t},fromAttribute(t,e){switch(e){case Boolean:return null!==t;case Number:return null===t?null:Number(t);case Object:case Array:return JSON.parse(t)}return t}},g=(t,e)=>e!==t&&(e==e||t==t),w={attribute:!0,type:String,converter:m,reflect:!1,hasChanged:g};class P extends HTMLElement{constructor(){super(),this._updateState=0,this._instanceProperties=void 0,this._updatePromise=new Promise(t=>this._enableUpdatingResolver=t),this._changedProperties=new Map,this._reflectingProperties=void 0,this.initialize()}static get observedAttributes(){this.finalize();const t=[];return this._classProperties.forEach((e,s)=>{const r=this._attributeNameForProperty(s,e);void 0!==r&&(this._attributeToPropertyMap.set(r,s),t.push(r))}),t}static _ensureClassProperties(){if(!this.hasOwnProperty(JSCompiler_renameProperty("_classProperties",this))){this._classProperties=new Map;const t=Object.getPrototypeOf(this)._classProperties;void 0!==t&&t.forEach((t,e)=>this._classProperties.set(e,t))}}static createProperty(t,e=w){if(this._ensureClassProperties(),this._classProperties.set(t,e),e.noAccessor||this.prototype.hasOwnProperty(t))return;const s="symbol"==typeof t?Symbol():`__${t}`,r=this.getPropertyDescriptor(t,s,e);void 0!==r&&Object.defineProperty(this.prototype,t,r)}static getPropertyDescriptor(t,e,s){return{get(){return this[e]},set(s){const r=this[t];this[e]=s,this._requestUpdate(t,r)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this._classProperties&&this._classProperties.get(t)||w}static finalize(){const t=Object.getPrototypeOf(this);if(t.hasOwnProperty("finalized")||t.finalize(),this.finalized=!0,this._ensureClassProperties(),this._attributeToPropertyMap=new Map,this.hasOwnProperty(JSCompiler_renameProperty("properties",this))){const t=this.properties,e=[...Object.getOwnPropertyNames(t),..."function"==typeof Object.getOwnPropertySymbols?Object.getOwnPropertySymbols(t):[]];for(const s of e)this.createProperty(s,t[s])}}static _attributeNameForProperty(t,e){const s=e.attribute;return!1===s?void 0:"string"==typeof s?s:"string"==typeof t?t.toLowerCase():void 0}static _valueHasChanged(t,e,s=g){return s(t,e)}static _propertyValueFromAttribute(t,e){const s=e.type,r=e.converter||m,i="function"==typeof r?r:r.fromAttribute;return i?i(t,s):t}static _propertyValueToAttribute(t,e){if(void 0===e.reflect)return;const s=e.type,r=e.converter;return(r&&r.toAttribute||m.toAttribute)(t,s)}initialize(){this._saveInstanceProperties(),this._requestUpdate()}_saveInstanceProperties(){this.constructor._classProperties.forEach((t,e)=>{if(this.hasOwnProperty(e)){const t=this[e];delete this[e],this._instanceProperties||(this._instanceProperties=new Map),this._instanceProperties.set(e,t)}})}_applyInstanceProperties(){this._instanceProperties.forEach((t,e)=>this[e]=t),this._instanceProperties=void 0}connectedCallback(){this.enableUpdating()}enableUpdating(){void 0!==this._enableUpdatingResolver&&(this._enableUpdatingResolver(),this._enableUpdatingResolver=void 0)}disconnectedCallback(){}attributeChangedCallback(t,e,s){e!==s&&this._attributeToProperty(t,s)}_propertyToAttribute(t,e,s=w){const r=this.constructor,i=r._attributeNameForProperty(t,s);if(void 0!==i){const t=r._propertyValueToAttribute(e,s);if(void 0===t)return;this._updateState=8|this._updateState,null==t?this.removeAttribute(i):this.setAttribute(i,t),this._updateState=-9&this._updateState}}_attributeToProperty(t,e){if(8&this._updateState)return;const s=this.constructor,r=s._attributeToPropertyMap.get(t);if(void 0!==r){const t=s.getPropertyOptions(r);this._updateState=16|this._updateState,this[r]=s._propertyValueFromAttribute(e,t),this._updateState=-17&this._updateState}}_requestUpdate(t,e){let s=!0;if(void 0!==t){const r=this.constructor,i=r.getPropertyOptions(t);r._valueHasChanged(this[t],e,i.hasChanged)?(this._changedProperties.has(t)||this._changedProperties.set(t,e),!0!==i.reflect||16&this._updateState||(void 0===this._reflectingProperties&&(this._reflectingProperties=new Map),this._reflectingProperties.set(t,i))):s=!1}!this._hasRequestedUpdate&&s&&(this._updatePromise=this._enqueueUpdate())}requestUpdate(t,e){return this._requestUpdate(t,e),this.updateComplete}async _enqueueUpdate(){this._updateState=4|this._updateState;try{await this._updatePromise}catch(t){}const t=this.performUpdate();return null!=t&&await t,!this._hasRequestedUpdate}get _hasRequestedUpdate(){return 4&this._updateState}get hasUpdated(){return 1&this._updateState}performUpdate(){this._instanceProperties&&this._applyInstanceProperties();let t=!1;const e=this._changedProperties;try{t=this.shouldUpdate(e),t?this.update(e):this._markUpdated()}catch(e){throw t=!1,this._markUpdated(),e}t&&(1&this._updateState||(this._updateState=1|this._updateState,this.firstUpdated(e)),this.updated(e))}_markUpdated(){this._changedProperties=new Map,this._updateState=-5&this._updateState}get updateComplete(){return this._getUpdateComplete()}_getUpdateComplete(){return this._updatePromise}shouldUpdate(t){return!0}update(t){void 0!==this._reflectingProperties&&this._reflectingProperties.size>0&&(this._reflectingProperties.forEach((t,e)=>this._propertyToAttribute(e,this[e],t)),this._reflectingProperties=void 0),this._markUpdated()}updated(t){}firstUpdated(t){}}P.finalized=!0;
+const l=(t,e)=>`${t}--${e}`;let u=!0;void 0===window.ShadyCSS?u=!1:void 0===window.ShadyCSS.prepareTemplateDom&&(console.warn("Incompatible ShadyCSS version detected. Please update to at least @webcomponents/webcomponentsjs@2.0.2 and @webcomponents/shadycss@1.3.1."),u=!1);const y=t=>e=>{const s=l(e.type,t);let n=r.get(s);void 0===n&&(n={stringsArray:new WeakMap,keyString:new Map},r.set(s,n));let a=n.stringsArray.get(e.strings);if(void 0!==a)return a;const p=e.strings.join(i);if(a=n.keyString.get(p),void 0===a){const s=e.getTemplateElement();u&&window.ShadyCSS.prepareTemplateDom(s,t),a=new o(e,s),n.keyString.set(p,a)}return n.stringsArray.set(e.strings,a),a},S=["html","svg"],_=new Set,f=(t,e,s)=>{_.add(t);const i=s?s.element:document.createElement("template"),o=e.querySelectorAll("style"),{length:n}=o;if(0===n)return void window.ShadyCSS.prepareTemplateStyles(i,t);const a=document.createElement("style");for(let t=0;t{S.forEach(e=>{const s=r.get(l(e,t));void 0!==s&&s.keyString.forEach(t=>{const{element:{content:e}}=t,s=new Set;Array.from(e.querySelectorAll("style")).forEach(t=>{s.add(t)}),p(t,s)})})})(t);const h=i.content;s?function(t,e,s=null){const{element:{content:r},parts:i}=t;if(null==s)return void r.appendChild(e);const o=document.createTreeWalker(r,133,null,!1);let n=d(i),a=0,p=-1;for(;o.nextNode();){for(p++,o.currentNode===s&&(a=c(e),s.parentNode.insertBefore(e,s));-1!==n&&i[n].index===p;){if(a>0){for(;-1!==n;)i[n].index+=a,n=d(i,n);return}n=d(i,n)}}}(s,a,h.firstChild):h.insertBefore(a,h.firstChild),window.ShadyCSS.prepareTemplateStyles(i,t);const u=h.querySelector("style");if(window.ShadyCSS.nativeShadow&&null!==u)e.insertBefore(u.cloneNode(!0),e.firstChild);else if(s){h.insertBefore(a,h.firstChild);const t=new Set;t.add(a),p(s,t)}};window.JSCompiler_renameProperty=(t,e)=>t;const m={toAttribute(t,e){switch(e){case Boolean:return t?"":null;case Object:case Array:return null==t?t:JSON.stringify(t)}return t},fromAttribute(t,e){switch(e){case Boolean:return null!==t;case Number:return null===t?null:Number(t);case Object:case Array:return JSON.parse(t)}return t}},g=(t,e)=>e!==t&&(e==e||t==t),w={attribute:!0,type:String,converter:m,reflect:!1,hasChanged:g};class P extends HTMLElement{constructor(){super(),this._updateState=0,this._instanceProperties=void 0,this._updatePromise=new Promise(t=>this._enableUpdatingResolver=t),this._changedProperties=new Map,this._reflectingProperties=void 0,this.initialize()}static get observedAttributes(){this.finalize();const t=[];return this._classProperties.forEach((e,s)=>{const r=this._attributeNameForProperty(s,e);void 0!==r&&(this._attributeToPropertyMap.set(r,s),t.push(r))}),t}static _ensureClassProperties(){if(!this.hasOwnProperty(JSCompiler_renameProperty("_classProperties",this))){this._classProperties=new Map;const t=Object.getPrototypeOf(this)._classProperties;void 0!==t&&t.forEach((t,e)=>this._classProperties.set(e,t))}}static createProperty(t,e=w){if(this._ensureClassProperties(),this._classProperties.set(t,e),e.noAccessor||this.prototype.hasOwnProperty(t))return;const s="symbol"==typeof t?Symbol():"__"+t,r=this.getPropertyDescriptor(t,s,e);void 0!==r&&Object.defineProperty(this.prototype,t,r)}static getPropertyDescriptor(t,e,s){return{get(){return this[e]},set(s){const r=this[t];this[e]=s,this._requestUpdate(t,r)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this._classProperties&&this._classProperties.get(t)||w}static finalize(){const t=Object.getPrototypeOf(this);if(t.hasOwnProperty("finalized")||t.finalize(),this.finalized=!0,this._ensureClassProperties(),this._attributeToPropertyMap=new Map,this.hasOwnProperty(JSCompiler_renameProperty("properties",this))){const t=this.properties,e=[...Object.getOwnPropertyNames(t),..."function"==typeof Object.getOwnPropertySymbols?Object.getOwnPropertySymbols(t):[]];for(const s of e)this.createProperty(s,t[s])}}static _attributeNameForProperty(t,e){const s=e.attribute;return!1===s?void 0:"string"==typeof s?s:"string"==typeof t?t.toLowerCase():void 0}static _valueHasChanged(t,e,s=g){return s(t,e)}static _propertyValueFromAttribute(t,e){const s=e.type,r=e.converter||m,i="function"==typeof r?r:r.fromAttribute;return i?i(t,s):t}static _propertyValueToAttribute(t,e){if(void 0===e.reflect)return;const s=e.type,r=e.converter;return(r&&r.toAttribute||m.toAttribute)(t,s)}initialize(){this._saveInstanceProperties(),this._requestUpdate()}_saveInstanceProperties(){this.constructor._classProperties.forEach((t,e)=>{if(this.hasOwnProperty(e)){const t=this[e];delete this[e],this._instanceProperties||(this._instanceProperties=new Map),this._instanceProperties.set(e,t)}})}_applyInstanceProperties(){this._instanceProperties.forEach((t,e)=>this[e]=t),this._instanceProperties=void 0}connectedCallback(){this.enableUpdating()}enableUpdating(){void 0!==this._enableUpdatingResolver&&(this._enableUpdatingResolver(),this._enableUpdatingResolver=void 0)}disconnectedCallback(){}attributeChangedCallback(t,e,s){e!==s&&this._attributeToProperty(t,s)}_propertyToAttribute(t,e,s=w){const r=this.constructor,i=r._attributeNameForProperty(t,s);if(void 0!==i){const t=r._propertyValueToAttribute(e,s);if(void 0===t)return;this._updateState=8|this._updateState,null==t?this.removeAttribute(i):this.setAttribute(i,t),this._updateState=-9&this._updateState}}_attributeToProperty(t,e){if(8&this._updateState)return;const s=this.constructor,r=s._attributeToPropertyMap.get(t);if(void 0!==r){const t=s.getPropertyOptions(r);this._updateState=16|this._updateState,this[r]=s._propertyValueFromAttribute(e,t),this._updateState=-17&this._updateState}}_requestUpdate(t,e){let s=!0;if(void 0!==t){const r=this.constructor,i=r.getPropertyOptions(t);r._valueHasChanged(this[t],e,i.hasChanged)?(this._changedProperties.has(t)||this._changedProperties.set(t,e),!0!==i.reflect||16&this._updateState||(void 0===this._reflectingProperties&&(this._reflectingProperties=new Map),this._reflectingProperties.set(t,i))):s=!1}!this._hasRequestedUpdate&&s&&(this._updatePromise=this._enqueueUpdate())}requestUpdate(t,e){return this._requestUpdate(t,e),this.updateComplete}async _enqueueUpdate(){this._updateState=4|this._updateState;try{await this._updatePromise}catch(t){}const t=this.performUpdate();return null!=t&&await t,!this._hasRequestedUpdate}get _hasRequestedUpdate(){return 4&this._updateState}get hasUpdated(){return 1&this._updateState}performUpdate(){this._instanceProperties&&this._applyInstanceProperties();let t=!1;const e=this._changedProperties;try{t=this.shouldUpdate(e),t?this.update(e):this._markUpdated()}catch(e){throw t=!1,this._markUpdated(),e}t&&(1&this._updateState||(this._updateState=1|this._updateState,this.firstUpdated(e)),this.updated(e))}_markUpdated(){this._changedProperties=new Map,this._updateState=-5&this._updateState}get updateComplete(){return this._getUpdateComplete()}_getUpdateComplete(){return this._updatePromise}shouldUpdate(t){return!0}update(t){void 0!==this._reflectingProperties&&this._reflectingProperties.size>0&&(this._reflectingProperties.forEach((t,e)=>this._propertyToAttribute(e,this[e],t)),this._reflectingProperties=void 0),this._markUpdated()}updated(t){}firstUpdated(t){}}P.finalized=!0;
/**
@license
Copyright (c) 2019 The Polymer Project Authors. All rights reserved.
diff --git a/web_modules/lit-element.js.map b/web_modules/lit-element.js.map
index ed75c7b..e3871e0 100644
--- a/web_modules/lit-element.js.map
+++ b/web_modules/lit-element.js.map
@@ -1 +1 @@
-{"version":3,"file":"lit-element.js","sources":["../node_modules/lit-html/lib/modify-template.js","../node_modules/lit-html/lib/shady-render.js","../node_modules/lit-element/lib/updating-element.js","../node_modules/lit-element/lib/css-tag.js","../node_modules/lit-element/lit-element.js"],"sourcesContent":["/**\n * @license\n * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at\n * http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at\n * http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at\n * http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at\n * http://polymer.github.io/PATENTS.txt\n */\n/**\n * @module shady-render\n */\nimport { isTemplatePartActive } from './template.js';\nconst walkerNodeFilter = 133 /* NodeFilter.SHOW_{ELEMENT|COMMENT|TEXT} */;\n/**\n * Removes the list of nodes from a Template safely. In addition to removing\n * nodes from the Template, the Template part indices are updated to match\n * the mutated Template DOM.\n *\n * As the template is walked the removal state is tracked and\n * part indices are adjusted as needed.\n *\n * div\n * div#1 (remove) <-- start removing (removing node is div#1)\n * div\n * div#2 (remove) <-- continue removing (removing node is still div#1)\n * div\n * div <-- stop removing since previous sibling is the removing node (div#1,\n * removed 4 nodes)\n */\nexport function removeNodesFromTemplate(template, nodesToRemove) {\n const { element: { content }, parts } = template;\n const walker = document.createTreeWalker(content, walkerNodeFilter, null, false);\n let partIndex = nextActiveIndexInTemplateParts(parts);\n let part = parts[partIndex];\n let nodeIndex = -1;\n let removeCount = 0;\n const nodesToRemoveInTemplate = [];\n let currentRemovingNode = null;\n while (walker.nextNode()) {\n nodeIndex++;\n const node = walker.currentNode;\n // End removal if stepped past the removing node\n if (node.previousSibling === currentRemovingNode) {\n currentRemovingNode = null;\n }\n // A node to remove was found in the template\n if (nodesToRemove.has(node)) {\n nodesToRemoveInTemplate.push(node);\n // Track node we're removing\n if (currentRemovingNode === null) {\n currentRemovingNode = node;\n }\n }\n // When removing, increment count by which to adjust subsequent part indices\n if (currentRemovingNode !== null) {\n removeCount++;\n }\n while (part !== undefined && part.index === nodeIndex) {\n // If part is in a removed node deactivate it by setting index to -1 or\n // adjust the index as needed.\n part.index = currentRemovingNode !== null ? -1 : part.index - removeCount;\n // go to the next active part.\n partIndex = nextActiveIndexInTemplateParts(parts, partIndex);\n part = parts[partIndex];\n }\n }\n nodesToRemoveInTemplate.forEach((n) => n.parentNode.removeChild(n));\n}\nconst countNodes = (node) => {\n let count = (node.nodeType === 11 /* Node.DOCUMENT_FRAGMENT_NODE */) ? 0 : 1;\n const walker = document.createTreeWalker(node, walkerNodeFilter, null, false);\n while (walker.nextNode()) {\n count++;\n }\n return count;\n};\nconst nextActiveIndexInTemplateParts = (parts, startIndex = -1) => {\n for (let i = startIndex + 1; i < parts.length; i++) {\n const part = parts[i];\n if (isTemplatePartActive(part)) {\n return i;\n }\n }\n return -1;\n};\n/**\n * Inserts the given node into the Template, optionally before the given\n * refNode. In addition to inserting the node into the Template, the Template\n * part indices are updated to match the mutated Template DOM.\n */\nexport function insertNodeIntoTemplate(template, node, refNode = null) {\n const { element: { content }, parts } = template;\n // If there's no refNode, then put node at end of template.\n // No part indices need to be shifted in this case.\n if (refNode === null || refNode === undefined) {\n content.appendChild(node);\n return;\n }\n const walker = document.createTreeWalker(content, walkerNodeFilter, null, false);\n let partIndex = nextActiveIndexInTemplateParts(parts);\n let insertCount = 0;\n let walkerIndex = -1;\n while (walker.nextNode()) {\n walkerIndex++;\n const walkerNode = walker.currentNode;\n if (walkerNode === refNode) {\n insertCount = countNodes(node);\n refNode.parentNode.insertBefore(node, refNode);\n }\n while (partIndex !== -1 && parts[partIndex].index === walkerIndex) {\n // If we've inserted the node, simply adjust all subsequent parts\n if (insertCount > 0) {\n while (partIndex !== -1) {\n parts[partIndex].index += insertCount;\n partIndex = nextActiveIndexInTemplateParts(parts, partIndex);\n }\n return;\n }\n partIndex = nextActiveIndexInTemplateParts(parts, partIndex);\n }\n }\n}\n//# sourceMappingURL=modify-template.js.map","/**\n * @license\n * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at\n * http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at\n * http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at\n * http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at\n * http://polymer.github.io/PATENTS.txt\n */\n/**\n * Module to add shady DOM/shady CSS polyfill support to lit-html template\n * rendering. See the [[render]] method for details.\n *\n * @module shady-render\n * @preferred\n */\n/**\n * Do not remove this comment; it keeps typedoc from misplacing the module\n * docs.\n */\nimport { removeNodes } from './dom.js';\nimport { insertNodeIntoTemplate, removeNodesFromTemplate } from './modify-template.js';\nimport { parts, render as litRender } from './render.js';\nimport { templateCaches } from './template-factory.js';\nimport { TemplateInstance } from './template-instance.js';\nimport { marker, Template } from './template.js';\nexport { html, svg, TemplateResult } from '../lit-html.js';\n// Get a key to lookup in `templateCaches`.\nconst getTemplateCacheKey = (type, scopeName) => `${type}--${scopeName}`;\nlet compatibleShadyCSSVersion = true;\nif (typeof window.ShadyCSS === 'undefined') {\n compatibleShadyCSSVersion = false;\n}\nelse if (typeof window.ShadyCSS.prepareTemplateDom === 'undefined') {\n console.warn(`Incompatible ShadyCSS version detected. ` +\n `Please update to at least @webcomponents/webcomponentsjs@2.0.2 and ` +\n `@webcomponents/shadycss@1.3.1.`);\n compatibleShadyCSSVersion = false;\n}\n/**\n * Template factory which scopes template DOM using ShadyCSS.\n * @param scopeName {string}\n */\nconst shadyTemplateFactory = (scopeName) => (result) => {\n const cacheKey = getTemplateCacheKey(result.type, scopeName);\n let templateCache = templateCaches.get(cacheKey);\n if (templateCache === undefined) {\n templateCache = {\n stringsArray: new WeakMap(),\n keyString: new Map()\n };\n templateCaches.set(cacheKey, templateCache);\n }\n let template = templateCache.stringsArray.get(result.strings);\n if (template !== undefined) {\n return template;\n }\n const key = result.strings.join(marker);\n template = templateCache.keyString.get(key);\n if (template === undefined) {\n const element = result.getTemplateElement();\n if (compatibleShadyCSSVersion) {\n window.ShadyCSS.prepareTemplateDom(element, scopeName);\n }\n template = new Template(result, element);\n templateCache.keyString.set(key, template);\n }\n templateCache.stringsArray.set(result.strings, template);\n return template;\n};\nconst TEMPLATE_TYPES = ['html', 'svg'];\n/**\n * Removes all style elements from Templates for the given scopeName.\n */\nconst removeStylesFromLitTemplates = (scopeName) => {\n TEMPLATE_TYPES.forEach((type) => {\n const templates = templateCaches.get(getTemplateCacheKey(type, scopeName));\n if (templates !== undefined) {\n templates.keyString.forEach((template) => {\n const { element: { content } } = template;\n // IE 11 doesn't support the iterable param Set constructor\n const styles = new Set();\n Array.from(content.querySelectorAll('style')).forEach((s) => {\n styles.add(s);\n });\n removeNodesFromTemplate(template, styles);\n });\n }\n });\n};\nconst shadyRenderSet = new Set();\n/**\n * For the given scope name, ensures that ShadyCSS style scoping is performed.\n * This is done just once per scope name so the fragment and template cannot\n * be modified.\n * (1) extracts styles from the rendered fragment and hands them to ShadyCSS\n * to be scoped and appended to the document\n * (2) removes style elements from all lit-html Templates for this scope name.\n *\n * Note,