From 3c6e07117aa427c50acd0b5bbf26fc5324c51a34 Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Sun, 30 Sep 2018 10:32:44 +0800 Subject: [PATCH 001/524] init the repo --- .gitignore | 4 ++++ .prettierrc | 4 ++++ README.md | 3 +++ package.json | 33 +++++++++++++++++++++++++++++++++ src/index.ts | 0 tsconfig.json | 12 ++++++++++++ tslint.json | 14 ++++++++++++++ 7 files changed, 70 insertions(+) create mode 100644 .gitignore create mode 100644 .prettierrc create mode 100644 README.md create mode 100644 package.json create mode 100644 src/index.ts create mode 100644 tsconfig.json create mode 100644 tslint.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..6ccc9d846d --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.vscode +node_modules +package-lock.json +build diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000000..1502887d63 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,4 @@ +{ + "singleQuote": true, + "trailingComma": "es5" +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000000..98c66522e2 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# rrweb-snapshot + +Not ready yet diff --git a/package.json b/package.json new file mode 100644 index 0000000000..c8c0d7d16a --- /dev/null +++ b/package.json @@ -0,0 +1,33 @@ +{ + "name": "rrweb-snapshot", + "version": "0.1.0", + "description": "rrweb's component to take a snapshot of DOM, aka DOM serializer", + "main": "index.js", + "scripts": { + "test": "mocha -r ts-node/register src/**/*.test.ts" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/rrweb-io/rrweb-snapshot.git" + }, + "keywords": [ + "rrweb", + "snapshot", + "DOM" + ], + "author": "yanzhen@smartx.com", + "license": "MIT", + "bugs": { + "url": "https://github.com/rrweb-io/rrweb-snapshot/issues" + }, + "homepage": "https://github.com/rrweb-io/rrweb-snapshot#readme", + "devDependencies": { + "@types/chai": "^4.1.4", + "@types/mocha": "^5.2.5", + "chai": "^4.1.2", + "mocha": "^5.2.0", + "ts-node": "^7.0.1", + "tslint": "^4.5.1", + "typescript": "^3.0.3" + } +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000000..1aec14ff9d --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "module": "commonjs", + "noImplicitAny": true, + "removeComments": true, + "preserveConstEnums": true, + "sourceMap": true, + "rootDir": "src", + "outDir": "build" + }, + "compileOnSave": true +} \ No newline at end of file diff --git a/tslint.json b/tslint.json new file mode 100644 index 0000000000..c82ebf60b8 --- /dev/null +++ b/tslint.json @@ -0,0 +1,14 @@ +{ + "defaultSeverity": "error", + "extends": ["tslint:recommended"], + "jsRules": {}, + "rules": { + "no-any": true, + "quotemark": [true, "single"], + "ordered-imports": false, + "object-literal-sort-keys": false, + "no-unused-variable": true, + "object-literal-key-quotes": false + }, + "rulesDirectory": [] +} \ No newline at end of file From 819cf3062ee14fa103a61b803f7702bb200611d5 Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Sun, 30 Sep 2018 13:44:13 +0800 Subject: [PATCH 002/524] basic snapshot implementation --- src/index.ts | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++ tsconfig.json | 5 +- tslint.json | 3 +- 3 files changed, 143 insertions(+), 3 deletions(-) diff --git a/src/index.ts b/src/index.ts index e69de29bb2..4a003d2b99 100644 --- a/src/index.ts +++ b/src/index.ts @@ -0,0 +1,138 @@ +let _id = 1; + +function genId(): number { + return _id++; +} + +enum NodeType { + Document, + DocumentType, + Element, + Text, + CDATA, + Comment, +} + +type serializedNode = + | documentNode + | documentTypeNode + | elementNode + | textNode + | cdataNode + | commentNode; + +type documentNode = { + type: NodeType.Document; + childNodes: serializedNode[]; +}; + +type documentTypeNode = { + type: NodeType.DocumentType; + name: string; + publicId: string; + systemId: string; +}; + +type attributes = { + [key: string]: string; +}; +type elementNode = { + type: NodeType.Element; + tagName: string; + attributes: attributes; + childNodes: serializedNode[]; +}; + +type textNode = { + type: NodeType.Text; + textContent: string; +}; + +type cdataNode = { + type: NodeType.CDATA; + textContent: ''; +}; + +type commentNode = { + type: NodeType.Comment; + textContent: string; +}; + +function serializeNode(n: Node): serializedNode | false { + switch (n.nodeType) { + case n.DOCUMENT_NODE: + return { + type: NodeType.Document, + childNodes: [], + }; + case n.DOCUMENT_TYPE_NODE: + return { + type: NodeType.DocumentType, + name: (n as DocumentType).name, + publicId: (n as DocumentType).publicId, + systemId: (n as DocumentType).systemId, + }; + case n.ELEMENT_NODE: + const tagName = (n as HTMLElement).tagName.toLowerCase(); + const attributes: attributes = {}; + for (const { name, value } of Array.from((n as HTMLElement).attributes)) { + attributes[name] = value; + } + return { + type: NodeType.Element, + tagName, + attributes, + childNodes: [], + }; + case n.TEXT_NODE: + // The parent node may not be a html element which has a tagName attribute. + // So just let it be undefined which is ok in this use case. + const parentTagName = + n.parentNode && (n.parentNode as HTMLElement).tagName; + let textContent = (n as Text).textContent; + if (parentTagName === 'SCRIPT') { + textContent = ''; + } + return { + type: NodeType.Text, + textContent, + }; + case n.CDATA_SECTION_NODE: + return { + type: NodeType.CDATA, + textContent: '', + }; + case n.COMMENT_NODE: + return { + type: NodeType.Comment, + textContent: (n as Comment).textContent, + }; + default: + return false; + } +} + +type serializedNodeWithId = serializedNode & { id: number }; + +function snapshot(n: Node): serializedNodeWithId | null { + const _serializedNode = serializeNode(n); + if (!_serializedNode) { + // TODO: dev only + console.warn(n, 'not serialized'); + return null; + } + const serializedNode: serializedNodeWithId = Object.assign(_serializedNode, { + id: genId(), + }); + if ( + serializedNode.type === NodeType.Document || + serializedNode.type === NodeType.Element + ) { + for (const childN of Array.from(n.childNodes)) { + serializedNode.childNodes.push(snapshot(childN)); + } + } + return serializedNode; +} + +export default snapshot; diff --git a/tsconfig.json b/tsconfig.json index 1aec14ff9d..ce1b7e3ca7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,7 +6,8 @@ "preserveConstEnums": true, "sourceMap": true, "rootDir": "src", - "outDir": "build" + "outDir": "build", + "lib": ["es6", "dom"] }, "compileOnSave": true -} \ No newline at end of file +} diff --git a/tslint.json b/tslint.json index c82ebf60b8..3a0c080195 100644 --- a/tslint.json +++ b/tslint.json @@ -8,7 +8,8 @@ "ordered-imports": false, "object-literal-sort-keys": false, "no-unused-variable": true, - "object-literal-key-quotes": false + "object-literal-key-quotes": false, + "variable-name": [true, "ban-keywords", "check-format", "allow-leading-underscore"] }, "rulesDirectory": [] } \ No newline at end of file From 3edd364c3b40f5fd9e2b339eaea522c9493bf2f8 Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Sun, 30 Sep 2018 15:26:00 +0800 Subject: [PATCH 003/524] basic rebuild implementation --- src/index.ts | 140 ++---------------------------------------------- src/rebuild.ts | 46 ++++++++++++++++ src/snapshot.ts | 89 ++++++++++++++++++++++++++++++ src/types.ts | 55 +++++++++++++++++++ 4 files changed, 193 insertions(+), 137 deletions(-) create mode 100644 src/rebuild.ts create mode 100644 src/snapshot.ts create mode 100644 src/types.ts diff --git a/src/index.ts b/src/index.ts index 4a003d2b99..758f2df991 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,138 +1,4 @@ -let _id = 1; +import snapshot from './snapshot'; +import rebuild from './rebuild'; -function genId(): number { - return _id++; -} - -enum NodeType { - Document, - DocumentType, - Element, - Text, - CDATA, - Comment, -} - -type serializedNode = - | documentNode - | documentTypeNode - | elementNode - | textNode - | cdataNode - | commentNode; - -type documentNode = { - type: NodeType.Document; - childNodes: serializedNode[]; -}; - -type documentTypeNode = { - type: NodeType.DocumentType; - name: string; - publicId: string; - systemId: string; -}; - -type attributes = { - [key: string]: string; -}; -type elementNode = { - type: NodeType.Element; - tagName: string; - attributes: attributes; - childNodes: serializedNode[]; -}; - -type textNode = { - type: NodeType.Text; - textContent: string; -}; - -type cdataNode = { - type: NodeType.CDATA; - textContent: ''; -}; - -type commentNode = { - type: NodeType.Comment; - textContent: string; -}; - -function serializeNode(n: Node): serializedNode | false { - switch (n.nodeType) { - case n.DOCUMENT_NODE: - return { - type: NodeType.Document, - childNodes: [], - }; - case n.DOCUMENT_TYPE_NODE: - return { - type: NodeType.DocumentType, - name: (n as DocumentType).name, - publicId: (n as DocumentType).publicId, - systemId: (n as DocumentType).systemId, - }; - case n.ELEMENT_NODE: - const tagName = (n as HTMLElement).tagName.toLowerCase(); - const attributes: attributes = {}; - for (const { name, value } of Array.from((n as HTMLElement).attributes)) { - attributes[name] = value; - } - return { - type: NodeType.Element, - tagName, - attributes, - childNodes: [], - }; - case n.TEXT_NODE: - // The parent node may not be a html element which has a tagName attribute. - // So just let it be undefined which is ok in this use case. - const parentTagName = - n.parentNode && (n.parentNode as HTMLElement).tagName; - let textContent = (n as Text).textContent; - if (parentTagName === 'SCRIPT') { - textContent = ''; - } - return { - type: NodeType.Text, - textContent, - }; - case n.CDATA_SECTION_NODE: - return { - type: NodeType.CDATA, - textContent: '', - }; - case n.COMMENT_NODE: - return { - type: NodeType.Comment, - textContent: (n as Comment).textContent, - }; - default: - return false; - } -} - -type serializedNodeWithId = serializedNode & { id: number }; - -function snapshot(n: Node): serializedNodeWithId | null { - const _serializedNode = serializeNode(n); - if (!_serializedNode) { - // TODO: dev only - console.warn(n, 'not serialized'); - return null; - } - const serializedNode: serializedNodeWithId = Object.assign(_serializedNode, { - id: genId(), - }); - if ( - serializedNode.type === NodeType.Document || - serializedNode.type === NodeType.Element - ) { - for (const childN of Array.from(n.childNodes)) { - serializedNode.childNodes.push(snapshot(childN)); - } - } - return serializedNode; -} - -export default snapshot; +export { snapshot, rebuild }; diff --git a/src/rebuild.ts b/src/rebuild.ts new file mode 100644 index 0000000000..1d581e4527 --- /dev/null +++ b/src/rebuild.ts @@ -0,0 +1,46 @@ +import { serializedNodeWithId, NodeType } from './types'; + +function buildNode(n: serializedNodeWithId): Node | null { + switch (n.type) { + case NodeType.Document: + return document.implementation.createDocument(null, '', null); + case NodeType.DocumentType: + return document.implementation.createDocumentType( + n.name, + n.publicId, + n.systemId, + ); + case NodeType.Element: + const node = document.createElement(n.tagName); + for (const name in n.attributes) { + if (n.attributes.hasOwnProperty(name)) { + node.setAttribute(name, n.attributes[name]); + } + } + return node; + case NodeType.Text: + return document.createTextNode(n.textContent); + case NodeType.CDATA: + return document.createCDATASection(n.textContent); + case NodeType.Comment: + return document.createComment(n.textContent); + default: + return null; + } +} + +function rebuild(n: serializedNodeWithId): Node | null { + const root = buildNode(n); + if (!root) { + return null; + } + if (n.type === NodeType.Document || n.type === NodeType.Element) { + for (const childN of n.childNodes) { + const childNode = rebuild(childN); + root.appendChild(childNode); + } + } + return root; +} + +export default rebuild; diff --git a/src/snapshot.ts b/src/snapshot.ts new file mode 100644 index 0000000000..ce805da52e --- /dev/null +++ b/src/snapshot.ts @@ -0,0 +1,89 @@ +import { + serializedNode, + serializedNodeWithId, + NodeType, + attributes, +} from './types'; + +let _id = 1; + +function genId(): number { + return _id++; +} + +function serializeNode(n: Node): serializedNode | false { + switch (n.nodeType) { + case n.DOCUMENT_NODE: + return { + type: NodeType.Document, + childNodes: [], + }; + case n.DOCUMENT_TYPE_NODE: + return { + type: NodeType.DocumentType, + name: (n as DocumentType).name, + publicId: (n as DocumentType).publicId, + systemId: (n as DocumentType).systemId, + }; + case n.ELEMENT_NODE: + const tagName = (n as HTMLElement).tagName.toLowerCase(); + const attributes: attributes = {}; + for (const { name, value } of Array.from((n as HTMLElement).attributes)) { + attributes[name] = value; + } + return { + type: NodeType.Element, + tagName, + attributes, + childNodes: [], + }; + case n.TEXT_NODE: + // The parent node may not be a html element which has a tagName attribute. + // So just let it be undefined which is ok in this use case. + const parentTagName = + n.parentNode && (n.parentNode as HTMLElement).tagName; + let textContent = (n as Text).textContent; + if (parentTagName === 'SCRIPT') { + textContent = ''; + } + return { + type: NodeType.Text, + textContent, + }; + case n.CDATA_SECTION_NODE: + return { + type: NodeType.CDATA, + textContent: '', + }; + case n.COMMENT_NODE: + return { + type: NodeType.Comment, + textContent: (n as Comment).textContent, + }; + default: + return false; + } +} + +function snapshot(n: Node): serializedNodeWithId | null { + const _serializedNode = serializeNode(n); + if (!_serializedNode) { + // TODO: dev only + console.warn(n, 'not serialized'); + return null; + } + const serializedNode: serializedNodeWithId = Object.assign(_serializedNode, { + id: genId(), + }); + if ( + serializedNode.type === NodeType.Document || + serializedNode.type === NodeType.Element + ) { + for (const childN of Array.from(n.childNodes)) { + serializedNode.childNodes.push(snapshot(childN)); + } + } + return serializedNode; +} + +export default snapshot; diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000000..25fc9962d6 --- /dev/null +++ b/src/types.ts @@ -0,0 +1,55 @@ +export enum NodeType { + Document, + DocumentType, + Element, + Text, + CDATA, + Comment, +} + +export type documentNode = { + type: NodeType.Document; + childNodes: serializedNodeWithId[]; +}; + +export type documentTypeNode = { + type: NodeType.DocumentType; + name: string; + publicId: string; + systemId: string; +}; + +export type attributes = { + [key: string]: string; +}; +export type elementNode = { + type: NodeType.Element; + tagName: string; + attributes: attributes; + childNodes: serializedNodeWithId[]; +}; + +export type textNode = { + type: NodeType.Text; + textContent: string; +}; + +export type cdataNode = { + type: NodeType.CDATA; + textContent: ''; +}; + +export type commentNode = { + type: NodeType.Comment; + textContent: string; +}; + +export type serializedNode = + | documentNode + | documentTypeNode + | elementNode + | textNode + | cdataNode + | commentNode; + +export type serializedNodeWithId = serializedNode & { id: number }; From 7d1cf132661d0c758af38479c660d111b3d7eea8 Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Sun, 30 Sep 2018 16:20:53 +0800 Subject: [PATCH 004/524] setup tests --- .prettierrc | 4 +-- index.d.ts | 4 +++ package.json | 6 +++- src/rebuild.ts | 6 +++- test/html/about-mozilla.html | 57 +++++++++++++++++++++++++++++ test/html/basic.html | 15 ++++++++ test/index.ts | 70 ++++++++++++++++++++++++++++++++++++ tsconfig.json | 4 ++- tslint.json | 10 ++++-- 9 files changed, 169 insertions(+), 7 deletions(-) create mode 100644 index.d.ts create mode 100644 test/html/about-mozilla.html create mode 100644 test/html/basic.html create mode 100644 test/index.ts diff --git a/.prettierrc b/.prettierrc index 1502887d63..a20502b7f0 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,4 +1,4 @@ { "singleQuote": true, - "trailingComma": "es5" -} \ No newline at end of file + "trailingComma": "all" +} diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 0000000000..f7f2dbfa0c --- /dev/null +++ b/index.d.ts @@ -0,0 +1,4 @@ +declare module 'mocha-jsdom' { + function mochaDom(options: any): void; + export = mochaDom; +} diff --git a/package.json b/package.json index c8c0d7d16a..2c62a4c911 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "rrweb's component to take a snapshot of DOM, aka DOM serializer", "main": "index.js", "scripts": { - "test": "mocha -r ts-node/register src/**/*.test.ts" + "test": "TS_NODE_FILES=true mocha -r ts-node/register test/**/*.ts" }, "repository": { "type": "git", @@ -23,9 +23,13 @@ "homepage": "https://github.com/rrweb-io/rrweb-snapshot#readme", "devDependencies": { "@types/chai": "^4.1.4", + "@types/jsdom": "^11.12.0", "@types/mocha": "^5.2.5", + "@types/node": "^10.11.3", "chai": "^4.1.2", + "jsdom": "^12.1.0", "mocha": "^5.2.0", + "mocha-jsdom": "^2.0.0", "ts-node": "^7.0.1", "tslint": "^4.5.1", "typescript": "^3.0.3" diff --git a/src/rebuild.ts b/src/rebuild.ts index 1d581e4527..3dee602629 100644 --- a/src/rebuild.ts +++ b/src/rebuild.ts @@ -14,7 +14,11 @@ function buildNode(n: serializedNodeWithId): Node | null { const node = document.createElement(n.tagName); for (const name in n.attributes) { if (n.attributes.hasOwnProperty(name)) { - node.setAttribute(name, n.attributes[name]); + try { + node.setAttribute(name, n.attributes[name]); + } catch (error) { + // skip invalid attribute + } } } return node; diff --git a/test/html/about-mozilla.html b/test/html/about-mozilla.html new file mode 100644 index 0000000000..f353c48233 --- /dev/null +++ b/test/html/about-mozilla.html @@ -0,0 +1,57 @@ + + + + + The Book of Mozilla, 11:9 + + + + + +

+ Mammon slept. And the beast reborn spread over the earth and its numbers + grew legion. And they proclaimed the times and sacrificed crops unto the + fire, with the cunning of foxes. And they built a new world in their own + image as promised by the + sacred words, and spoke + of the beast with their children. Mammon awoke, and lo! it was + naught but a follower. +

+ +

+ from The Book of Mozilla, 11:9
(10th Edition) +

+ + + + \ No newline at end of file diff --git a/test/html/basic.html b/test/html/basic.html new file mode 100644 index 0000000000..95fac2bede --- /dev/null +++ b/test/html/basic.html @@ -0,0 +1,15 @@ + + + + + + + + Document + + + + + + + \ No newline at end of file diff --git a/test/index.ts b/test/index.ts new file mode 100644 index 0000000000..a9fba36956 --- /dev/null +++ b/test/index.ts @@ -0,0 +1,70 @@ +import 'mocha'; +import mochaDom = require('mocha-jsdom'); +import { expect } from 'chai'; +import * as fs from 'fs'; +import * as path from 'path'; +import { JSDOM } from 'jsdom'; +import { snapshot, rebuild } from '../src'; + +const htmlFolder = path.join(__dirname, 'html'); +const htmls = fs.readdirSync(htmlFolder).map(filePath => { + return { + filePath, + content: fs.readFileSync(path.resolve(htmlFolder, filePath), 'utf-8'), + }; +}); + +describe('integration tests', () => { + mochaDom({ url: 'http://localhost' }); + + it('will snapshot document type', () => { + const raw = ''; + const dom = new JSDOM(raw); + const snap = snapshot(dom.window.document); + expect(snap).to.deep.equal({ + type: 0, + childNodes: [ + { + type: 2, + tagName: 'html', + attributes: {}, + childNodes: [ + { + type: 2, + tagName: 'head', + attributes: {}, + childNodes: [], + id: 3, + }, + { + type: 2, + tagName: 'body', + attributes: {}, + childNodes: [], + id: 4, + }, + ], + id: 2, + }, + ], + id: 1, + }); + }); + + it('will not throw error with invalid attribute', () => { + const raw = ``; + const dom = new JSDOM(raw); + expect(() => rebuild(snapshot(dom.window.document))).not.to.throw(); + }); + + for (const html of htmls) { + it('[html file]:' + html.filePath, () => { + const dom = new JSDOM(html.content); + const snap = snapshot(dom.window.document); + const rebuildDom = rebuild(snap); + expect((rebuildDom as Document).documentElement.outerHTML).to.equal( + dom.window.document.documentElement.outerHTML, + ); + }); + } +}); diff --git a/tsconfig.json b/tsconfig.json index ce1b7e3ca7..06b323aa91 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,5 +9,7 @@ "outDir": "build", "lib": ["es6", "dom"] }, - "compileOnSave": true + "compileOnSave": true, + "exclude": ["test"], + "include": ["index.d.ts"] } diff --git a/tslint.json b/tslint.json index 3a0c080195..a153081c53 100644 --- a/tslint.json +++ b/tslint.json @@ -9,7 +9,13 @@ "object-literal-sort-keys": false, "no-unused-variable": true, "object-literal-key-quotes": false, - "variable-name": [true, "ban-keywords", "check-format", "allow-leading-underscore"] + "variable-name": [ + true, + "ban-keywords", + "check-format", + "allow-leading-underscore" + ], + "arrow-parens": false }, "rulesDirectory": [] -} \ No newline at end of file +} From 05e4103f7a6f9918fcaa71a1e1a0e2e09eae697d Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Sun, 30 Sep 2018 17:38:44 +0800 Subject: [PATCH 005/524] replace script tag with noscript and inline the states of form field components --- src/rebuild.ts | 13 +++- src/snapshot.ts | 35 +++++++++- src/types.ts | 2 +- test/html/with-script.html | 18 +++++ test/index.ts | 70 -------------------- test/integration.ts | 132 +++++++++++++++++++++++++++++++++++++ 6 files changed, 195 insertions(+), 75 deletions(-) create mode 100644 test/html/with-script.html delete mode 100644 test/index.ts create mode 100644 test/integration.ts diff --git a/src/rebuild.ts b/src/rebuild.ts index 3dee602629..f6be61ca7e 100644 --- a/src/rebuild.ts +++ b/src/rebuild.ts @@ -11,11 +11,20 @@ function buildNode(n: serializedNodeWithId): Node | null { n.systemId, ); case NodeType.Element: - const node = document.createElement(n.tagName); + const tagName = n.tagName === 'script' ? 'noscript' : n.tagName; + const node = document.createElement(tagName); for (const name in n.attributes) { if (n.attributes.hasOwnProperty(name)) { + let value = n.attributes[name]; + value = typeof value === 'boolean' ? '' : value; + // textarea hack + if (n.tagName === 'textarea' && name === 'value') { + const child = document.createTextNode(value); + node.appendChild(child); + continue; + } try { - node.setAttribute(name, n.attributes[name]); + node.setAttribute(name, value); } catch (error) { // skip invalid attribute } diff --git a/src/snapshot.ts b/src/snapshot.ts index ce805da52e..c6f4eb6010 100644 --- a/src/snapshot.ts +++ b/src/snapshot.ts @@ -11,6 +11,10 @@ function genId(): number { return _id++; } +function resetId() { + _id = 1; +} + function serializeNode(n: Node): serializedNode | false { switch (n.nodeType) { case n.DOCUMENT_NODE: @@ -31,6 +35,28 @@ function serializeNode(n: Node): serializedNode | false { for (const { name, value } of Array.from((n as HTMLElement).attributes)) { attributes[name] = value; } + if ( + tagName === 'input' || + tagName === 'textarea' || + tagName === 'select' + ) { + const value = (n as HTMLInputElement | HTMLTextAreaElement).value; + if ( + attributes.type !== 'radio' && + attributes.type !== 'checkbox' && + value + ) { + attributes.value = value; + } else if ((n as HTMLInputElement).checked) { + attributes.checked = (n as HTMLInputElement).checked; + } + } + if (tagName === 'option') { + const selectValue = (n as HTMLOptionElement).parentElement; + if (attributes.value === (selectValue as HTMLSelectElement).value) { + attributes.selected = (n as HTMLOptionElement).selected; + } + } return { type: NodeType.Element, tagName, @@ -65,7 +91,7 @@ function serializeNode(n: Node): serializedNode | false { } } -function snapshot(n: Node): serializedNodeWithId | null { +function _snapshot(n: Node): serializedNodeWithId | null { const _serializedNode = serializeNode(n); if (!_serializedNode) { // TODO: dev only @@ -80,10 +106,15 @@ function snapshot(n: Node): serializedNodeWithId | null { serializedNode.type === NodeType.Element ) { for (const childN of Array.from(n.childNodes)) { - serializedNode.childNodes.push(snapshot(childN)); + serializedNode.childNodes.push(_snapshot(childN)); } } return serializedNode; } +function snapshot(n: Node): serializedNodeWithId | null { + resetId(); + return _snapshot(n); +} + export default snapshot; diff --git a/src/types.ts b/src/types.ts index 25fc9962d6..17fc0e42c0 100644 --- a/src/types.ts +++ b/src/types.ts @@ -20,7 +20,7 @@ export type documentTypeNode = { }; export type attributes = { - [key: string]: string; + [key: string]: string | boolean; }; export type elementNode = { type: NodeType.Element; diff --git a/test/html/with-script.html b/test/html/with-script.html new file mode 100644 index 0000000000..e3598090ea --- /dev/null +++ b/test/html/with-script.html @@ -0,0 +1,18 @@ + + + + + + + + with script + + + + + + + + \ No newline at end of file diff --git a/test/index.ts b/test/index.ts deleted file mode 100644 index a9fba36956..0000000000 --- a/test/index.ts +++ /dev/null @@ -1,70 +0,0 @@ -import 'mocha'; -import mochaDom = require('mocha-jsdom'); -import { expect } from 'chai'; -import * as fs from 'fs'; -import * as path from 'path'; -import { JSDOM } from 'jsdom'; -import { snapshot, rebuild } from '../src'; - -const htmlFolder = path.join(__dirname, 'html'); -const htmls = fs.readdirSync(htmlFolder).map(filePath => { - return { - filePath, - content: fs.readFileSync(path.resolve(htmlFolder, filePath), 'utf-8'), - }; -}); - -describe('integration tests', () => { - mochaDom({ url: 'http://localhost' }); - - it('will snapshot document type', () => { - const raw = ''; - const dom = new JSDOM(raw); - const snap = snapshot(dom.window.document); - expect(snap).to.deep.equal({ - type: 0, - childNodes: [ - { - type: 2, - tagName: 'html', - attributes: {}, - childNodes: [ - { - type: 2, - tagName: 'head', - attributes: {}, - childNodes: [], - id: 3, - }, - { - type: 2, - tagName: 'body', - attributes: {}, - childNodes: [], - id: 4, - }, - ], - id: 2, - }, - ], - id: 1, - }); - }); - - it('will not throw error with invalid attribute', () => { - const raw = ``; - const dom = new JSDOM(raw); - expect(() => rebuild(snapshot(dom.window.document))).not.to.throw(); - }); - - for (const html of htmls) { - it('[html file]:' + html.filePath, () => { - const dom = new JSDOM(html.content); - const snap = snapshot(dom.window.document); - const rebuildDom = rebuild(snap); - expect((rebuildDom as Document).documentElement.outerHTML).to.equal( - dom.window.document.documentElement.outerHTML, - ); - }); - } -}); diff --git a/test/integration.ts b/test/integration.ts new file mode 100644 index 0000000000..00375d0dba --- /dev/null +++ b/test/integration.ts @@ -0,0 +1,132 @@ +import 'mocha'; +import mochaDom = require('mocha-jsdom'); +import { expect } from 'chai'; +import * as fs from 'fs'; +import * as path from 'path'; +import { JSDOM } from 'jsdom'; +import { snapshot, rebuild } from '../src'; + +const htmlFolder = path.join(__dirname, 'html'); +const htmls = fs.readdirSync(htmlFolder).map(filePath => { + return { + filePath, + content: fs.readFileSync(path.resolve(htmlFolder, filePath), 'utf-8'), + }; +}); + +describe('integration tests', () => { + mochaDom({ url: 'http://localhost' }); + + for (const html of htmls) { + it('[html file]:' + html.filePath, () => { + const dom = new JSDOM(html.content); + const snap = snapshot(dom.window.document); + const rebuildDom = rebuild(snap); + const htmlStr = dom.window.document.documentElement.outerHTML + .replace(/') + .replace(//g, '') + .replace(/<\/script>/g, ''); + expect((rebuildDom as Document).documentElement.outerHTML).to.equal( + htmlStr, + ); + }); + } + + it('will snapshot document type', () => { + const raw = ''; + const dom = new JSDOM(raw); + const snap = snapshot(dom.window.document); + expect(snap).to.deep.equal({ + type: 0, + childNodes: [ + { + type: 2, + tagName: 'html', + attributes: {}, + childNodes: [ + { + type: 2, + tagName: 'head', + attributes: {}, + childNodes: [], + id: 3, + }, + { + type: 2, + tagName: 'body', + attributes: {}, + childNodes: [], + id: 4, + }, + ], + id: 2, + }, + ], + id: 1, + }); + }); + + it('will not throw error with invalid attribute', () => { + const raw = ``; + const dom = new JSDOM(raw); + expect(() => rebuild(snapshot(dom.window.document))).not.to.throw(); + }); + + it('will inline text input value', () => { + const raw = ''; + const dom = new JSDOM(raw); + dom.window.document.querySelector('input').value = '1'; + const rebuildDom = rebuild(snapshot(dom.window.document)); + expect((rebuildDom as Document).querySelector('input').outerHTML).to.equal( + '', + ); + }); + + it('will inline radio input value', () => { + const raw = ''; + const dom = new JSDOM(raw); + dom.window.document.querySelector('input').checked = true; + const rebuildDom = rebuild(snapshot(dom.window.document)); + expect((rebuildDom as Document).querySelector('input').outerHTML).to.equal( + '', + ); + }); + + it('will inline checkbox input value', () => { + const raw = ''; + const dom = new JSDOM(raw); + dom.window.document.querySelector('input').checked = true; + const rebuildDom = rebuild(snapshot(dom.window.document)); + expect((rebuildDom as Document).querySelector('input').outerHTML).to.equal( + '', + ); + }); + + it('will inline textarea value into text node', () => { + const raw = ''; + const dom = new JSDOM(raw); + dom.window.document.querySelector('textarea').value = '1234'; + const rebuildDom = rebuild(snapshot(dom.window.document)); + expect( + (rebuildDom as Document).querySelector('textarea').outerHTML, + ).to.equal(''); + }); + + it('will inline options state', () => { + const raw = ` + + `; + const dom = new JSDOM(raw); + dom.window.document.querySelector('select').value = '2'; + const rebuildDom = rebuild(snapshot(dom.window.document)); + expect((rebuildDom as Document).querySelector('select').outerHTML).to.equal( + ``, + ); + }); +}); From bd325870e7753a3d658c1aaa1db5244357510560 Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Wed, 3 Oct 2018 12:08:46 +0800 Subject: [PATCH 006/524] refactor test infra so most test cases could be implemented by pure HTML --- test/css/style.css | 6 ++ test/html/form-fields.html | 79 ++++++++++++++++++++++ test/html/invalid-attribute.html | 9 +++ test/html/with-script.html | 21 +++++- test/integration.ts | 108 +++++++++---------------------- 5 files changed, 146 insertions(+), 77 deletions(-) create mode 100644 test/css/style.css create mode 100644 test/html/form-fields.html create mode 100644 test/html/invalid-attribute.html diff --git a/test/css/style.css b/test/css/style.css new file mode 100644 index 0000000000..70b063e64a --- /dev/null +++ b/test/css/style.css @@ -0,0 +1,6 @@ +body { + margin: 0; +} +p { + color: red; +} diff --git a/test/html/form-fields.html b/test/html/form-fields.html new file mode 100644 index 0000000000..6eef35449e --- /dev/null +++ b/test/html/form-fields.html @@ -0,0 +1,79 @@ + + + + + + + + form fields + + + +
+ + + + + +
+ + + + + + + + + + + + + + + form fields + + + +
+ + + + + +
+ + + + \ No newline at end of file diff --git a/test/html/invalid-attribute.html b/test/html/invalid-attribute.html new file mode 100644 index 0000000000..6fa84ad4c0 --- /dev/null +++ b/test/html/invalid-attribute.html @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/test/html/with-script.html b/test/html/with-script.html index e3598090ea..3dd8ca93e9 100644 --- a/test/html/with-script.html +++ b/test/html/with-script.html @@ -11,8 +11,27 @@ + + + + + + + + + + + + with script + + + + + + + \ No newline at end of file diff --git a/test/integration.ts b/test/integration.ts index 00375d0dba..4f9917c87c 100644 --- a/test/integration.ts +++ b/test/integration.ts @@ -8,9 +8,19 @@ import { snapshot, rebuild } from '../src'; const htmlFolder = path.join(__dirname, 'html'); const htmls = fs.readdirSync(htmlFolder).map(filePath => { + const raw = fs.readFileSync(path.resolve(htmlFolder, filePath), 'utf-8'); + if (//.test(raw)) { + const [src, dest] = raw.split(''); + return { + filePath, + src, + dest, + }; + } return { filePath, - content: fs.readFileSync(path.resolve(htmlFolder, filePath), 'utf-8'), + src: raw, + dest: raw, }; }); @@ -18,17 +28,27 @@ describe('integration tests', () => { mochaDom({ url: 'http://localhost' }); for (const html of htmls) { - it('[html file]:' + html.filePath, () => { - const dom = new JSDOM(html.content); - const snap = snapshot(dom.window.document); - const rebuildDom = rebuild(snap); - const htmlStr = dom.window.document.documentElement.outerHTML - .replace(/') - .replace(//g, '') - .replace(/<\/script>/g, ''); - expect((rebuildDom as Document).documentElement.outerHTML).to.equal( - htmlStr, - ); + it('[html file]: ' + html.filePath, done => { + const srcDom = new JSDOM(html.src, { runScripts: 'dangerously' }); + const destDom = new JSDOM(html.dest); + srcDom.window.document.addEventListener('DOMContentLoaded', () => { + const snap = snapshot(srcDom.window.document); + const rebuildDom = rebuild(snap); + const htmlStr = destDom.window.document.documentElement.outerHTML.replace( + /\n\n/g, + '', + ); + const rebuildStr = (rebuildDom as Document).documentElement.outerHTML.replace( + /\n\n/g, + '', + ); + try { + expect(rebuildStr).to.equal(htmlStr); + done(); + } catch (error) { + done(error); + } + }); }); } @@ -65,68 +85,4 @@ describe('integration tests', () => { id: 1, }); }); - - it('will not throw error with invalid attribute', () => { - const raw = ``; - const dom = new JSDOM(raw); - expect(() => rebuild(snapshot(dom.window.document))).not.to.throw(); - }); - - it('will inline text input value', () => { - const raw = ''; - const dom = new JSDOM(raw); - dom.window.document.querySelector('input').value = '1'; - const rebuildDom = rebuild(snapshot(dom.window.document)); - expect((rebuildDom as Document).querySelector('input').outerHTML).to.equal( - '', - ); - }); - - it('will inline radio input value', () => { - const raw = ''; - const dom = new JSDOM(raw); - dom.window.document.querySelector('input').checked = true; - const rebuildDom = rebuild(snapshot(dom.window.document)); - expect((rebuildDom as Document).querySelector('input').outerHTML).to.equal( - '', - ); - }); - - it('will inline checkbox input value', () => { - const raw = ''; - const dom = new JSDOM(raw); - dom.window.document.querySelector('input').checked = true; - const rebuildDom = rebuild(snapshot(dom.window.document)); - expect((rebuildDom as Document).querySelector('input').outerHTML).to.equal( - '', - ); - }); - - it('will inline textarea value into text node', () => { - const raw = ''; - const dom = new JSDOM(raw); - dom.window.document.querySelector('textarea').value = '1234'; - const rebuildDom = rebuild(snapshot(dom.window.document)); - expect( - (rebuildDom as Document).querySelector('textarea').outerHTML, - ).to.equal(''); - }); - - it('will inline options state', () => { - const raw = ` - - `; - const dom = new JSDOM(raw); - dom.window.document.querySelector('select').value = '2'; - const rebuildDom = rebuild(snapshot(dom.window.document)); - expect((rebuildDom as Document).querySelector('select').outerHTML).to.equal( - ``, - ); - }); }); From c24e0c6a2fb64729371f744aefc90db2348a2668 Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Fri, 5 Oct 2018 22:26:18 +0800 Subject: [PATCH 007/524] refactor the test infra: use puppeteer instead of jsdom to get rid of some hack implementations --- index.d.ts | 6 +- package.json | 11 ++- rollup.config.js | 10 +++ test/html/with-script.html | 4 +- test/html/with-style-sheet.html | 16 ++++ test/integration.ts | 145 ++++++++++++++++++-------------- test/js/a.js | 1 + test/server.ts | 0 tsconfig.json | 2 +- 9 files changed, 124 insertions(+), 71 deletions(-) create mode 100644 rollup.config.js create mode 100644 test/html/with-style-sheet.html create mode 100644 test/js/a.js create mode 100644 test/server.ts diff --git a/index.d.ts b/index.d.ts index f7f2dbfa0c..cbe3deb631 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,4 +1,4 @@ -declare module 'mocha-jsdom' { - function mochaDom(options: any): void; - export = mochaDom; +declare module 'rollup-plugin-typescript' { + function typescript(): any; + export = typescript; } diff --git a/package.json b/package.json index 2c62a4c911..5944a8df19 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "description": "rrweb's component to take a snapshot of DOM, aka DOM serializer", "main": "index.js", "scripts": { - "test": "TS_NODE_FILES=true mocha -r ts-node/register test/**/*.ts" + "test": "TS_NODE_FILES=true mocha -r ts-node/register test/**/*.ts", + "compile": "rollup --config" }, "repository": { "type": "git", @@ -23,14 +24,16 @@ "homepage": "https://github.com/rrweb-io/rrweb-snapshot#readme", "devDependencies": { "@types/chai": "^4.1.4", - "@types/jsdom": "^11.12.0", "@types/mocha": "^5.2.5", "@types/node": "^10.11.3", + "@types/puppeteer": "^1.8.0", "chai": "^4.1.2", - "jsdom": "^12.1.0", "mocha": "^5.2.0", - "mocha-jsdom": "^2.0.0", + "puppeteer": "^1.9.0", + "rollup": "^0.66.4", + "rollup-plugin-typescript": "^1.0.0", "ts-node": "^7.0.1", + "tslib": "^1.9.3", "tslint": "^4.5.1", "typescript": "^3.0.3" } diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 0000000000..d50804666a --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,10 @@ +import typescript from 'rollup-plugin-typescript'; + +export default { + input: './src/index.ts', + plugins: [typescript()], + output: { + name: 'rrweb', + format: 'iife', + }, +}; diff --git a/test/html/with-script.html b/test/html/with-script.html index 3dd8ca93e9..5ef140a7ed 100644 --- a/test/html/with-script.html +++ b/test/html/with-script.html @@ -9,7 +9,7 @@ - + @@ -30,7 +30,7 @@ - + diff --git a/test/html/with-style-sheet.html b/test/html/with-style-sheet.html new file mode 100644 index 0000000000..43e0cb01e2 --- /dev/null +++ b/test/html/with-style-sheet.html @@ -0,0 +1,16 @@ + + + + + + + + with style sheet + + + + + + + + \ No newline at end of file diff --git a/test/integration.ts b/test/integration.ts index 4f9917c87c..cdd4139f1b 100644 --- a/test/integration.ts +++ b/test/integration.ts @@ -1,10 +1,12 @@ -import 'mocha'; -import mochaDom = require('mocha-jsdom'); -import { expect } from 'chai'; import * as fs from 'fs'; import * as path from 'path'; -import { JSDOM } from 'jsdom'; -import { snapshot, rebuild } from '../src'; +import * as http from 'http'; +import * as url from 'url'; +import 'mocha'; +import * as puppeteer from 'puppeteer'; +import * as rollup from 'rollup'; +import typescript = require('rollup-plugin-typescript'); +import { expect } from 'chai'; const htmlFolder = path.join(__dirname, 'html'); const htmls = fs.readdirSync(htmlFolder).map(filePath => { @@ -24,65 +26,86 @@ const htmls = fs.readdirSync(htmlFolder).map(filePath => { }; }); -describe('integration tests', () => { - mochaDom({ url: 'http://localhost' }); +interface IMimeType { + [key: string]: string; +} - for (const html of htmls) { - it('[html file]: ' + html.filePath, done => { - const srcDom = new JSDOM(html.src, { runScripts: 'dangerously' }); - const destDom = new JSDOM(html.dest); - srcDom.window.document.addEventListener('DOMContentLoaded', () => { - const snap = snapshot(srcDom.window.document); - const rebuildDom = rebuild(snap); - const htmlStr = destDom.window.document.documentElement.outerHTML.replace( - /\n\n/g, - '', - ); - const rebuildStr = (rebuildDom as Document).documentElement.outerHTML.replace( - /\n\n/g, - '', - ); - try { - expect(rebuildStr).to.equal(htmlStr); - done(); - } catch (error) { - done(error); - } - }); +const server = () => + new Promise(resolve => { + const mimeType: IMimeType = { + '.html': 'text/html', + '.js': 'text/javascript', + '.css': 'text/css', + }; + const s = http.createServer((req, res) => { + const parsedUrl = url.parse(req.url); + const sanitizePath = path + .normalize(parsedUrl.pathname) + .replace(/^(\.\.[\/\\])+/, ''); + let pathname = path.join(__dirname, sanitizePath); + try { + const data = fs.readFileSync(pathname); + const ext = path.parse(pathname).ext; + res.setHeader('Content-type', mimeType[ext] || 'text/plain'); + res.setHeader('Access-Control-Allow-Origin', '*'); + res.setHeader('Access-Control-Allow-Methods', 'GET'); + res.setHeader('Access-Control-Allow-Headers', 'Content-type'); + res.end(data); + } catch (error) { + res.end(); + } }); - } + s.listen(3030).on('listening', () => { + resolve(s); + }); + }); - it('will snapshot document type', () => { - const raw = ''; - const dom = new JSDOM(raw); - const snap = snapshot(dom.window.document); - expect(snap).to.deep.equal({ - type: 0, - childNodes: [ - { - type: 2, - tagName: 'html', - attributes: {}, - childNodes: [ - { - type: 2, - tagName: 'head', - attributes: {}, - childNodes: [], - id: 3, - }, - { - type: 2, - tagName: 'body', - attributes: {}, - childNodes: [], - id: 4, - }, - ], - id: 2, - }, - ], - id: 1, +describe('integration tests', () => { + before(async () => { + this.server = await server(); + this.browser = await puppeteer.launch({ + headless: false, + executablePath: '/home/yanzhen/Desktop/chrome-linux/chrome', + }); + + const bundle = await rollup.rollup({ + input: path.resolve(__dirname, '../src/index.ts'), + plugins: [typescript()], }); + const { code } = await bundle.generate({ + name: 'rrweb', + format: 'iife', + }); + this.code = code; + }); + + after(() => { + this.browser.close(); + this.server.close(); }); + + for (const html of htmls) { + it('[html file]: ' + html.filePath, async () => { + const page: puppeteer.Page = await this.browser.newPage(); + await page.goto(`http://localhost:3030/html/${html.filePath}`); + await page.setContent(html.src); + page.once('load', async () => { + await page.evaluate(() => { + const x = new XMLSerializer(); + return x.serializeToString(document); + }); + const rebuildHtml = (await page.evaluate(`${this.code} + const x = new XMLSerializer(); + const snap = rrweb.snapshot(document); + x.serializeToString(rrweb.rebuild(snap)); + `)).replace(/\n\n/g, ''); + await page.goto(`data:text/html,${html.dest}`); + const destHtml = (await page.evaluate(() => { + const x = new XMLSerializer(); + return x.serializeToString(document); + })).replace(/\n\n/g, ''); + expect(rebuildHtml).to.equal(destHtml); + }); + }).timeout(5000); + } }); diff --git a/test/js/a.js b/test/js/a.js new file mode 100644 index 0000000000..7a776f910f --- /dev/null +++ b/test/js/a.js @@ -0,0 +1 @@ +var a = 1 + 1; diff --git a/test/server.ts b/test/server.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tsconfig.json b/tsconfig.json index 06b323aa91..6378ca69d7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,5 +11,5 @@ }, "compileOnSave": true, "exclude": ["test"], - "include": ["index.d.ts"] + "include": ["src", "index.d.ts"] } From 8b82981b621d8b11763876e988251d644b1b082a Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Fri, 5 Oct 2018 23:06:51 +0800 Subject: [PATCH 008/524] try to inline linked stylesheet when in same origin --- src/rebuild.ts | 20 +++++++++++--- src/snapshot.ts | 38 ++++++++++++++++++++++----- src/types.ts | 4 +++ test/html/cors-style-sheet.html | 16 ++++++++++++ test/html/with-style-sheet.html | 19 ++++++++++++++ test/integration.ts | 46 +++++++++++++++++---------------- 6 files changed, 110 insertions(+), 33 deletions(-) create mode 100644 test/html/cors-style-sheet.html diff --git a/src/rebuild.ts b/src/rebuild.ts index f6be61ca7e..bcf1f681ba 100644 --- a/src/rebuild.ts +++ b/src/rebuild.ts @@ -1,4 +1,15 @@ -import { serializedNodeWithId, NodeType } from './types'; +import { serializedNodeWithId, NodeType, tagMap, elementNode } from './types'; + +const tagMap: tagMap = { + script: 'noscript', +}; +function getTagName(n: elementNode): string { + let tagName = tagMap[n.tagName] ? tagMap[n.tagName] : n.tagName; + if (tagName === 'link' && n.attributes._cssText) { + tagName = 'style'; + } + return tagName; +} function buildNode(n: serializedNodeWithId): Node | null { switch (n.type) { @@ -11,14 +22,15 @@ function buildNode(n: serializedNodeWithId): Node | null { n.systemId, ); case NodeType.Element: - const tagName = n.tagName === 'script' ? 'noscript' : n.tagName; + const tagName = getTagName(n); const node = document.createElement(tagName); for (const name in n.attributes) { if (n.attributes.hasOwnProperty(name)) { let value = n.attributes[name]; value = typeof value === 'boolean' ? '' : value; - // textarea hack - if (n.tagName === 'textarea' && name === 'value') { + const isTextarea = tagName === 'textarea' && name === 'value'; + const isRemoteCss = tagName === 'style' && name === '_cssText'; + if (isTextarea || isRemoteCss) { const child = document.createTextNode(value); node.appendChild(child); continue; diff --git a/src/snapshot.ts b/src/snapshot.ts index c6f4eb6010..c5af9f58b7 100644 --- a/src/snapshot.ts +++ b/src/snapshot.ts @@ -15,7 +15,18 @@ function resetId() { _id = 1; } -function serializeNode(n: Node): serializedNode | false { +function getCssRulesString(s: CSSStyleSheet): string | null { + try { + const rules = s.rules || s.cssRules; + return rules + ? Array.from(rules).reduce((prev, cur) => (prev += cur.cssText), '') + : null; + } catch (error) { + return null; + } +} + +function serializeNode(n: Node, doc: Document): serializedNode | false { switch (n.nodeType) { case n.DOCUMENT_NODE: return { @@ -31,10 +42,23 @@ function serializeNode(n: Node): serializedNode | false { }; case n.ELEMENT_NODE: const tagName = (n as HTMLElement).tagName.toLowerCase(); - const attributes: attributes = {}; + let attributes: attributes = {}; for (const { name, value } of Array.from((n as HTMLElement).attributes)) { attributes[name] = value; } + // remote css + if (tagName === 'link' && attributes.hasOwnProperty('href')) { + const stylesheet = Array.from(doc.styleSheets).find( + s => s.href === attributes.href, + ); + const cssText = getCssRulesString(stylesheet as CSSStyleSheet); + if (cssText) { + attributes = { + _cssText: cssText, + }; + } + } + // form fields if ( tagName === 'input' || tagName === 'textarea' || @@ -91,8 +115,8 @@ function serializeNode(n: Node): serializedNode | false { } } -function _snapshot(n: Node): serializedNodeWithId | null { - const _serializedNode = serializeNode(n); +function _snapshot(n: Node, doc: Document): serializedNodeWithId | null { + const _serializedNode = serializeNode(n, doc); if (!_serializedNode) { // TODO: dev only console.warn(n, 'not serialized'); @@ -106,15 +130,15 @@ function _snapshot(n: Node): serializedNodeWithId | null { serializedNode.type === NodeType.Element ) { for (const childN of Array.from(n.childNodes)) { - serializedNode.childNodes.push(_snapshot(childN)); + serializedNode.childNodes.push(_snapshot(childN, doc)); } } return serializedNode; } -function snapshot(n: Node): serializedNodeWithId | null { +function snapshot(n: Document): serializedNodeWithId | null { resetId(); - return _snapshot(n); + return _snapshot(n, n); } export default snapshot; diff --git a/src/types.ts b/src/types.ts index 17fc0e42c0..ea19a1989f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -53,3 +53,7 @@ export type serializedNode = | commentNode; export type serializedNodeWithId = serializedNode & { id: number }; + +export type tagMap = { + [key: string]: string; +}; diff --git a/test/html/cors-style-sheet.html b/test/html/cors-style-sheet.html new file mode 100644 index 0000000000..06dddaa262 --- /dev/null +++ b/test/html/cors-style-sheet.html @@ -0,0 +1,16 @@ + + + + + + + + with style sheet + + + + + + + + \ No newline at end of file diff --git a/test/html/with-style-sheet.html b/test/html/with-style-sheet.html index 43e0cb01e2..14f09d38f9 100644 --- a/test/html/with-style-sheet.html +++ b/test/html/with-style-sheet.html @@ -13,4 +13,23 @@ + + + + + + + + + + + + with style sheet + + + + + + + \ No newline at end of file diff --git a/test/integration.ts b/test/integration.ts index cdd4139f1b..40f9cc035f 100644 --- a/test/integration.ts +++ b/test/integration.ts @@ -64,7 +64,7 @@ describe('integration tests', () => { before(async () => { this.server = await server(); this.browser = await puppeteer.launch({ - headless: false, + // headless: false, executablePath: '/home/yanzhen/Desktop/chrome-linux/chrome', }); @@ -79,33 +79,35 @@ describe('integration tests', () => { this.code = code; }); - after(() => { - this.browser.close(); - this.server.close(); + after(async () => { + await this.browser.close(); + await this.server.close(); }); - for (const html of htmls) { + for (const html of htmls.slice(0, 10)) { it('[html file]: ' + html.filePath, async () => { const page: puppeteer.Page = await this.browser.newPage(); - await page.goto(`http://localhost:3030/html/${html.filePath}`); + // console for debug + // tslint:disable-next-line: no-console + page.on('console', msg => console.log(msg.text())); + await page.goto(`http://localhost:3030/html`); await page.setContent(html.src); - page.once('load', async () => { - await page.evaluate(() => { - const x = new XMLSerializer(); - return x.serializeToString(document); - }); - const rebuildHtml = (await page.evaluate(`${this.code} - const x = new XMLSerializer(); - const snap = rrweb.snapshot(document); - x.serializeToString(rrweb.rebuild(snap)); - `)).replace(/\n\n/g, ''); - await page.goto(`data:text/html,${html.dest}`); - const destHtml = (await page.evaluate(() => { - const x = new XMLSerializer(); - return x.serializeToString(document); - })).replace(/\n\n/g, ''); - expect(rebuildHtml).to.equal(destHtml); + await page.evaluate(() => { + const x = new XMLSerializer(); + return x.serializeToString(document); }); + const rebuildHtml = (await page.evaluate(`${this.code} + const x = new XMLSerializer(); + const snap = rrweb.snapshot(document); + x.serializeToString(rrweb.rebuild(snap)); + `)).replace(/\n\n/g, ''); + await page.goto(`http://localhost:3030/html`); + await page.setContent(html.dest); + const destHtml = (await page.evaluate(() => { + const x = new XMLSerializer(); + return x.serializeToString(document); + })).replace(/\n\n/g, ''); + expect(rebuildHtml).to.equal(destHtml); }).timeout(5000); } }); From bfe431e99ab87cfe58050cacec0f804abd5a8cb9 Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Sat, 6 Oct 2018 10:13:33 +0800 Subject: [PATCH 009/524] add iframe tests and update urls in test file --- src/snapshot.ts | 8 ++++---- test/html/iframe-inner.html | 1 + test/html/iframe.html | 12 ++++++++++++ test/html/with-script.html | 4 ++-- test/html/with-style-sheet.html | 2 +- 5 files changed, 20 insertions(+), 7 deletions(-) create mode 100644 test/html/iframe-inner.html create mode 100644 test/html/iframe.html diff --git a/src/snapshot.ts b/src/snapshot.ts index c5af9f58b7..0501f499eb 100644 --- a/src/snapshot.ts +++ b/src/snapshot.ts @@ -47,10 +47,10 @@ function serializeNode(n: Node, doc: Document): serializedNode | false { attributes[name] = value; } // remote css - if (tagName === 'link' && attributes.hasOwnProperty('href')) { - const stylesheet = Array.from(doc.styleSheets).find( - s => s.href === attributes.href, - ); + if (tagName === 'link') { + const stylesheet = Array.from(doc.styleSheets).find(s => { + return s.href === (n as HTMLLinkElement).href; + }); const cssText = getCssRulesString(stylesheet as CSSStyleSheet); if (cssText) { attributes = { diff --git a/test/html/iframe-inner.html b/test/html/iframe-inner.html new file mode 100644 index 0000000000..2ef778d9d8 --- /dev/null +++ b/test/html/iframe-inner.html @@ -0,0 +1 @@ + diff --git a/test/html/iframe.html b/test/html/iframe.html new file mode 100644 index 0000000000..8b45139ed4 --- /dev/null +++ b/test/html/iframe.html @@ -0,0 +1,12 @@ + + + + + + + iframe + + + + + diff --git a/test/html/with-script.html b/test/html/with-script.html index 5ef140a7ed..d727133827 100644 --- a/test/html/with-script.html +++ b/test/html/with-script.html @@ -9,7 +9,7 @@ - + @@ -30,7 +30,7 @@ - + diff --git a/test/html/with-style-sheet.html b/test/html/with-style-sheet.html index 14f09d38f9..9fc5bdad20 100644 --- a/test/html/with-style-sheet.html +++ b/test/html/with-style-sheet.html @@ -6,7 +6,7 @@ with style sheet - + From b536f1206470403d571d9ba530b6ed6f82590d48 Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Sat, 6 Oct 2018 22:27:49 +0800 Subject: [PATCH 010/524] update declaration file --- index.d.ts | 8 ++++---- package.json | 2 +- test.d.ts | 4 ++++ test/server.ts | 0 tsconfig.json | 2 +- 5 files changed, 10 insertions(+), 6 deletions(-) create mode 100644 test.d.ts delete mode 100644 test/server.ts diff --git a/index.d.ts b/index.d.ts index cbe3deb631..e1d96cb4b1 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,4 +1,4 @@ -declare module 'rollup-plugin-typescript' { - function typescript(): any; - export = typescript; -} +import { serializedNodeWithId } from './src/types'; + +export function snapshot(n: Document): serializedNodeWithId | null; +export function rebuild(n: serializedNodeWithId): Node | null; diff --git a/package.json b/package.json index 5944a8df19..a4d87dcf36 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "rrweb's component to take a snapshot of DOM, aka DOM serializer", "main": "index.js", "scripts": { - "test": "TS_NODE_FILES=true mocha -r ts-node/register test/**/*.ts", + "test": "TS_NODE_CACHE=false TS_NODE_FILES=true mocha -r ts-node/register test/**/*.ts", "compile": "rollup --config" }, "repository": { diff --git a/test.d.ts b/test.d.ts new file mode 100644 index 0000000000..cbe3deb631 --- /dev/null +++ b/test.d.ts @@ -0,0 +1,4 @@ +declare module 'rollup-plugin-typescript' { + function typescript(): any; + export = typescript; +} diff --git a/test/server.ts b/test/server.ts deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tsconfig.json b/tsconfig.json index 6378ca69d7..f82e02cd85 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,5 +11,5 @@ }, "compileOnSave": true, "exclude": ["test"], - "include": ["src", "index.d.ts"] + "include": ["src", "test.d.ts"] } From 4a1137748c6d9508896fe84f252e64400ba38b54 Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Mon, 8 Oct 2018 10:28:34 +0800 Subject: [PATCH 011/524] bump 0.2.0 --- README.md | 8 +++++++- package.json | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 98c66522e2..d61b9f71d6 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ # rrweb-snapshot -Not ready yet +Snapshot the DOM into a stateful and serializable data structure. +Also provide the ability to rebuild the DOM via snapshot. + +## TODO + +- [ ] Replace any url in css rules into absolute path. +- [ ] Select a suitable build strategy. diff --git a/package.json b/package.json index a4d87dcf36..73c0b112e9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rrweb-snapshot", - "version": "0.1.0", + "version": "0.2.0", "description": "rrweb's component to take a snapshot of DOM, aka DOM serializer", "main": "index.js", "scripts": { From 978e12b089683c3454433898d5cbcebd0bf8b458 Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Mon, 8 Oct 2018 11:20:48 +0800 Subject: [PATCH 012/524] add strict null check and fix codes --- index.d.ts | 1 + src/index.ts | 1 + src/rebuild.ts | 6 +++++- src/snapshot.ts | 9 ++++++--- tsconfig.json | 1 + 5 files changed, 14 insertions(+), 4 deletions(-) diff --git a/index.d.ts b/index.d.ts index e1d96cb4b1..bb15b0beaf 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,4 +1,5 @@ import { serializedNodeWithId } from './src/types'; +export * from './src/types'; export function snapshot(n: Document): serializedNodeWithId | null; export function rebuild(n: serializedNodeWithId): Node | null; diff --git a/src/index.ts b/src/index.ts index 758f2df991..6b8e1450e4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,5 @@ import snapshot from './snapshot'; import rebuild from './rebuild'; +export * from './types'; export { snapshot, rebuild }; diff --git a/src/rebuild.ts b/src/rebuild.ts index bcf1f681ba..fce1fb36b5 100644 --- a/src/rebuild.ts +++ b/src/rebuild.ts @@ -62,7 +62,11 @@ function rebuild(n: serializedNodeWithId): Node | null { if (n.type === NodeType.Document || n.type === NodeType.Element) { for (const childN of n.childNodes) { const childNode = rebuild(childN); - root.appendChild(childNode); + if (!childNode) { + console.warn('Failed to rebuild', childN); + } else { + root.appendChild(childNode); + } } } return root; diff --git a/src/snapshot.ts b/src/snapshot.ts index 0501f499eb..913210a49c 100644 --- a/src/snapshot.ts +++ b/src/snapshot.ts @@ -98,7 +98,7 @@ function serializeNode(n: Node, doc: Document): serializedNode | false { } return { type: NodeType.Text, - textContent, + textContent: textContent || '', }; case n.CDATA_SECTION_NODE: return { @@ -108,7 +108,7 @@ function serializeNode(n: Node, doc: Document): serializedNode | false { case n.COMMENT_NODE: return { type: NodeType.Comment, - textContent: (n as Comment).textContent, + textContent: (n as Comment).textContent || '', }; default: return false; @@ -130,7 +130,10 @@ function _snapshot(n: Node, doc: Document): serializedNodeWithId | null { serializedNode.type === NodeType.Element ) { for (const childN of Array.from(n.childNodes)) { - serializedNode.childNodes.push(_snapshot(childN, doc)); + const serializedChildNode = _snapshot(childN, doc); + if (serializedChildNode) { + serializedNode.childNodes.push(serializedChildNode); + } } } return serializedNode; diff --git a/tsconfig.json b/tsconfig.json index f82e02cd85..d58ee54673 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,6 +2,7 @@ "compilerOptions": { "module": "commonjs", "noImplicitAny": true, + "strictNullChecks": true, "removeComments": true, "preserveConstEnums": true, "sourceMap": true, From f143eee54a70a441685051a666f9e5d23c0c2534 Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Mon, 8 Oct 2018 15:35:03 +0800 Subject: [PATCH 013/524] return id node map when snapshot --- index.d.ts | 4 ++-- src/snapshot.ts | 29 ++++++++++++++++++++++++----- src/types.ts | 8 ++++++++ test/integration.ts | 6 +++--- 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/index.d.ts b/index.d.ts index bb15b0beaf..fa9eae71ae 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,5 +1,5 @@ -import { serializedNodeWithId } from './src/types'; +import { serializedNodeWithId, idNodeMap } from './src/types'; export * from './src/types'; -export function snapshot(n: Document): serializedNodeWithId | null; +export function snapshot(n: Document): [serializedNodeWithId | null, idNodeMap]; export function rebuild(n: serializedNodeWithId): Node | null; diff --git a/src/snapshot.ts b/src/snapshot.ts index 913210a49c..15642b7fa8 100644 --- a/src/snapshot.ts +++ b/src/snapshot.ts @@ -3,6 +3,8 @@ import { serializedNodeWithId, NodeType, attributes, + INode, + idNodeMap, } from './types'; let _id = 1; @@ -115,22 +117,38 @@ function serializeNode(n: Node, doc: Document): serializedNode | false { } } -function _snapshot(n: Node, doc: Document): serializedNodeWithId | null { +function serializeNodeWithId( + n: Node, + doc: Document, +): serializedNodeWithId | null { const _serializedNode = serializeNode(n, doc); if (!_serializedNode) { // TODO: dev only console.warn(n, 'not serialized'); return null; } - const serializedNode: serializedNodeWithId = Object.assign(_serializedNode, { + return Object.assign(_serializedNode, { id: genId(), }); +} + +function _snapshot( + n: Node, + doc: Document, + map: idNodeMap, +): serializedNodeWithId | null { + const serializedNode = serializeNodeWithId(n, doc); + if (!serializedNode) { + return null; + } + (n as INode).__sn = serializedNode; + map[serializedNode.id] = n as INode; if ( serializedNode.type === NodeType.Document || serializedNode.type === NodeType.Element ) { for (const childN of Array.from(n.childNodes)) { - const serializedChildNode = _snapshot(childN, doc); + const serializedChildNode = _snapshot(childN, doc, map); if (serializedChildNode) { serializedNode.childNodes.push(serializedChildNode); } @@ -139,9 +157,10 @@ function _snapshot(n: Node, doc: Document): serializedNodeWithId | null { return serializedNode; } -function snapshot(n: Document): serializedNodeWithId | null { +function snapshot(n: Document): [serializedNodeWithId | null, idNodeMap] { resetId(); - return _snapshot(n, n); + const idNodeMap: idNodeMap = {}; + return [_snapshot(n, n, idNodeMap), idNodeMap]; } export default snapshot; diff --git a/src/types.ts b/src/types.ts index ea19a1989f..6fbe58e286 100644 --- a/src/types.ts +++ b/src/types.ts @@ -57,3 +57,11 @@ export type serializedNodeWithId = serializedNode & { id: number }; export type tagMap = { [key: string]: string; }; + +export interface INode extends Node { + __sn: serializedNodeWithId; +} + +export type idNodeMap = { + [key: number]: INode; +}; diff --git a/test/integration.ts b/test/integration.ts index 40f9cc035f..a6ed7da5f1 100644 --- a/test/integration.ts +++ b/test/integration.ts @@ -38,9 +38,9 @@ const server = () => '.css': 'text/css', }; const s = http.createServer((req, res) => { - const parsedUrl = url.parse(req.url); + const parsedUrl = url.parse(req.url!); const sanitizePath = path - .normalize(parsedUrl.pathname) + .normalize(parsedUrl.pathname!) .replace(/^(\.\.[\/\\])+/, ''); let pathname = path.join(__dirname, sanitizePath); try { @@ -98,7 +98,7 @@ describe('integration tests', () => { }); const rebuildHtml = (await page.evaluate(`${this.code} const x = new XMLSerializer(); - const snap = rrweb.snapshot(document); + const [snap] = rrweb.snapshot(document); x.serializeToString(rrweb.rebuild(snap)); `)).replace(/\n\n/g, ''); await page.goto(`http://localhost:3030/html`); From d59ba817cb2f30d0d05a780d384262acb93286bc Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Tue, 9 Oct 2018 10:51:30 +0800 Subject: [PATCH 014/524] export serializeNodeWithId so rrweb could serialize newly added nodes --- index.d.ts | 5 +++++ src/index.ts | 4 ++-- src/snapshot.ts | 12 +++++++----- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/index.d.ts b/index.d.ts index fa9eae71ae..85dc9653bf 100644 --- a/index.d.ts +++ b/index.d.ts @@ -3,3 +3,8 @@ export * from './src/types'; export function snapshot(n: Document): [serializedNodeWithId | null, idNodeMap]; export function rebuild(n: serializedNodeWithId): Node | null; +export function serializeNodeWithId( + n: Node, + doc: Document, + map: idNodeMap, +): serializedNodeWithId | null; diff --git a/src/index.ts b/src/index.ts index 6b8e1450e4..fd9694655a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ -import snapshot from './snapshot'; +import snapshot, { serializeNodeWithId } from './snapshot'; import rebuild from './rebuild'; export * from './types'; -export { snapshot, rebuild }; +export { snapshot, serializeNodeWithId, rebuild }; diff --git a/src/snapshot.ts b/src/snapshot.ts index 15642b7fa8..04eddcf3a3 100644 --- a/src/snapshot.ts +++ b/src/snapshot.ts @@ -117,9 +117,10 @@ function serializeNode(n: Node, doc: Document): serializedNode | false { } } -function serializeNodeWithId( +export function serializeNodeWithId( n: Node, doc: Document, + map: idNodeMap, ): serializedNodeWithId | null { const _serializedNode = serializeNode(n, doc); if (!_serializedNode) { @@ -127,9 +128,12 @@ function serializeNodeWithId( console.warn(n, 'not serialized'); return null; } - return Object.assign(_serializedNode, { + const serializedNode = Object.assign(_serializedNode, { id: genId(), }); + (n as INode).__sn = serializedNode; + map[serializedNode.id] = n as INode; + return serializedNode; } function _snapshot( @@ -137,12 +141,10 @@ function _snapshot( doc: Document, map: idNodeMap, ): serializedNodeWithId | null { - const serializedNode = serializeNodeWithId(n, doc); + const serializedNode = serializeNodeWithId(n, doc, map); if (!serializedNode) { return null; } - (n as INode).__sn = serializedNode; - map[serializedNode.id] = n as INode; if ( serializedNode.type === NodeType.Document || serializedNode.type === NodeType.Element From b3fdc44fc757f08bf4d5e77b08f452cd9ac45c3c Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Thu, 11 Oct 2018 16:44:38 +0800 Subject: [PATCH 015/524] update the bundle config --- .gitignore | 1 + package.json | 10 +++++++--- rollup.config.js | 19 +++++++++++++++---- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 6ccc9d846d..f35f48b860 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ node_modules package-lock.json build +dist diff --git a/package.json b/package.json index 73c0b112e9..0c399ca927 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,12 @@ { "name": "rrweb-snapshot", - "version": "0.2.0", + "version": "0.3.0", "description": "rrweb's component to take a snapshot of DOM, aka DOM serializer", - "main": "index.js", + "main": "dist/index.js", + "module": "dist/module.js", "scripts": { "test": "TS_NODE_CACHE=false TS_NODE_FILES=true mocha -r ts-node/register test/**/*.ts", - "compile": "rollup --config" + "bundle": "rollup --config" }, "repository": { "type": "git", @@ -16,6 +17,9 @@ "snapshot", "DOM" ], + "files": [ + "dist" + ], "author": "yanzhen@smartx.com", "license": "MIT", "bugs": { diff --git a/rollup.config.js b/rollup.config.js index d50804666a..dc2cd261f5 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -3,8 +3,19 @@ import typescript from 'rollup-plugin-typescript'; export default { input: './src/index.ts', plugins: [typescript()], - output: { - name: 'rrweb', - format: 'iife', - }, + output: [ + { + format: 'cjs', + file: './dist/index.js', + }, + { + format: 'esm', + file: './dist/module.js', + }, + { + name: 'rrwebSnapshot', + format: 'iife', + file: './dist/browser.js', + }, + ], }; From 1ddb0a334336e8337930a181f7e6c6916a2948b1 Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Fri, 12 Oct 2018 12:43:16 +0800 Subject: [PATCH 016/524] return id node map when rebuild --- index.d.ts | 2 +- src/rebuild.ts | 20 +++++++++++++++++--- test/css/style.css | 3 +++ test/html/with-style-sheet.html | 2 +- test/integration.ts | 2 +- 5 files changed, 23 insertions(+), 6 deletions(-) diff --git a/index.d.ts b/index.d.ts index 85dc9653bf..0bc43523fd 100644 --- a/index.d.ts +++ b/index.d.ts @@ -2,7 +2,7 @@ import { serializedNodeWithId, idNodeMap } from './src/types'; export * from './src/types'; export function snapshot(n: Document): [serializedNodeWithId | null, idNodeMap]; -export function rebuild(n: serializedNodeWithId): Node | null; +export function rebuild(n: serializedNodeWithId): [Node | null, idNodeMap]; export function serializeNodeWithId( n: Node, doc: Document, diff --git a/src/rebuild.ts b/src/rebuild.ts index fce1fb36b5..1302926284 100644 --- a/src/rebuild.ts +++ b/src/rebuild.ts @@ -1,4 +1,11 @@ -import { serializedNodeWithId, NodeType, tagMap, elementNode } from './types'; +import { + serializedNodeWithId, + NodeType, + tagMap, + elementNode, + idNodeMap, + INode, +} from './types'; const tagMap: tagMap = { script: 'noscript', @@ -54,14 +61,16 @@ function buildNode(n: serializedNodeWithId): Node | null { } } -function rebuild(n: serializedNodeWithId): Node | null { +function _rebuild(n: serializedNodeWithId, map: idNodeMap): Node | null { const root = buildNode(n); if (!root) { return null; } + (root as INode).__sn = n; + map[n.id] = root as INode; if (n.type === NodeType.Document || n.type === NodeType.Element) { for (const childN of n.childNodes) { - const childNode = rebuild(childN); + const childNode = _rebuild(childN, map); if (!childNode) { console.warn('Failed to rebuild', childN); } else { @@ -72,4 +81,9 @@ function rebuild(n: serializedNodeWithId): Node | null { return root; } +function rebuild(n: serializedNodeWithId): [Node | null, idNodeMap] { + const idNodeMap: idNodeMap = {}; + return [_rebuild(n, idNodeMap), idNodeMap]; +} + export default rebuild; diff --git a/test/css/style.css b/test/css/style.css index 70b063e64a..f1be9954d9 100644 --- a/test/css/style.css +++ b/test/css/style.css @@ -4,3 +4,6 @@ body { p { color: red; } +body > p { + color: yellow; +} diff --git a/test/html/with-style-sheet.html b/test/html/with-style-sheet.html index 9fc5bdad20..9ba3c5e4d2 100644 --- a/test/html/with-style-sheet.html +++ b/test/html/with-style-sheet.html @@ -25,7 +25,7 @@ with style sheet - + diff --git a/test/integration.ts b/test/integration.ts index a6ed7da5f1..13647cc8ad 100644 --- a/test/integration.ts +++ b/test/integration.ts @@ -99,7 +99,7 @@ describe('integration tests', () => { const rebuildHtml = (await page.evaluate(`${this.code} const x = new XMLSerializer(); const [snap] = rrweb.snapshot(document); - x.serializeToString(rrweb.rebuild(snap)); + x.serializeToString(rrweb.rebuild(snap)[0]); `)).replace(/\n\n/g, ''); await page.goto(`http://localhost:3030/html`); await page.setContent(html.dest); From ffc2b01796c2c54c72d6ffad27bd0d1153bcc821 Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Fri, 12 Oct 2018 15:56:02 +0800 Subject: [PATCH 017/524] add data attribute to element when rebuild --- index.d.ts | 2 +- src/rebuild.ts | 23 ++++++----------------- 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/index.d.ts b/index.d.ts index 0bc43523fd..85dc9653bf 100644 --- a/index.d.ts +++ b/index.d.ts @@ -2,7 +2,7 @@ import { serializedNodeWithId, idNodeMap } from './src/types'; export * from './src/types'; export function snapshot(n: Document): [serializedNodeWithId | null, idNodeMap]; -export function rebuild(n: serializedNodeWithId): [Node | null, idNodeMap]; +export function rebuild(n: serializedNodeWithId): Node | null; export function serializeNodeWithId( n: Node, doc: Document, diff --git a/src/rebuild.ts b/src/rebuild.ts index 1302926284..223e3be894 100644 --- a/src/rebuild.ts +++ b/src/rebuild.ts @@ -1,11 +1,4 @@ -import { - serializedNodeWithId, - NodeType, - tagMap, - elementNode, - idNodeMap, - INode, -} from './types'; +import { serializedNodeWithId, NodeType, tagMap, elementNode } from './types'; const tagMap: tagMap = { script: 'noscript', @@ -61,16 +54,17 @@ function buildNode(n: serializedNodeWithId): Node | null { } } -function _rebuild(n: serializedNodeWithId, map: idNodeMap): Node | null { +function rebuild(n: serializedNodeWithId): Node | null { const root = buildNode(n); if (!root) { return null; } - (root as INode).__sn = n; - map[n.id] = root as INode; + if (n.type === NodeType.Element) { + (root as HTMLElement).setAttribute('data-rrid', String(n.id)); + } if (n.type === NodeType.Document || n.type === NodeType.Element) { for (const childN of n.childNodes) { - const childNode = _rebuild(childN, map); + const childNode = rebuild(childN); if (!childNode) { console.warn('Failed to rebuild', childN); } else { @@ -81,9 +75,4 @@ function _rebuild(n: serializedNodeWithId, map: idNodeMap): Node | null { return root; } -function rebuild(n: serializedNodeWithId): [Node | null, idNodeMap] { - const idNodeMap: idNodeMap = {}; - return [_rebuild(n, idNodeMap), idNodeMap]; -} - export default rebuild; From 3e5c0adcdc3d5e2bc6f0656410ca0c0c9ee13f77 Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Fri, 12 Oct 2018 16:28:06 +0800 Subject: [PATCH 018/524] use jest-snapshot to apply the snapshot testing --- package.json | 1 + test.d.ts | 17 ++++ test/__snapshots__/integration.ts.snap | 133 +++++++++++++++++++++++++ test/html/form-fields.html | 38 ------- test/html/invalid-attribute.html | 6 -- test/html/with-script.html | 19 ---- test/html/with-style-sheet.html | 19 ---- test/integration.ts | 44 ++++---- 8 files changed, 172 insertions(+), 105 deletions(-) create mode 100644 test/__snapshots__/integration.ts.snap diff --git a/package.json b/package.json index 0c399ca927..119a44c056 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "@types/node": "^10.11.3", "@types/puppeteer": "^1.8.0", "chai": "^4.1.2", + "jest-snapshot": "^23.6.0", "mocha": "^5.2.0", "puppeteer": "^1.9.0", "rollup": "^0.66.4", diff --git a/test.d.ts b/test.d.ts index cbe3deb631..a3b614eedb 100644 --- a/test.d.ts +++ b/test.d.ts @@ -2,3 +2,20 @@ declare module 'rollup-plugin-typescript' { function typescript(): any; export = typescript; } + +declare module 'jest-snapshot' { + export class SnapshotState { + constructor(testFile: string, options: any); + + save(): any; + } + type matchResult = { + pass: boolean; + report(): string; + }; + export function toMatchSnapshot( + received: any, + propertyMatchers?: any, + testName?: string, + ): matchResult; +} diff --git a/test/__snapshots__/integration.ts.snap b/test/__snapshots__/integration.ts.snap new file mode 100644 index 0000000000..6aba1b5e53 --- /dev/null +++ b/test/__snapshots__/integration.ts.snap @@ -0,0 +1,133 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`[html file]: about-mozilla.html 1`] = ` +" + The Book of Mozilla, 11:9 + +

+ Mammon slept. And the beast reborn spread over the earth and its numbers + grew legion. And they proclaimed the times and sacrificed crops unto the + fire, with the cunning of foxes. And they built a new world in their own + image as promised by the + sacred words, and spoke + of the beast with their children. Mammon awoke, and lo! it was + naught but a follower. +

+ from The Book of Mozilla, 11:9
(10th Edition) +

" +`; + +exports[`[html file]: basic.html 1`] = ` +" + + + + Document +" +`; + +exports[`[html file]: cors-style-sheet.html 1`] = ` +" + + + + with style sheet + +" +`; + +exports[`[html file]: form-fields.html 1`] = ` +" + + + + form fields + +
+ + + + + +
+" +`; + +exports[`[html file]: iframe.html 1`] = ` +" + + + + iframe + + + +" +`; + +exports[`[html file]: iframe-inner.html 1`] = ` +" +" +`; + +exports[`[html file]: invalid-attribute.html 1`] = ` +" +" +`; + +exports[`[html file]: with-script.html 1`] = ` +" + + + + with script + + + " +`; + +exports[`[html file]: with-style-sheet.html 1`] = ` +" + + + + with style sheet + + +" +`; diff --git a/test/html/form-fields.html b/test/html/form-fields.html index 6eef35449e..50778d603b 100644 --- a/test/html/form-fields.html +++ b/test/html/form-fields.html @@ -39,41 +39,3 @@ - - - - - - - - - - - form fields - - - -
- - - - - -
- - - - \ No newline at end of file diff --git a/test/html/invalid-attribute.html b/test/html/invalid-attribute.html index 6fa84ad4c0..e2428e2888 100644 --- a/test/html/invalid-attribute.html +++ b/test/html/invalid-attribute.html @@ -1,9 +1,3 @@ - - - - - - \ No newline at end of file diff --git a/test/html/with-script.html b/test/html/with-script.html index d727133827..b4812e96b2 100644 --- a/test/html/with-script.html +++ b/test/html/with-script.html @@ -16,22 +16,3 @@ - - - - - - - - - - - with script - - - - - - - - \ No newline at end of file diff --git a/test/html/with-style-sheet.html b/test/html/with-style-sheet.html index 9ba3c5e4d2..2083dae96f 100644 --- a/test/html/with-style-sheet.html +++ b/test/html/with-style-sheet.html @@ -14,22 +14,3 @@ - - - - - - - - - - - with style sheet - - - - - - - - \ No newline at end of file diff --git a/test/integration.ts b/test/integration.ts index 13647cc8ad..861c6580f1 100644 --- a/test/integration.ts +++ b/test/integration.ts @@ -6,23 +6,15 @@ import 'mocha'; import * as puppeteer from 'puppeteer'; import * as rollup from 'rollup'; import typescript = require('rollup-plugin-typescript'); -import { expect } from 'chai'; +import { assert } from 'chai'; +import { SnapshotState, toMatchSnapshot } from 'jest-snapshot'; const htmlFolder = path.join(__dirname, 'html'); const htmls = fs.readdirSync(htmlFolder).map(filePath => { const raw = fs.readFileSync(path.resolve(htmlFolder, filePath), 'utf-8'); - if (//.test(raw)) { - const [src, dest] = raw.split(''); - return { - filePath, - src, - dest, - }; - } return { filePath, src: raw, - dest: raw, }; }); @@ -60,6 +52,20 @@ const server = () => }); }); +function matchSnapshot(actual: string, testFile: string, testTitle: string) { + const snapshotState = new SnapshotState(testFile, { + updateSnapshot: process.env.SNAPSHOT_UPDATE ? 'all' : 'new', + }); + + const matcher = toMatchSnapshot.bind({ + snapshotState, + currentTestName: testTitle, + }); + const result = matcher(actual); + snapshotState.save(); + return result; +} + describe('integration tests', () => { before(async () => { this.server = await server(); @@ -85,29 +91,21 @@ describe('integration tests', () => { }); for (const html of htmls.slice(0, 10)) { - it('[html file]: ' + html.filePath, async () => { + const title = '[html file]: ' + html.filePath; + it(title, async () => { const page: puppeteer.Page = await this.browser.newPage(); // console for debug // tslint:disable-next-line: no-console page.on('console', msg => console.log(msg.text())); await page.goto(`http://localhost:3030/html`); await page.setContent(html.src); - await page.evaluate(() => { - const x = new XMLSerializer(); - return x.serializeToString(document); - }); const rebuildHtml = (await page.evaluate(`${this.code} const x = new XMLSerializer(); const [snap] = rrweb.snapshot(document); - x.serializeToString(rrweb.rebuild(snap)[0]); + x.serializeToString(rrweb.rebuild(snap)); `)).replace(/\n\n/g, ''); - await page.goto(`http://localhost:3030/html`); - await page.setContent(html.dest); - const destHtml = (await page.evaluate(() => { - const x = new XMLSerializer(); - return x.serializeToString(document); - })).replace(/\n\n/g, ''); - expect(rebuildHtml).to.equal(destHtml); + const result = matchSnapshot(rebuildHtml, __filename, title); + assert(result.pass, result.pass ? '' : result.report()); }).timeout(5000); } }); From eef6a6e3899e7dc79c2502ade0931f09e4483d8b Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Tue, 16 Oct 2018 12:11:00 +0800 Subject: [PATCH 019/524] change relative path into absolute path --- README.md | 5 ---- src/snapshot.ts | 38 ++++++++++++++++++++++++-- test/__snapshots__/integration.ts.snap | 18 ++++++++++-- test/css/style.css | 2 ++ test/html/with-relative-res.html | 13 +++++++++ 5 files changed, 66 insertions(+), 10 deletions(-) create mode 100644 test/html/with-relative-res.html diff --git a/README.md b/README.md index d61b9f71d6..854d85b921 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,3 @@ Snapshot the DOM into a stateful and serializable data structure. Also provide the ability to rebuild the DOM via snapshot. - -## TODO - -- [ ] Replace any url in css rules into absolute path. -- [ ] Select a suitable build strategy. diff --git a/src/snapshot.ts b/src/snapshot.ts index 04eddcf3a3..e4527e9297 100644 --- a/src/snapshot.ts +++ b/src/snapshot.ts @@ -28,6 +28,35 @@ function getCssRulesString(s: CSSStyleSheet): string | null { } } +const URL_IN_CSS_REF = /url\((['"])([^'"]*)\1\)/gm; +function absoluteToStylesheet(cssText: string, href: string): string { + return cssText.replace(URL_IN_CSS_REF, (_1, _2, filePath) => { + const stack = href.split('/'); + const parts = filePath.split('/'); + stack.pop(); + for (const part of parts) { + if (part === '.') { + continue; + } else if (part === '..') { + stack.pop(); + } else { + stack.push(part); + } + } + return `url('${stack.join('/')}')`; + }); +} + +const RELATIVE_PATH = /^(\.\.|\.|)\//; +function absoluteToDoc(doc: Document, attributeValue: string): string { + if (!RELATIVE_PATH.test(attributeValue)) { + return attributeValue; + } + const a: HTMLAnchorElement = document.createElement('a'); + a.href = attributeValue; + return a.href; +} + function serializeNode(n: Node, doc: Document): serializedNode | false { switch (n.nodeType) { case n.DOCUMENT_NODE: @@ -46,7 +75,12 @@ function serializeNode(n: Node, doc: Document): serializedNode | false { const tagName = (n as HTMLElement).tagName.toLowerCase(); let attributes: attributes = {}; for (const { name, value } of Array.from((n as HTMLElement).attributes)) { - attributes[name] = value; + // relative path in attribute + if (name === 'src' || name === 'href') { + attributes[name] = absoluteToDoc(doc, value); + } else { + attributes[name] = value; + } } // remote css if (tagName === 'link') { @@ -56,7 +90,7 @@ function serializeNode(n: Node, doc: Document): serializedNode | false { const cssText = getCssRulesString(stylesheet as CSSStyleSheet); if (cssText) { attributes = { - _cssText: cssText, + _cssText: absoluteToStylesheet(cssText, stylesheet!.href!), }; } } diff --git a/test/__snapshots__/integration.ts.snap b/test/__snapshots__/integration.ts.snap index 6aba1b5e53..45ae353eca 100644 --- a/test/__snapshots__/integration.ts.snap +++ b/test/__snapshots__/integration.ts.snap @@ -96,7 +96,7 @@ exports[`[html file]: iframe.html 1`] = ` iframe - + " `; @@ -110,6 +110,18 @@ exports[`[html file]: invalid-attribute.html 1`] = ` " `; +exports[`[html file]: with-relative-res.html 1`] = ` +" + + + + Document + + + + \\"\\"" +`; + exports[`[html file]: with-script.html 1`] = ` " @@ -117,7 +129,7 @@ exports[`[html file]: with-script.html 1`] = ` with script - + " `; @@ -127,7 +139,7 @@ exports[`[html file]: with-style-sheet.html 1`] = ` with style sheet - + " `; diff --git a/test/css/style.css b/test/css/style.css index f1be9954d9..fe10f55d70 100644 --- a/test/css/style.css +++ b/test/css/style.css @@ -1,8 +1,10 @@ body { margin: 0; + background: url('../a.jpg'); } p { color: red; + background: url('./b.jpg'); } body > p { color: yellow; diff --git a/test/html/with-relative-res.html b/test/html/with-relative-res.html new file mode 100644 index 0000000000..9e75f035c1 --- /dev/null +++ b/test/html/with-relative-res.html @@ -0,0 +1,13 @@ + + + + + + + Document + + + + + + \ No newline at end of file From 0eedab53eb1cc484ffeda8ae435e290c3df7cc28 Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Tue, 16 Oct 2018 12:12:31 +0800 Subject: [PATCH 020/524] bump 0.3.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 119a44c056..da1d93dc2a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rrweb-snapshot", - "version": "0.3.0", + "version": "0.3.1", "description": "rrweb's component to take a snapshot of DOM, aka DOM serializer", "main": "dist/index.js", "module": "dist/module.js", From e461136f7101cc03337cb8ce26195098274b2eef Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Tue, 16 Oct 2018 15:18:07 +0800 Subject: [PATCH 021/524] impl the extra child data attribute to align id map --- src/rebuild.ts | 9 +++++++++ src/snapshot.ts | 4 ++-- test/__snapshots__/integration.ts.snap | 8 ++++---- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/rebuild.ts b/src/rebuild.ts index 223e3be894..4e61283e48 100644 --- a/src/rebuild.ts +++ b/src/rebuild.ts @@ -24,6 +24,7 @@ function buildNode(n: serializedNodeWithId): Node | null { case NodeType.Element: const tagName = getTagName(n); const node = document.createElement(tagName); + const extraChildIndexes: number[] = []; for (const name in n.attributes) { if (n.attributes.hasOwnProperty(name)) { let value = n.attributes[name]; @@ -32,6 +33,8 @@ function buildNode(n: serializedNodeWithId): Node | null { const isRemoteCss = tagName === 'style' && name === '_cssText'; if (isTextarea || isRemoteCss) { const child = document.createTextNode(value); + // identify the extra child DOM we added when rebuild + extraChildIndexes.push(node.childNodes.length); node.appendChild(child); continue; } @@ -42,6 +45,12 @@ function buildNode(n: serializedNodeWithId): Node | null { } } } + if (extraChildIndexes.length) { + node.setAttribute( + 'data-extra-child-index', + JSON.stringify(extraChildIndexes), + ); + } return node; case NodeType.Text: return document.createTextNode(n.textContent); diff --git a/src/snapshot.ts b/src/snapshot.ts index e4527e9297..fa3aea8cb3 100644 --- a/src/snapshot.ts +++ b/src/snapshot.ts @@ -52,7 +52,7 @@ function absoluteToDoc(doc: Document, attributeValue: string): string { if (!RELATIVE_PATH.test(attributeValue)) { return attributeValue; } - const a: HTMLAnchorElement = document.createElement('a'); + const a: HTMLAnchorElement = doc.createElement('a'); a.href = attributeValue; return a.href; } @@ -130,7 +130,7 @@ function serializeNode(n: Node, doc: Document): serializedNode | false { n.parentNode && (n.parentNode as HTMLElement).tagName; let textContent = (n as Text).textContent; if (parentTagName === 'SCRIPT') { - textContent = ''; + textContent = 'SCRIPT_PLACEHOLDER'; } return { type: NodeType.Text, diff --git a/test/__snapshots__/integration.ts.snap b/test/__snapshots__/integration.ts.snap index 45ae353eca..87f1446e87 100644 --- a/test/__snapshots__/integration.ts.snap +++ b/test/__snapshots__/integration.ts.snap @@ -76,7 +76,7 @@ exports[`[html file]: form-fields.html 1`] = ` - + " `; @@ -130,7 +130,7 @@ exports[`[html file]: with-script.html 1`] = ` with script - " + " `; exports[`[html file]: with-style-sheet.html 1`] = ` @@ -139,7 +139,7 @@ exports[`[html file]: with-style-sheet.html 1`] = ` with style sheet - + " `; From 71932ee530bc7e9fe6117c597cb139618f62d089 Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Tue, 16 Oct 2018 17:53:35 +0800 Subject: [PATCH 022/524] update README and add travis --- .travis.yml | 14 ++++++++++++++ README.md | 32 ++++++++++++++++++++++++++++++++ test/integration.ts | 1 - 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..55653dd1d7 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,14 @@ +language: node_js + +node_js: + - 10 + +cache: + directories: + - 'node_modules' + +install: + - npm install + +script: + - npm test diff --git a/README.md b/README.md index 854d85b921..1dcd2adac9 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,36 @@ # rrweb-snapshot +[![Build Status](https://travis-ci.org/rrweb-io/rrweb-snapshot.svg?branch=master)](https://travis-ci.org/rrweb-io/rrweb-snapshot) + Snapshot the DOM into a stateful and serializable data structure. Also provide the ability to rebuild the DOM via snapshot. + +## API + +This module export 3 methods: + +### snapshot + +`snapshot` will traverse the DOM and return a stateful and serializable data structure which can represent the current DOM **view**. + +There are serveral things will be done during snapshot: + +1. Inline some DOM states into HTML attributes, e.g, HTMLInputElement's value. +2. Turn script tags into noscript tags to avoid scripts being executed. +3. Try to inline stylesheets to make sure local stylesheets can be used. +4. Make relative paths in href, src, css to be absolute paths. +5. Give a id to each Node, and return the id node map when snapshot finished. + +#### rebuild + +`rebuild` will build the DOM according to the taken snapshot. + +There are serveral things will be done during rebuild: + +1. Add data-rrid attribute if Node is an Element. +2. Create some extra DOM node like text node to place inline css and some states. +3. Add data-extra-child-index attribute if Node has some extra child DOM. + +#### serializeNodeWithId + +`serializeNodeWithId` can serialize a node into snapshot format with id. diff --git a/test/integration.ts b/test/integration.ts index 861c6580f1..700469f2ea 100644 --- a/test/integration.ts +++ b/test/integration.ts @@ -71,7 +71,6 @@ describe('integration tests', () => { this.server = await server(); this.browser = await puppeteer.launch({ // headless: false, - executablePath: '/home/yanzhen/Desktop/chrome-linux/chrome', }); const bundle = await rollup.rollup({ From fade2df5d46fc974570eb8d34730dcf1b85d1ebb Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Tue, 16 Oct 2018 18:00:24 +0800 Subject: [PATCH 023/524] bump 0.4.0 --- .travis.yml | 4 ---- package.json | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 55653dd1d7..26cef21f03 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,10 +3,6 @@ language: node_js node_js: - 10 -cache: - directories: - - 'node_modules' - install: - npm install diff --git a/package.json b/package.json index da1d93dc2a..57db3613bc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rrweb-snapshot", - "version": "0.3.1", + "version": "0.4.0", "description": "rrweb's component to take a snapshot of DOM, aka DOM serializer", "main": "dist/index.js", "module": "dist/module.js", From 72beb51110a8782b66354dee22c5332d67d61c07 Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Tue, 16 Oct 2018 18:09:51 +0800 Subject: [PATCH 024/524] fix npm package files and bump version --- package.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 57db3613bc..6f32f4e480 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rrweb-snapshot", - "version": "0.4.0", + "version": "0.4.2", "description": "rrweb's component to take a snapshot of DOM, aka DOM serializer", "main": "dist/index.js", "module": "dist/module.js", @@ -18,7 +18,9 @@ "DOM" ], "files": [ - "dist" + "dist", + "index.d.ts", + "src/types.ts" ], "author": "yanzhen@smartx.com", "license": "MIT", From 2eed038e6b3c63d022ea751f742c5fd03b67b40d Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Wed, 17 Oct 2018 12:06:18 +0800 Subject: [PATCH 025/524] init repo --- .gitignore | 7 +++++ .prettierrc | 4 +++ README.md | 70 +++++++++++++++++++++++++++++++++++++++++++++++ package.json | 21 ++++++++++++++ public/global.css | 61 +++++++++++++++++++++++++++++++++++++++++ public/index.html | 16 +++++++++++ rollup.config.js | 43 +++++++++++++++++++++++++++++ src/App.html | 17 ++++++++++++ src/Player.html | 17 ++++++++++++ src/main.js | 10 +++++++ 10 files changed, 266 insertions(+) create mode 100644 .gitignore create mode 100644 .prettierrc create mode 100644 README.md create mode 100644 package.json create mode 100644 public/global.css create mode 100644 public/index.html create mode 100644 rollup.config.js create mode 100644 src/App.html create mode 100644 src/Player.html create mode 100644 src/main.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..49acba0037 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +node_modules +public/bundle.* +package-lock.json +yarn.lock + +.vscode diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000000..a20502b7f0 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,4 @@ +{ + "singleQuote": true, + "trailingComma": "all" +} diff --git a/README.md b/README.md new file mode 100644 index 0000000000..3e411bf696 --- /dev/null +++ b/README.md @@ -0,0 +1,70 @@ +*Psst — looking for a shareable component template? Go here --> [sveltejs/component-template](https://github.com/sveltejs/component-template)* + +--- + +# svelte app + +This is a project template for [Svelte](https://svelte.technology) apps. It lives at https://github.com/sveltejs/template. + +To create a new project based on this template using [degit](https://github.com/Rich-Harris/degit): + +```bash +npm install -g degit # you only need to do this once + +degit sveltejs/template svelte-app +cd svelte-app +``` + +*Note that you will need to have [Node.js](https://nodejs.org) installed.* + + +## Get started + +Install the dependencies... + +```bash +cd svelte-app +npm install +``` + +...then start [Rollup](https://rollupjs.org): + +```bash +npm run dev +``` + +Navigate to [localhost:5000](http://localhost:5000). You should see your app running. Edit a component file in `src`, save it, and reload the page to see your changes. + + +## Deploying to the web + +### With [now](https://zeit.co/now) + +Install `now` if you haven't already: + +```bash +npm install -g now +``` + +Then, from within your project folder: + +```bash +now +``` + +As an alternative, use the [Now desktop client](https://zeit.co/download) and simply drag the unzipped project folder to the taskbar icon. + +### With [surge](https://surge.sh/) + +Install `surge` if you haven't already: + +```bash +npm install -g surge +``` + +Then, from within your project folder: + +```bash +npm run build +surge public +``` diff --git a/package.json b/package.json new file mode 100644 index 0000000000..b07af65f87 --- /dev/null +++ b/package.json @@ -0,0 +1,21 @@ +{ + "name": "rrweb-player", + "version": "0.1.0", + "devDependencies": { + "npm-run-all": "^4.1.3", + "rollup": "^0.66.2", + "rollup-plugin-commonjs": "^9.1.8", + "rollup-plugin-node-resolve": "^3.4.0", + "rollup-plugin-svelte": "^4.3.1", + "rollup-plugin-terser": "^3.0.0", + "sirv-cli": "^0.2.2", + "svelte": "^2.13.5" + }, + "scripts": { + "build": "rollup -c", + "autobuild": "rollup -c -w", + "dev": "run-p start:dev autobuild", + "start": "sirv public", + "start:dev": "sirv public --dev" + } +} \ No newline at end of file diff --git a/public/global.css b/public/global.css new file mode 100644 index 0000000000..9d682a3961 --- /dev/null +++ b/public/global.css @@ -0,0 +1,61 @@ +html, body { + position: relative; + width: 100%; + height: 100%; +} + +body { + color: #333; + margin: 0; + padding: 8px; + box-sizing: border-box; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; +} + +a { + color: rgb(0,100,200); + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +a:visited { + color: rgb(0,80,160); +} + +label { + display: block; +} + +input, button, select, textarea { + font-family: inherit; + font-size: inherit; + padding: 0.4em; + margin: 0 0 0.5em 0; + box-sizing: border-box; + border: 1px solid #ccc; + border-radius: 2px; +} + +input:disabled { + color: #ccc; +} + +input[type="range"] { + height: 0; +} + +button { + background-color: #f4f4f4; + outline: none; +} + +button:active { + background-color: #ddd; +} + +button:focus { + border-color: #666; +} \ No newline at end of file diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000000..6bb5adc070 --- /dev/null +++ b/public/index.html @@ -0,0 +1,16 @@ + + + + + + + Svelte app + + + + + + + + + \ No newline at end of file diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 0000000000..d9aa427843 --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,43 @@ +import svelte from 'rollup-plugin-svelte'; +import resolve from 'rollup-plugin-node-resolve'; +import commonjs from 'rollup-plugin-commonjs'; +import { terser } from 'rollup-plugin-terser'; + +const production = !process.env.ROLLUP_WATCH; + +export default { + input: 'src/main.js', + output: { + sourcemap: true, + format: 'iife', + name: 'app', + file: 'public/bundle.js' + }, + plugins: [ + svelte({ + // opt in to v3 behaviour today + skipIntroByDefault: true, + nestedTransitions: true, + + // enable run-time checks when not in production + dev: !production, + // we'll extract any component CSS out into + // a separate file — better for performance + css: css => { + css.write('public/bundle.css'); + } + }), + + // If you have external dependencies installed from + // npm, you'll most likely need these plugins. In + // some cases you'll need additional configuration — + // consult the documentation for details: + // https://github.com/rollup/rollup-plugin-commonjs + resolve(), + commonjs(), + + // If we're building for production (npm run build + // instead of npm run dev), minify + production && terser() + ] +}; diff --git a/src/App.html b/src/App.html new file mode 100644 index 0000000000..140cf9d3c4 --- /dev/null +++ b/src/App.html @@ -0,0 +1,17 @@ +

+ rrweb player playground +

+ + + + + \ No newline at end of file diff --git a/src/Player.html b/src/Player.html new file mode 100644 index 0000000000..719e03a7b0 --- /dev/null +++ b/src/Player.html @@ -0,0 +1,17 @@ +
+ rrplayer +
+ + + + diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000000..c804ceec1e --- /dev/null +++ b/src/main.js @@ -0,0 +1,10 @@ +import App from './App.html'; + +const app = new App({ + target: document.body, + data: { + name: 'world' + } +}); + +export default app; \ No newline at end of file From 904cc493dbac611bd194aa31a4407052211fc16f Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Wed, 17 Oct 2018 14:14:44 +0800 Subject: [PATCH 026/524] add eslint --- .eslintrc.json | 13 +++++++++++++ package.json | 5 ++++- src/App.html | 15 +++++++-------- src/Player.html | 24 +++++++++++++++++++----- src/main.js | 10 +++++----- src/util.js | 7 +++++++ 6 files changed, 55 insertions(+), 19 deletions(-) create mode 100644 .eslintrc.json create mode 100644 src/util.js diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000000..b066720dc3 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,13 @@ +{ + "extends": "google", + "parserOptions": { + "ecmaVersion": 7, + "sourceType": "module" + }, + "rules": { + "require-jsdoc": "off", + "arrow-parens": "off", + "object-curly-spacing": "off" + }, + "plugins": ["html"] +} diff --git a/package.json b/package.json index b07af65f87..75368a6ae0 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,9 @@ "name": "rrweb-player", "version": "0.1.0", "devDependencies": { + "eslint": "^5.7.0", + "eslint-config-google": "^0.11.0", + "eslint-plugin-html": "^4.0.6", "npm-run-all": "^4.1.3", "rollup": "^0.66.2", "rollup-plugin-commonjs": "^9.1.8", @@ -18,4 +21,4 @@ "start": "sirv public", "start:dev": "sirv public --dev" } -} \ No newline at end of file +} diff --git a/src/App.html b/src/App.html index 140cf9d3c4..73363aecbe 100644 --- a/src/App.html +++ b/src/App.html @@ -1,5 +1,5 @@

- rrweb player playground + rrweb player playground

@@ -7,11 +7,10 @@

\ No newline at end of file diff --git a/src/Player.html b/src/Player.html index 719e03a7b0..edabdbb1ce 100644 --- a/src/Player.html +++ b/src/Player.html @@ -1,4 +1,4 @@ -
+
rrplayer
@@ -9,9 +9,23 @@ + return { + width: 1024, + height: 576, + }; + }, + computed: { + style({ width, height }) { + return inlineCss({ + width: `${width}px`, + height: `${height}px`, + }); + }, + }, + }; + + \ No newline at end of file diff --git a/src/main.js b/src/main.js index c804ceec1e..9263290175 100644 --- a/src/main.js +++ b/src/main.js @@ -1,10 +1,10 @@ import App from './App.html'; const app = new App({ - target: document.body, - data: { - name: 'world' - } + target: document.body, + data: { + name: 'world', + }, }); -export default app; \ No newline at end of file +export default app; diff --git a/src/util.js b/src/util.js new file mode 100644 index 0000000000..da07ec1932 --- /dev/null +++ b/src/util.js @@ -0,0 +1,7 @@ +export function inlineCss(cssObj) { + let style = ''; + Object.keys(cssObj).forEach(key => { + style += `${key}: ${cssObj[key]};`; + }); + return style; +} From f97c829a7dbbc412b48e2f8720637765ec2f1f7e Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Wed, 17 Oct 2018 15:45:02 +0800 Subject: [PATCH 027/524] attach the scaled iframe into player --- .gitignore | 1 + package.json | 3 +++ rollup.config.js | 62 ++++++++++++++++++++++---------------------- src/App.html | 3 ++- src/Player.html | 67 +++++++++++++++++++++++++++++++++++++++++++++--- src/main.js | 7 ++++- 6 files changed, 106 insertions(+), 37 deletions(-) diff --git a/.gitignore b/.gitignore index 49acba0037..7be014c58f 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ package-lock.json yarn.lock .vscode +temp diff --git a/package.json b/package.json index 75368a6ae0..c3d94cf6f2 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,9 @@ "sirv-cli": "^0.2.2", "svelte": "^2.13.5" }, + "dependencies": { + "rrweb": "file:../rrweb" + }, "scripts": { "build": "rollup -c", "autobuild": "rollup -c -w", diff --git a/rollup.config.js b/rollup.config.js index d9aa427843..e48c8da129 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -6,38 +6,38 @@ import { terser } from 'rollup-plugin-terser'; const production = !process.env.ROLLUP_WATCH; export default { - input: 'src/main.js', - output: { - sourcemap: true, - format: 'iife', - name: 'app', - file: 'public/bundle.js' - }, - plugins: [ - svelte({ - // opt in to v3 behaviour today - skipIntroByDefault: true, - nestedTransitions: true, + input: 'src/main.js', + output: { + sourcemap: true, + format: 'iife', + name: 'app', + file: 'public/bundle.js', + }, + plugins: [ + svelte({ + // opt in to v3 behaviour today + skipIntroByDefault: true, + nestedTransitions: true, - // enable run-time checks when not in production - dev: !production, - // we'll extract any component CSS out into - // a separate file — better for performance - css: css => { - css.write('public/bundle.css'); - } - }), + // enable run-time checks when not in production + dev: !production, + // we'll extract any component CSS out into + // a separate file — better for performance + css: css => { + css.write('public/bundle.css'); + }, + }), - // If you have external dependencies installed from - // npm, you'll most likely need these plugins. In - // some cases you'll need additional configuration — - // consult the documentation for details: - // https://github.com/rollup/rollup-plugin-commonjs - resolve(), - commonjs(), + // If you have external dependencies installed from + // npm, you'll most likely need these plugins. In + // some cases you'll need additional configuration — + // consult the documentation for details: + // https://github.com/rollup/rollup-plugin-commonjs + resolve(), + commonjs(), - // If we're building for production (npm run build - // instead of npm run dev), minify - production && terser() - ] + // If we're building for production (npm run build + // instead of npm run dev), minify + production && terser(), + ], }; diff --git a/src/App.html b/src/App.html index 73363aecbe..c54fde621a 100644 --- a/src/App.html +++ b/src/App.html @@ -1,13 +1,14 @@

rrweb player playground

- + \ No newline at end of file diff --git a/src/main.js b/src/main.js index 9263290175..e69387f863 100644 --- a/src/main.js +++ b/src/main.js @@ -1,9 +1,14 @@ import App from './App.html'; +const events = + // prettier-ignore + // eslint-disable-next-line + [{"type":0,"data":{"href":"http://127.0.0.1:5500/checkout-demo/index.html?"},"timestamp":1539674870305},{"type":1,"data":{"width":1173,"height":711},"timestamp":1539674870317},{"type":2,"data":{"node":{"type":0,"childNodes":[{"type":1,"name":"html","publicId":"","systemId":"","id":2},{"type":5,"textContent":" saved from url=(0052)https://getbootstrap.com/docs/4.1/examples/checkout/ ","id":3},{"type":2,"tagName":"html","attributes":{"lang":"en"},"childNodes":[{"type":2,"tagName":"head","attributes":{},"childNodes":[{"type":3,"textContent":"\n ","id":6},{"type":2,"tagName":"meta","attributes":{"http-equiv":"Content-Type","content":"text/html; charset=UTF-8"},"childNodes":[],"id":7},{"type":3,"textContent":"\n\n ","id":8},{"type":2,"tagName":"meta","attributes":{"name":"viewport","content":"width=device-width, initial-scale=1, shrink-to-fit=no"},"childNodes":[],"id":9},{"type":3,"textContent":"\n ","id":10},{"type":2,"tagName":"meta","attributes":{"name":"description","content":""},"childNodes":[],"id":11},{"type":3,"textContent":"\n ","id":12},{"type":2,"tagName":"meta","attributes":{"name":"author","content":""},"childNodes":[],"id":13},{"type":3,"textContent":"\n ","id":14},{"type":2,"tagName":"link","attributes":{"rel":"icon","href":"https://getbootstrap.com/favicon.ico"},"childNodes":[],"id":15},{"type":3,"textContent":"\n\n ","id":16},{"type":2,"tagName":"title","attributes":{},"childNodes":[{"type":3,"textContent":"Checkout example for Bootstrap","id":18}],"id":17},{"type":3,"textContent":"\n\n ","id":19},{"type":5,"textContent":" Bootstrap core CSS ","id":20},{"type":3,"textContent":"\n ","id":21},{"type":2,"tagName":"link","attributes":{"_cssText":":root { --blue:#007bff; --indigo:#6610f2; --purple:#6f42c1; --pink:#e83e8c; --red:#dc3545; --orange:#fd7e14; --yellow:#ffc107; --green:#28a745; --teal:#20c997; --cyan:#17a2b8; --white:#fff; --gray:#6c757d; --gray-dark:#343a40; --primary:#007bff; --secondary:#6c757d; --success:#28a745; --info:#17a2b8; --warning:#ffc107; --danger:#dc3545; --light:#f8f9fa; --dark:#343a40; --breakpoint-xs:0; --breakpoint-sm:576px; --breakpoint-md:768px; --breakpoint-lg:992px; --breakpoint-xl:1200px; --font-family-sans-serif:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\",\"Noto Color Emoji\"; --font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace; }*, ::after, ::before { box-sizing: border-box; }html { font-family: sans-serif; line-height: 1.15; text-size-adjust: 100%; -webkit-tap-highlight-color: transparent; }article, aside, figcaption, figure, footer, header, hgroup, main, nav, section { display: block; }body { margin: 0px; font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\"; font-size: 1rem; font-weight: 400; line-height: 1.5; color: rgb(33, 37, 41); text-align: left; background-color: rgb(255, 255, 255); }[tabindex=\"-1\"]:focus { outline: 0px !important; }hr { box-sizing: content-box; height: 0px; overflow: visible; }h1, h2, h3, h4, h5, h6 { margin-top: 0px; margin-bottom: 0.5rem; }p { margin-top: 0px; margin-bottom: 1rem; }abbr[data-original-title], abbr[title] { text-decoration: underline dotted; cursor: help; border-bottom: 0px; }address { margin-bottom: 1rem; font-style: normal; line-height: inherit; }dl, ol, ul { margin-top: 0px; margin-bottom: 1rem; }ol ol, ol ul, ul ol, ul ul { margin-bottom: 0px; }dt { font-weight: 700; }dd { margin-bottom: 0.5rem; margin-left: 0px; }blockquote { margin: 0px 0px 1rem; }dfn { font-style: italic; }b, strong { font-weight: bolder; }small { font-size: 80%; }sub, sup { position: relative; font-size: 75%; line-height: 0; vertical-align: baseline; }sub { bottom: -0.25em; }sup { top: -0.5em; }a { color: rgb(0, 123, 255); text-decoration: none; background-color: transparent; }a:hover { color: rgb(0, 86, 179); text-decoration: underline; }a:not([href]):not([tabindex]) { color: inherit; text-decoration: none; }a:not([href]):not([tabindex]):focus, a:not([href]):not([tabindex]):hover { color: inherit; text-decoration: none; }a:not([href]):not([tabindex]):focus { outline: 0px; }code, kbd, pre, samp { font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; font-size: 1em; }pre { margin-top: 0px; margin-bottom: 1rem; overflow: auto; }figure { margin: 0px 0px 1rem; }img { vertical-align: middle; border-style: none; }svg { overflow: hidden; vertical-align: middle; }table { border-collapse: collapse; }caption { padding-top: 0.75rem; padding-bottom: 0.75rem; color: rgb(108, 117, 125); text-align: left; caption-side: bottom; }th { text-align: inherit; }label { display: inline-block; margin-bottom: 0.5rem; }button { border-radius: 0px; }button:focus { outline: -webkit-focus-ring-color auto 5px; }button, input, optgroup, select, textarea { margin: 0px; font-family: inherit; font-size: inherit; line-height: inherit; }button, input { overflow: visible; }button, select { text-transform: none; }[type=\"reset\"], [type=\"submit\"], button, html [type=\"button\"] { -webkit-appearance: button; }input[type=\"checkbox\"], input[type=\"radio\"] { box-sizing: border-box; padding: 0px; }input[type=\"date\"], input[type=\"datetime-local\"], input[type=\"month\"], input[type=\"time\"] { -webkit-appearance: listbox; }textarea { overflow: auto; resize: vertical; }fieldset { min-width: 0px; padding: 0px; margin: 0px; border: 0px; }legend { display: block; width: 100%; max-width: 100%; padding: 0px; margin-bottom: 0.5rem; font-size: 1.5rem; line-height: inherit; color: inherit; white-space: normal; }progress { vertical-align: baseline; }[type=\"number\"]::-webkit-inner-spin-button, [type=\"number\"]::-webkit-outer-spin-button { height: auto; }[type=\"search\"] { outline-offset: -2px; -webkit-appearance: none; }[type=\"search\"]::-webkit-search-cancel-button, [type=\"search\"]::-webkit-search-decoration { -webkit-appearance: none; }::-webkit-file-upload-button { font: inherit; -webkit-appearance: button; }output { display: inline-block; }summary { display: list-item; cursor: pointer; }template { display: none; }[hidden] { display: none !important; }.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 { margin-bottom: 0.5rem; font-family: inherit; font-weight: 500; line-height: 1.2; color: inherit; }.h1, h1 { font-size: 2.5rem; }.h2, h2 { font-size: 2rem; }.h3, h3 { font-size: 1.75rem; }.h4, h4 { font-size: 1.5rem; }.h5, h5 { font-size: 1.25rem; }.h6, h6 { font-size: 1rem; }.lead { font-size: 1.25rem; font-weight: 300; }.display-1 { font-size: 6rem; font-weight: 300; line-height: 1.2; }.display-2 { font-size: 5.5rem; font-weight: 300; line-height: 1.2; }.display-3 { font-size: 4.5rem; font-weight: 300; line-height: 1.2; }.display-4 { font-size: 3.5rem; font-weight: 300; line-height: 1.2; }hr { margin-top: 1rem; margin-bottom: 1rem; border-width: 1px 0px 0px; border-right-style: initial; border-bottom-style: initial; border-left-style: initial; border-right-color: initial; border-bottom-color: initial; border-left-color: initial; border-image: initial; border-top-style: solid; border-top-color: rgba(0, 0, 0, 0.1); }.small, small { font-size: 80%; font-weight: 400; }.mark, mark { padding: 0.2em; background-color: rgb(252, 248, 227); }.list-unstyled { padding-left: 0px; list-style: none; }.list-inline { padding-left: 0px; list-style: none; }.list-inline-item { display: inline-block; }.list-inline-item:not(:last-child) { margin-right: 0.5rem; }.initialism { font-size: 90%; text-transform: uppercase; }.blockquote { margin-bottom: 1rem; font-size: 1.25rem; }.blockquote-footer { display: block; font-size: 80%; color: rgb(108, 117, 125); }.blockquote-footer::before { content: \"— \"; }.img-fluid { max-width: 100%; height: auto; }.img-thumbnail { padding: 0.25rem; background-color: rgb(255, 255, 255); border: 1px solid rgb(222, 226, 230); border-radius: 0.25rem; max-width: 100%; height: auto; }.figure { display: inline-block; }.figure-img { margin-bottom: 0.5rem; line-height: 1; }.figure-caption { font-size: 90%; color: rgb(108, 117, 125); }code { font-size: 87.5%; color: rgb(232, 62, 140); word-break: break-word; }a > code { color: inherit; }kbd { padding: 0.2rem 0.4rem; font-size: 87.5%; color: rgb(255, 255, 255); background-color: rgb(33, 37, 41); border-radius: 0.2rem; }kbd kbd { padding: 0px; font-size: 100%; font-weight: 700; }pre { display: block; font-size: 87.5%; color: rgb(33, 37, 41); }pre code { font-size: inherit; color: inherit; word-break: normal; }.pre-scrollable { max-height: 340px; overflow-y: scroll; }.container { width: 100%; padding-right: 15px; padding-left: 15px; margin-right: auto; margin-left: auto; }@media (min-width: 576px) {\n .container { max-width: 540px; }\n}@media (min-width: 768px) {\n .container { max-width: 720px; }\n}@media (min-width: 992px) {\n .container { max-width: 960px; }\n}@media (min-width: 1200px) {\n .container { max-width: 1140px; }\n}.container-fluid { width: 100%; padding-right: 15px; padding-left: 15px; margin-right: auto; margin-left: auto; }.row { display: flex; flex-wrap: wrap; margin-right: -15px; margin-left: -15px; }.no-gutters { margin-right: 0px; margin-left: 0px; }.no-gutters > .col, .no-gutters > [class*=\"col-\"] { padding-right: 0px; padding-left: 0px; }.col, .col-1, .col-10, .col-11, .col-12, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-auto, .col-lg, .col-lg-1, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-auto, .col-md, .col-md-1, .col-md-10, .col-md-11, .col-md-12, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-auto, .col-sm, .col-sm-1, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-auto, .col-xl, .col-xl-1, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-auto { position: relative; width: 100%; min-height: 1px; padding-right: 15px; padding-left: 15px; }.col { flex-basis: 0px; flex-grow: 1; max-width: 100%; }.col-auto { flex: 0 0 auto; width: auto; max-width: none; }.col-1 { flex: 0 0 8.33333%; max-width: 8.33333%; }.col-2 { flex: 0 0 16.6667%; max-width: 16.6667%; }.col-3 { flex: 0 0 25%; max-width: 25%; }.col-4 { flex: 0 0 33.3333%; max-width: 33.3333%; }.col-5 { flex: 0 0 41.6667%; max-width: 41.6667%; }.col-6 { flex: 0 0 50%; max-width: 50%; }.col-7 { flex: 0 0 58.3333%; max-width: 58.3333%; }.col-8 { flex: 0 0 66.6667%; max-width: 66.6667%; }.col-9 { flex: 0 0 75%; max-width: 75%; }.col-10 { flex: 0 0 83.3333%; max-width: 83.3333%; }.col-11 { flex: 0 0 91.6667%; max-width: 91.6667%; }.col-12 { flex: 0 0 100%; max-width: 100%; }.order-first { order: -1; }.order-last { order: 13; }.order-0 { order: 0; }.order-1 { order: 1; }.order-2 { order: 2; }.order-3 { order: 3; }.order-4 { order: 4; }.order-5 { order: 5; }.order-6 { order: 6; }.order-7 { order: 7; }.order-8 { order: 8; }.order-9 { order: 9; }.order-10 { order: 10; }.order-11 { order: 11; }.order-12 { order: 12; }.offset-1 { margin-left: 8.33333%; }.offset-2 { margin-left: 16.6667%; }.offset-3 { margin-left: 25%; }.offset-4 { margin-left: 33.3333%; }.offset-5 { margin-left: 41.6667%; }.offset-6 { margin-left: 50%; }.offset-7 { margin-left: 58.3333%; }.offset-8 { margin-left: 66.6667%; }.offset-9 { margin-left: 75%; }.offset-10 { margin-left: 83.3333%; }.offset-11 { margin-left: 91.6667%; }@media (min-width: 576px) {\n .col-sm { flex-basis: 0px; flex-grow: 1; max-width: 100%; }\n .col-sm-auto { flex: 0 0 auto; width: auto; max-width: none; }\n .col-sm-1 { flex: 0 0 8.33333%; max-width: 8.33333%; }\n .col-sm-2 { flex: 0 0 16.6667%; max-width: 16.6667%; }\n .col-sm-3 { flex: 0 0 25%; max-width: 25%; }\n .col-sm-4 { flex: 0 0 33.3333%; max-width: 33.3333%; }\n .col-sm-5 { flex: 0 0 41.6667%; max-width: 41.6667%; }\n .col-sm-6 { flex: 0 0 50%; max-width: 50%; }\n .col-sm-7 { flex: 0 0 58.3333%; max-width: 58.3333%; }\n .col-sm-8 { flex: 0 0 66.6667%; max-width: 66.6667%; }\n .col-sm-9 { flex: 0 0 75%; max-width: 75%; }\n .col-sm-10 { flex: 0 0 83.3333%; max-width: 83.3333%; }\n .col-sm-11 { flex: 0 0 91.6667%; max-width: 91.6667%; }\n .col-sm-12 { flex: 0 0 100%; max-width: 100%; }\n .order-sm-first { order: -1; }\n .order-sm-last { order: 13; }\n .order-sm-0 { order: 0; }\n .order-sm-1 { order: 1; }\n .order-sm-2 { order: 2; }\n .order-sm-3 { order: 3; }\n .order-sm-4 { order: 4; }\n .order-sm-5 { order: 5; }\n .order-sm-6 { order: 6; }\n .order-sm-7 { order: 7; }\n .order-sm-8 { order: 8; }\n .order-sm-9 { order: 9; }\n .order-sm-10 { order: 10; }\n .order-sm-11 { order: 11; }\n .order-sm-12 { order: 12; }\n .offset-sm-0 { margin-left: 0px; }\n .offset-sm-1 { margin-left: 8.33333%; }\n .offset-sm-2 { margin-left: 16.6667%; }\n .offset-sm-3 { margin-left: 25%; }\n .offset-sm-4 { margin-left: 33.3333%; }\n .offset-sm-5 { margin-left: 41.6667%; }\n .offset-sm-6 { margin-left: 50%; }\n .offset-sm-7 { margin-left: 58.3333%; }\n .offset-sm-8 { margin-left: 66.6667%; }\n .offset-sm-9 { margin-left: 75%; }\n .offset-sm-10 { margin-left: 83.3333%; }\n .offset-sm-11 { margin-left: 91.6667%; }\n}@media (min-width: 768px) {\n .col-md { flex-basis: 0px; flex-grow: 1; max-width: 100%; }\n .col-md-auto { flex: 0 0 auto; width: auto; max-width: none; }\n .col-md-1 { flex: 0 0 8.33333%; max-width: 8.33333%; }\n .col-md-2 { flex: 0 0 16.6667%; max-width: 16.6667%; }\n .col-md-3 { flex: 0 0 25%; max-width: 25%; }\n .col-md-4 { flex: 0 0 33.3333%; max-width: 33.3333%; }\n .col-md-5 { flex: 0 0 41.6667%; max-width: 41.6667%; }\n .col-md-6 { flex: 0 0 50%; max-width: 50%; }\n .col-md-7 { flex: 0 0 58.3333%; max-width: 58.3333%; }\n .col-md-8 { flex: 0 0 66.6667%; max-width: 66.6667%; }\n .col-md-9 { flex: 0 0 75%; max-width: 75%; }\n .col-md-10 { flex: 0 0 83.3333%; max-width: 83.3333%; }\n .col-md-11 { flex: 0 0 91.6667%; max-width: 91.6667%; }\n .col-md-12 { flex: 0 0 100%; max-width: 100%; }\n .order-md-first { order: -1; }\n .order-md-last { order: 13; }\n .order-md-0 { order: 0; }\n .order-md-1 { order: 1; }\n .order-md-2 { order: 2; }\n .order-md-3 { order: 3; }\n .order-md-4 { order: 4; }\n .order-md-5 { order: 5; }\n .order-md-6 { order: 6; }\n .order-md-7 { order: 7; }\n .order-md-8 { order: 8; }\n .order-md-9 { order: 9; }\n .order-md-10 { order: 10; }\n .order-md-11 { order: 11; }\n .order-md-12 { order: 12; }\n .offset-md-0 { margin-left: 0px; }\n .offset-md-1 { margin-left: 8.33333%; }\n .offset-md-2 { margin-left: 16.6667%; }\n .offset-md-3 { margin-left: 25%; }\n .offset-md-4 { margin-left: 33.3333%; }\n .offset-md-5 { margin-left: 41.6667%; }\n .offset-md-6 { margin-left: 50%; }\n .offset-md-7 { margin-left: 58.3333%; }\n .offset-md-8 { margin-left: 66.6667%; }\n .offset-md-9 { margin-left: 75%; }\n .offset-md-10 { margin-left: 83.3333%; }\n .offset-md-11 { margin-left: 91.6667%; }\n}@media (min-width: 992px) {\n .col-lg { flex-basis: 0px; flex-grow: 1; max-width: 100%; }\n .col-lg-auto { flex: 0 0 auto; width: auto; max-width: none; }\n .col-lg-1 { flex: 0 0 8.33333%; max-width: 8.33333%; }\n .col-lg-2 { flex: 0 0 16.6667%; max-width: 16.6667%; }\n .col-lg-3 { flex: 0 0 25%; max-width: 25%; }\n .col-lg-4 { flex: 0 0 33.3333%; max-width: 33.3333%; }\n .col-lg-5 { flex: 0 0 41.6667%; max-width: 41.6667%; }\n .col-lg-6 { flex: 0 0 50%; max-width: 50%; }\n .col-lg-7 { flex: 0 0 58.3333%; max-width: 58.3333%; }\n .col-lg-8 { flex: 0 0 66.6667%; max-width: 66.6667%; }\n .col-lg-9 { flex: 0 0 75%; max-width: 75%; }\n .col-lg-10 { flex: 0 0 83.3333%; max-width: 83.3333%; }\n .col-lg-11 { flex: 0 0 91.6667%; max-width: 91.6667%; }\n .col-lg-12 { flex: 0 0 100%; max-width: 100%; }\n .order-lg-first { order: -1; }\n .order-lg-last { order: 13; }\n .order-lg-0 { order: 0; }\n .order-lg-1 { order: 1; }\n .order-lg-2 { order: 2; }\n .order-lg-3 { order: 3; }\n .order-lg-4 { order: 4; }\n .order-lg-5 { order: 5; }\n .order-lg-6 { order: 6; }\n .order-lg-7 { order: 7; }\n .order-lg-8 { order: 8; }\n .order-lg-9 { order: 9; }\n .order-lg-10 { order: 10; }\n .order-lg-11 { order: 11; }\n .order-lg-12 { order: 12; }\n .offset-lg-0 { margin-left: 0px; }\n .offset-lg-1 { margin-left: 8.33333%; }\n .offset-lg-2 { margin-left: 16.6667%; }\n .offset-lg-3 { margin-left: 25%; }\n .offset-lg-4 { margin-left: 33.3333%; }\n .offset-lg-5 { margin-left: 41.6667%; }\n .offset-lg-6 { margin-left: 50%; }\n .offset-lg-7 { margin-left: 58.3333%; }\n .offset-lg-8 { margin-left: 66.6667%; }\n .offset-lg-9 { margin-left: 75%; }\n .offset-lg-10 { margin-left: 83.3333%; }\n .offset-lg-11 { margin-left: 91.6667%; }\n}@media (min-width: 1200px) {\n .col-xl { flex-basis: 0px; flex-grow: 1; max-width: 100%; }\n .col-xl-auto { flex: 0 0 auto; width: auto; max-width: none; }\n .col-xl-1 { flex: 0 0 8.33333%; max-width: 8.33333%; }\n .col-xl-2 { flex: 0 0 16.6667%; max-width: 16.6667%; }\n .col-xl-3 { flex: 0 0 25%; max-width: 25%; }\n .col-xl-4 { flex: 0 0 33.3333%; max-width: 33.3333%; }\n .col-xl-5 { flex: 0 0 41.6667%; max-width: 41.6667%; }\n .col-xl-6 { flex: 0 0 50%; max-width: 50%; }\n .col-xl-7 { flex: 0 0 58.3333%; max-width: 58.3333%; }\n .col-xl-8 { flex: 0 0 66.6667%; max-width: 66.6667%; }\n .col-xl-9 { flex: 0 0 75%; max-width: 75%; }\n .col-xl-10 { flex: 0 0 83.3333%; max-width: 83.3333%; }\n .col-xl-11 { flex: 0 0 91.6667%; max-width: 91.6667%; }\n .col-xl-12 { flex: 0 0 100%; max-width: 100%; }\n .order-xl-first { order: -1; }\n .order-xl-last { order: 13; }\n .order-xl-0 { order: 0; }\n .order-xl-1 { order: 1; }\n .order-xl-2 { order: 2; }\n .order-xl-3 { order: 3; }\n .order-xl-4 { order: 4; }\n .order-xl-5 { order: 5; }\n .order-xl-6 { order: 6; }\n .order-xl-7 { order: 7; }\n .order-xl-8 { order: 8; }\n .order-xl-9 { order: 9; }\n .order-xl-10 { order: 10; }\n .order-xl-11 { order: 11; }\n .order-xl-12 { order: 12; }\n .offset-xl-0 { margin-left: 0px; }\n .offset-xl-1 { margin-left: 8.33333%; }\n .offset-xl-2 { margin-left: 16.6667%; }\n .offset-xl-3 { margin-left: 25%; }\n .offset-xl-4 { margin-left: 33.3333%; }\n .offset-xl-5 { margin-left: 41.6667%; }\n .offset-xl-6 { margin-left: 50%; }\n .offset-xl-7 { margin-left: 58.3333%; }\n .offset-xl-8 { margin-left: 66.6667%; }\n .offset-xl-9 { margin-left: 75%; }\n .offset-xl-10 { margin-left: 83.3333%; }\n .offset-xl-11 { margin-left: 91.6667%; }\n}.table { width: 100%; margin-bottom: 1rem; background-color: transparent; }.table td, .table th { padding: 0.75rem; vertical-align: top; border-top: 1px solid rgb(222, 226, 230); }.table thead th { vertical-align: bottom; border-bottom: 2px solid rgb(222, 226, 230); }.table tbody + tbody { border-top: 2px solid rgb(222, 226, 230); }.table .table { background-color: rgb(255, 255, 255); }.table-sm td, .table-sm th { padding: 0.3rem; }.table-bordered { border: 1px solid rgb(222, 226, 230); }.table-bordered td, .table-bordered th { border: 1px solid rgb(222, 226, 230); }.table-bordered thead td, .table-bordered thead th { border-bottom-width: 2px; }.table-borderless tbody + tbody, .table-borderless td, .table-borderless th, .table-borderless thead th { border: 0px; }.table-striped tbody tr:nth-of-type(2n+1) { background-color: rgba(0, 0, 0, 0.05); }.table-hover tbody tr:hover { background-color: rgba(0, 0, 0, 0.075); }.table-primary, .table-primary > td, .table-primary > th { background-color: rgb(184, 218, 255); }.table-hover .table-primary:hover { background-color: rgb(159, 205, 255); }.table-hover .table-primary:hover > td, .table-hover .table-primary:hover > th { background-color: rgb(159, 205, 255); }.table-secondary, .table-secondary > td, .table-secondary > th { background-color: rgb(214, 216, 219); }.table-hover .table-secondary:hover { background-color: rgb(200, 203, 207); }.table-hover .table-secondary:hover > td, .table-hover .table-secondary:hover > th { background-color: rgb(200, 203, 207); }.table-success, .table-success > td, .table-success > th { background-color: rgb(195, 230, 203); }.table-hover .table-success:hover { background-color: rgb(177, 223, 187); }.table-hover .table-success:hover > td, .table-hover .table-success:hover > th { background-color: rgb(177, 223, 187); }.table-info, .table-info > td, .table-info > th { background-color: rgb(190, 229, 235); }.table-hover .table-info:hover { background-color: rgb(171, 221, 229); }.table-hover .table-info:hover > td, .table-hover .table-info:hover > th { background-color: rgb(171, 221, 229); }.table-warning, .table-warning > td, .table-warning > th { background-color: rgb(255, 238, 186); }.table-hover .table-warning:hover { background-color: rgb(255, 232, 161); }.table-hover .table-warning:hover > td, .table-hover .table-warning:hover > th { background-color: rgb(255, 232, 161); }.table-danger, .table-danger > td, .table-danger > th { background-color: rgb(245, 198, 203); }.table-hover .table-danger:hover { background-color: rgb(241, 176, 183); }.table-hover .table-danger:hover > td, .table-hover .table-danger:hover > th { background-color: rgb(241, 176, 183); }.table-light, .table-light > td, .table-light > th { background-color: rgb(253, 253, 254); }.table-hover .table-light:hover { background-color: rgb(236, 236, 246); }.table-hover .table-light:hover > td, .table-hover .table-light:hover > th { background-color: rgb(236, 236, 246); }.table-dark, .table-dark > td, .table-dark > th { background-color: rgb(198, 200, 202); }.table-hover .table-dark:hover { background-color: rgb(185, 187, 190); }.table-hover .table-dark:hover > td, .table-hover .table-dark:hover > th { background-color: rgb(185, 187, 190); }.table-active, .table-active > td, .table-active > th { background-color: rgba(0, 0, 0, 0.075); }.table-hover .table-active:hover { background-color: rgba(0, 0, 0, 0.075); }.table-hover .table-active:hover > td, .table-hover .table-active:hover > th { background-color: rgba(0, 0, 0, 0.075); }.table .thead-dark th { color: rgb(255, 255, 255); background-color: rgb(33, 37, 41); border-color: rgb(50, 56, 62); }.table .thead-light th { color: rgb(73, 80, 87); background-color: rgb(233, 236, 239); border-color: rgb(222, 226, 230); }.table-dark { color: rgb(255, 255, 255); background-color: rgb(33, 37, 41); }.table-dark td, .table-dark th, .table-dark thead th { border-color: rgb(50, 56, 62); }.table-dark.table-bordered { border: 0px; }.table-dark.table-striped tbody tr:nth-of-type(2n+1) { background-color: rgba(255, 255, 255, 0.05); }.table-dark.table-hover tbody tr:hover { background-color: rgba(255, 255, 255, 0.075); }@media (max-width: 575.98px) {\n .table-responsive-sm { display: block; width: 100%; overflow-x: auto; }\n .table-responsive-sm > .table-bordered { border: 0px; }\n}@media (max-width: 767.98px) {\n .table-responsive-md { display: block; width: 100%; overflow-x: auto; }\n .table-responsive-md > .table-bordered { border: 0px; }\n}@media (max-width: 991.98px) {\n .table-responsive-lg { display: block; width: 100%; overflow-x: auto; }\n .table-responsive-lg > .table-bordered { border: 0px; }\n}@media (max-width: 1199.98px) {\n .table-responsive-xl { display: block; width: 100%; overflow-x: auto; }\n .table-responsive-xl > .table-bordered { border: 0px; }\n}.table-responsive { display: block; width: 100%; overflow-x: auto; }.table-responsive > .table-bordered { border: 0px; }.form-control { display: block; width: 100%; height: calc(2.25rem + 2px); padding: 0.375rem 0.75rem; font-size: 1rem; line-height: 1.5; color: rgb(73, 80, 87); background-color: rgb(255, 255, 255); background-clip: padding-box; border: 1px solid rgb(206, 212, 218); border-radius: 0.25rem; transition: border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; }@media not all {\n .form-control { transition: none 0s ease 0s; }\n}.form-control:focus { color: rgb(73, 80, 87); background-color: rgb(255, 255, 255); border-color: rgb(128, 189, 255); outline: 0px; box-shadow: rgba(0, 123, 255, 0.25) 0px 0px 0px 0.2rem; }.form-control::-webkit-input-placeholder { color: rgb(108, 117, 125); opacity: 1; }.form-control::placeholder { color: rgb(108, 117, 125); opacity: 1; }.form-control:disabled, .form-control[readonly] { background-color: rgb(233, 236, 239); opacity: 1; }.form-control-file, .form-control-range { display: block; width: 100%; }.col-form-label { padding-top: calc(0.375rem + 1px); padding-bottom: calc(0.375rem + 1px); margin-bottom: 0px; font-size: inherit; line-height: 1.5; }.col-form-label-lg { padding-top: calc(0.5rem + 1px); padding-bottom: calc(0.5rem + 1px); font-size: 1.25rem; line-height: 1.5; }.col-form-label-sm { padding-top: calc(0.25rem + 1px); padding-bottom: calc(0.25rem + 1px); font-size: 0.875rem; line-height: 1.5; }.form-control-plaintext { display: block; width: 100%; padding-top: 0.375rem; padding-bottom: 0.375rem; margin-bottom: 0px; line-height: 1.5; color: rgb(33, 37, 41); background-color: transparent; border-style: solid; border-color: transparent; border-image: initial; border-width: 1px 0px; }.form-control-plaintext.form-control-lg, .form-control-plaintext.form-control-sm { padding-right: 0px; padding-left: 0px; }.form-control-sm { height: calc(1.8125rem + 2px); padding: 0.25rem 0.5rem; font-size: 0.875rem; line-height: 1.5; border-radius: 0.2rem; }.form-control-lg { height: calc(2.875rem + 2px); padding: 0.5rem 1rem; font-size: 1.25rem; line-height: 1.5; border-radius: 0.3rem; }select.form-control[multiple], select.form-control[size] { height: auto; }textarea.form-control { height: auto; }.form-group { margin-bottom: 1rem; }.form-text { display: block; margin-top: 0.25rem; }.form-row { display: flex; flex-wrap: wrap; margin-right: -5px; margin-left: -5px; }.form-row > .col, .form-row > [class*=\"col-\"] { padding-right: 5px; padding-left: 5px; }.form-check { position: relative; display: block; padding-left: 1.25rem; }.form-check-input { position: absolute; margin-top: 0.3rem; margin-left: -1.25rem; }.form-check-input:disabled ~ .form-check-label { color: rgb(108, 117, 125); }.form-check-label { margin-bottom: 0px; }.form-check-inline { display: inline-flex; align-items: center; padding-left: 0px; margin-right: 0.75rem; }.form-check-inline .form-check-input { position: static; margin-top: 0px; margin-right: 0.3125rem; margin-left: 0px; }.valid-feedback { display: none; width: 100%; margin-top: 0.25rem; font-size: 80%; color: rgb(40, 167, 69); }.valid-tooltip { position: absolute; top: 100%; z-index: 5; display: none; max-width: 100%; padding: 0.25rem 0.5rem; margin-top: 0.1rem; font-size: 0.875rem; line-height: 1.5; color: rgb(255, 255, 255); background-color: rgba(40, 167, 69, 0.9); border-radius: 0.25rem; }.custom-select.is-valid, .form-control.is-valid, .was-validated .custom-select:valid, .was-validated .form-control:valid { border-color: rgb(40, 167, 69); }.custom-select.is-valid:focus, .form-control.is-valid:focus, .was-validated .custom-select:valid:focus, .was-validated .form-control:valid:focus { border-color: rgb(40, 167, 69); box-shadow: rgba(40, 167, 69, 0.25) 0px 0px 0px 0.2rem; }.custom-select.is-valid ~ .valid-feedback, .custom-select.is-valid ~ .valid-tooltip, .form-control.is-valid ~ .valid-feedback, .form-control.is-valid ~ .valid-tooltip, .was-validated .custom-select:valid ~ .valid-feedback, .was-validated .custom-select:valid ~ .valid-tooltip, .was-validated .form-control:valid ~ .valid-feedback, .was-validated .form-control:valid ~ .valid-tooltip { display: block; }.form-control-file.is-valid ~ .valid-feedback, .form-control-file.is-valid ~ .valid-tooltip, .was-validated .form-control-file:valid ~ .valid-feedback, .was-validated .form-control-file:valid ~ .valid-tooltip { display: block; }.form-check-input.is-valid ~ .form-check-label, .was-validated .form-check-input:valid ~ .form-check-label { color: rgb(40, 167, 69); }.form-check-input.is-valid ~ .valid-feedback, .form-check-input.is-valid ~ .valid-tooltip, .was-validated .form-check-input:valid ~ .valid-feedback, .was-validated .form-check-input:valid ~ .valid-tooltip { display: block; }.custom-control-input.is-valid ~ .custom-control-label, .was-validated .custom-control-input:valid ~ .custom-control-label { color: rgb(40, 167, 69); }.custom-control-input.is-valid ~ .custom-control-label::before, .was-validated .custom-control-input:valid ~ .custom-control-label::before { background-color: rgb(113, 221, 138); }.custom-control-input.is-valid ~ .valid-feedback, .custom-control-input.is-valid ~ .valid-tooltip, .was-validated .custom-control-input:valid ~ .valid-feedback, .was-validated .custom-control-input:valid ~ .valid-tooltip { display: block; }.custom-control-input.is-valid:checked ~ .custom-control-label::before, .was-validated .custom-control-input:valid:checked ~ .custom-control-label::before { background-color: rgb(52, 206, 87); }.custom-control-input.is-valid:focus ~ .custom-control-label::before, .was-validated .custom-control-input:valid:focus ~ .custom-control-label::before { box-shadow: rgb(255, 255, 255) 0px 0px 0px 1px, rgba(40, 167, 69, 0.25) 0px 0px 0px 0.2rem; }.custom-file-input.is-valid ~ .custom-file-label, .was-validated .custom-file-input:valid ~ .custom-file-label { border-color: rgb(40, 167, 69); }.custom-file-input.is-valid ~ .custom-file-label::after, .was-validated .custom-file-input:valid ~ .custom-file-label::after { border-color: inherit; }.custom-file-input.is-valid ~ .valid-feedback, .custom-file-input.is-valid ~ .valid-tooltip, .was-validated .custom-file-input:valid ~ .valid-feedback, .was-validated .custom-file-input:valid ~ .valid-tooltip { display: block; }.custom-file-input.is-valid:focus ~ .custom-file-label, .was-validated .custom-file-input:valid:focus ~ .custom-file-label { box-shadow: rgba(40, 167, 69, 0.25) 0px 0px 0px 0.2rem; }.invalid-feedback { display: none; width: 100%; margin-top: 0.25rem; font-size: 80%; color: rgb(220, 53, 69); }.invalid-tooltip { position: absolute; top: 100%; z-index: 5; display: none; max-width: 100%; padding: 0.25rem 0.5rem; margin-top: 0.1rem; font-size: 0.875rem; line-height: 1.5; color: rgb(255, 255, 255); background-color: rgba(220, 53, 69, 0.9); border-radius: 0.25rem; }.custom-select.is-invalid, .form-control.is-invalid, .was-validated .custom-select:invalid, .was-validated .form-control:invalid { border-color: rgb(220, 53, 69); }.custom-select.is-invalid:focus, .form-control.is-invalid:focus, .was-validated .custom-select:invalid:focus, .was-validated .form-control:invalid:focus { border-color: rgb(220, 53, 69); box-shadow: rgba(220, 53, 69, 0.25) 0px 0px 0px 0.2rem; }.custom-select.is-invalid ~ .invalid-feedback, .custom-select.is-invalid ~ .invalid-tooltip, .form-control.is-invalid ~ .invalid-feedback, .form-control.is-invalid ~ .invalid-tooltip, .was-validated .custom-select:invalid ~ .invalid-feedback, .was-validated .custom-select:invalid ~ .invalid-tooltip, .was-validated .form-control:invalid ~ .invalid-feedback, .was-validated .form-control:invalid ~ .invalid-tooltip { display: block; }.form-control-file.is-invalid ~ .invalid-feedback, .form-control-file.is-invalid ~ .invalid-tooltip, .was-validated .form-control-file:invalid ~ .invalid-feedback, .was-validated .form-control-file:invalid ~ .invalid-tooltip { display: block; }.form-check-input.is-invalid ~ .form-check-label, .was-validated .form-check-input:invalid ~ .form-check-label { color: rgb(220, 53, 69); }.form-check-input.is-invalid ~ .invalid-feedback, .form-check-input.is-invalid ~ .invalid-tooltip, .was-validated .form-check-input:invalid ~ .invalid-feedback, .was-validated .form-check-input:invalid ~ .invalid-tooltip { display: block; }.custom-control-input.is-invalid ~ .custom-control-label, .was-validated .custom-control-input:invalid ~ .custom-control-label { color: rgb(220, 53, 69); }.custom-control-input.is-invalid ~ .custom-control-label::before, .was-validated .custom-control-input:invalid ~ .custom-control-label::before { background-color: rgb(239, 162, 169); }.custom-control-input.is-invalid ~ .invalid-feedback, .custom-control-input.is-invalid ~ .invalid-tooltip, .was-validated .custom-control-input:invalid ~ .invalid-feedback, .was-validated .custom-control-input:invalid ~ .invalid-tooltip { display: block; }.custom-control-input.is-invalid:checked ~ .custom-control-label::before, .was-validated .custom-control-input:invalid:checked ~ .custom-control-label::before { background-color: rgb(228, 96, 109); }.custom-control-input.is-invalid:focus ~ .custom-control-label::before, .was-validated .custom-control-input:invalid:focus ~ .custom-control-label::before { box-shadow: rgb(255, 255, 255) 0px 0px 0px 1px, rgba(220, 53, 69, 0.25) 0px 0px 0px 0.2rem; }.custom-file-input.is-invalid ~ .custom-file-label, .was-validated .custom-file-input:invalid ~ .custom-file-label { border-color: rgb(220, 53, 69); }.custom-file-input.is-invalid ~ .custom-file-label::after, .was-validated .custom-file-input:invalid ~ .custom-file-label::after { border-color: inherit; }.custom-file-input.is-invalid ~ .invalid-feedback, .custom-file-input.is-invalid ~ .invalid-tooltip, .was-validated .custom-file-input:invalid ~ .invalid-feedback, .was-validated .custom-file-input:invalid ~ .invalid-tooltip { display: block; }.custom-file-input.is-invalid:focus ~ .custom-file-label, .was-validated .custom-file-input:invalid:focus ~ .custom-file-label { box-shadow: rgba(220, 53, 69, 0.25) 0px 0px 0px 0.2rem; }.form-inline { display: flex; flex-flow: row wrap; align-items: center; }.form-inline .form-check { width: 100%; }@media (min-width: 576px) {\n .form-inline label { display: flex; align-items: center; justify-content: center; margin-bottom: 0px; }\n .form-inline .form-group { display: flex; flex: 0 0 auto; flex-flow: row wrap; align-items: center; margin-bottom: 0px; }\n .form-inline .form-control { display: inline-block; width: auto; vertical-align: middle; }\n .form-inline .form-control-plaintext { display: inline-block; }\n .form-inline .custom-select, .form-inline .input-group { width: auto; }\n .form-inline .form-check { display: flex; align-items: center; justify-content: center; width: auto; padding-left: 0px; }\n .form-inline .form-check-input { position: relative; margin-top: 0px; margin-right: 0.25rem; margin-left: 0px; }\n .form-inline .custom-control { align-items: center; justify-content: center; }\n .form-inline .custom-control-label { margin-bottom: 0px; }\n}.btn { display: inline-block; font-weight: 400; text-align: center; white-space: nowrap; vertical-align: middle; user-select: none; border: 1px solid transparent; padding: 0.375rem 0.75rem; font-size: 1rem; line-height: 1.5; border-radius: 0.25rem; transition: color 0.15s ease-in-out 0s, background-color 0.15s ease-in-out 0s, border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; }@media not all {\n .btn { transition: none 0s ease 0s; }\n}.btn:focus, .btn:hover { text-decoration: none; }.btn.focus, .btn:focus { outline: 0px; box-shadow: rgba(0, 123, 255, 0.25) 0px 0px 0px 0.2rem; }.btn.disabled, .btn:disabled { opacity: 0.65; }.btn:not(:disabled):not(.disabled) { cursor: pointer; }a.btn.disabled, fieldset:disabled a.btn { pointer-events: none; }.btn-primary { color: rgb(255, 255, 255); background-color: rgb(0, 123, 255); border-color: rgb(0, 123, 255); }.btn-primary:hover { color: rgb(255, 255, 255); background-color: rgb(0, 105, 217); border-color: rgb(0, 98, 204); }.btn-primary.focus, .btn-primary:focus { box-shadow: rgba(0, 123, 255, 0.5) 0px 0px 0px 0.2rem; }.btn-primary.disabled, .btn-primary:disabled { color: rgb(255, 255, 255); background-color: rgb(0, 123, 255); border-color: rgb(0, 123, 255); }.btn-primary:not(:disabled):not(.disabled).active, .btn-primary:not(:disabled):not(.disabled):active, .show > .btn-primary.dropdown-toggle { color: rgb(255, 255, 255); background-color: rgb(0, 98, 204); border-color: rgb(0, 92, 191); }.btn-primary:not(:disabled):not(.disabled).active:focus, .btn-primary:not(:disabled):not(.disabled):active:focus, .show > .btn-primary.dropdown-toggle:focus { box-shadow: rgba(0, 123, 255, 0.5) 0px 0px 0px 0.2rem; }.btn-secondary { color: rgb(255, 255, 255); background-color: rgb(108, 117, 125); border-color: rgb(108, 117, 125); }.btn-secondary:hover { color: rgb(255, 255, 255); background-color: rgb(90, 98, 104); border-color: rgb(84, 91, 98); }.btn-secondary.focus, .btn-secondary:focus { box-shadow: rgba(108, 117, 125, 0.5) 0px 0px 0px 0.2rem; }.btn-secondary.disabled, .btn-secondary:disabled { color: rgb(255, 255, 255); background-color: rgb(108, 117, 125); border-color: rgb(108, 117, 125); }.btn-secondary:not(:disabled):not(.disabled).active, .btn-secondary:not(:disabled):not(.disabled):active, .show > .btn-secondary.dropdown-toggle { color: rgb(255, 255, 255); background-color: rgb(84, 91, 98); border-color: rgb(78, 85, 91); }.btn-secondary:not(:disabled):not(.disabled).active:focus, .btn-secondary:not(:disabled):not(.disabled):active:focus, .show > .btn-secondary.dropdown-toggle:focus { box-shadow: rgba(108, 117, 125, 0.5) 0px 0px 0px 0.2rem; }.btn-success { color: rgb(255, 255, 255); background-color: rgb(40, 167, 69); border-color: rgb(40, 167, 69); }.btn-success:hover { color: rgb(255, 255, 255); background-color: rgb(33, 136, 56); border-color: rgb(30, 126, 52); }.btn-success.focus, .btn-success:focus { box-shadow: rgba(40, 167, 69, 0.5) 0px 0px 0px 0.2rem; }.btn-success.disabled, .btn-success:disabled { color: rgb(255, 255, 255); background-color: rgb(40, 167, 69); border-color: rgb(40, 167, 69); }.btn-success:not(:disabled):not(.disabled).active, .btn-success:not(:disabled):not(.disabled):active, .show > .btn-success.dropdown-toggle { color: rgb(255, 255, 255); background-color: rgb(30, 126, 52); border-color: rgb(28, 116, 48); }.btn-success:not(:disabled):not(.disabled).active:focus, .btn-success:not(:disabled):not(.disabled):active:focus, .show > .btn-success.dropdown-toggle:focus { box-shadow: rgba(40, 167, 69, 0.5) 0px 0px 0px 0.2rem; }.btn-info { color: rgb(255, 255, 255); background-color: rgb(23, 162, 184); border-color: rgb(23, 162, 184); }.btn-info:hover { color: rgb(255, 255, 255); background-color: rgb(19, 132, 150); border-color: rgb(17, 122, 139); }.btn-info.focus, .btn-info:focus { box-shadow: rgba(23, 162, 184, 0.5) 0px 0px 0px 0.2rem; }.btn-info.disabled, .btn-info:disabled { color: rgb(255, 255, 255); background-color: rgb(23, 162, 184); border-color: rgb(23, 162, 184); }.btn-info:not(:disabled):not(.disabled).active, .btn-info:not(:disabled):not(.disabled):active, .show > .btn-info.dropdown-toggle { color: rgb(255, 255, 255); background-color: rgb(17, 122, 139); border-color: rgb(16, 112, 127); }.btn-info:not(:disabled):not(.disabled).active:focus, .btn-info:not(:disabled):not(.disabled):active:focus, .show > .btn-info.dropdown-toggle:focus { box-shadow: rgba(23, 162, 184, 0.5) 0px 0px 0px 0.2rem; }.btn-warning { color: rgb(33, 37, 41); background-color: rgb(255, 193, 7); border-color: rgb(255, 193, 7); }.btn-warning:hover { color: rgb(33, 37, 41); background-color: rgb(224, 168, 0); border-color: rgb(211, 158, 0); }.btn-warning.focus, .btn-warning:focus { box-shadow: rgba(255, 193, 7, 0.5) 0px 0px 0px 0.2rem; }.btn-warning.disabled, .btn-warning:disabled { color: rgb(33, 37, 41); background-color: rgb(255, 193, 7); border-color: rgb(255, 193, 7); }.btn-warning:not(:disabled):not(.disabled).active, .btn-warning:not(:disabled):not(.disabled):active, .show > .btn-warning.dropdown-toggle { color: rgb(33, 37, 41); background-color: rgb(211, 158, 0); border-color: rgb(198, 149, 0); }.btn-warning:not(:disabled):not(.disabled).active:focus, .btn-warning:not(:disabled):not(.disabled):active:focus, .show > .btn-warning.dropdown-toggle:focus { box-shadow: rgba(255, 193, 7, 0.5) 0px 0px 0px 0.2rem; }.btn-danger { color: rgb(255, 255, 255); background-color: rgb(220, 53, 69); border-color: rgb(220, 53, 69); }.btn-danger:hover { color: rgb(255, 255, 255); background-color: rgb(200, 35, 51); border-color: rgb(189, 33, 48); }.btn-danger.focus, .btn-danger:focus { box-shadow: rgba(220, 53, 69, 0.5) 0px 0px 0px 0.2rem; }.btn-danger.disabled, .btn-danger:disabled { color: rgb(255, 255, 255); background-color: rgb(220, 53, 69); border-color: rgb(220, 53, 69); }.btn-danger:not(:disabled):not(.disabled).active, .btn-danger:not(:disabled):not(.disabled):active, .show > .btn-danger.dropdown-toggle { color: rgb(255, 255, 255); background-color: rgb(189, 33, 48); border-color: rgb(178, 31, 45); }.btn-danger:not(:disabled):not(.disabled).active:focus, .btn-danger:not(:disabled):not(.disabled):active:focus, .show > .btn-danger.dropdown-toggle:focus { box-shadow: rgba(220, 53, 69, 0.5) 0px 0px 0px 0.2rem; }.btn-light { color: rgb(33, 37, 41); background-color: rgb(248, 249, 250); border-color: rgb(248, 249, 250); }.btn-light:hover { color: rgb(33, 37, 41); background-color: rgb(226, 230, 234); border-color: rgb(218, 224, 229); }.btn-light.focus, .btn-light:focus { box-shadow: rgba(248, 249, 250, 0.5) 0px 0px 0px 0.2rem; }.btn-light.disabled, .btn-light:disabled { color: rgb(33, 37, 41); background-color: rgb(248, 249, 250); border-color: rgb(248, 249, 250); }.btn-light:not(:disabled):not(.disabled).active, .btn-light:not(:disabled):not(.disabled):active, .show > .btn-light.dropdown-toggle { color: rgb(33, 37, 41); background-color: rgb(218, 224, 229); border-color: rgb(211, 217, 223); }.btn-light:not(:disabled):not(.disabled).active:focus, .btn-light:not(:disabled):not(.disabled):active:focus, .show > .btn-light.dropdown-toggle:focus { box-shadow: rgba(248, 249, 250, 0.5) 0px 0px 0px 0.2rem; }.btn-dark { color: rgb(255, 255, 255); background-color: rgb(52, 58, 64); border-color: rgb(52, 58, 64); }.btn-dark:hover { color: rgb(255, 255, 255); background-color: rgb(35, 39, 43); border-color: rgb(29, 33, 36); }.btn-dark.focus, .btn-dark:focus { box-shadow: rgba(52, 58, 64, 0.5) 0px 0px 0px 0.2rem; }.btn-dark.disabled, .btn-dark:disabled { color: rgb(255, 255, 255); background-color: rgb(52, 58, 64); border-color: rgb(52, 58, 64); }.btn-dark:not(:disabled):not(.disabled).active, .btn-dark:not(:disabled):not(.disabled):active, .show > .btn-dark.dropdown-toggle { color: rgb(255, 255, 255); background-color: rgb(29, 33, 36); border-color: rgb(23, 26, 29); }.btn-dark:not(:disabled):not(.disabled).active:focus, .btn-dark:not(:disabled):not(.disabled):active:focus, .show > .btn-dark.dropdown-toggle:focus { box-shadow: rgba(52, 58, 64, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-primary { color: rgb(0, 123, 255); background-color: transparent; background-image: none; border-color: rgb(0, 123, 255); }.btn-outline-primary:hover { color: rgb(255, 255, 255); background-color: rgb(0, 123, 255); border-color: rgb(0, 123, 255); }.btn-outline-primary.focus, .btn-outline-primary:focus { box-shadow: rgba(0, 123, 255, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-primary.disabled, .btn-outline-primary:disabled { color: rgb(0, 123, 255); background-color: transparent; }.btn-outline-primary:not(:disabled):not(.disabled).active, .btn-outline-primary:not(:disabled):not(.disabled):active, .show > .btn-outline-primary.dropdown-toggle { color: rgb(255, 255, 255); background-color: rgb(0, 123, 255); border-color: rgb(0, 123, 255); }.btn-outline-primary:not(:disabled):not(.disabled).active:focus, .btn-outline-primary:not(:disabled):not(.disabled):active:focus, .show > .btn-outline-primary.dropdown-toggle:focus { box-shadow: rgba(0, 123, 255, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-secondary { color: rgb(108, 117, 125); background-color: transparent; background-image: none; border-color: rgb(108, 117, 125); }.btn-outline-secondary:hover { color: rgb(255, 255, 255); background-color: rgb(108, 117, 125); border-color: rgb(108, 117, 125); }.btn-outline-secondary.focus, .btn-outline-secondary:focus { box-shadow: rgba(108, 117, 125, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-secondary.disabled, .btn-outline-secondary:disabled { color: rgb(108, 117, 125); background-color: transparent; }.btn-outline-secondary:not(:disabled):not(.disabled).active, .btn-outline-secondary:not(:disabled):not(.disabled):active, .show > .btn-outline-secondary.dropdown-toggle { color: rgb(255, 255, 255); background-color: rgb(108, 117, 125); border-color: rgb(108, 117, 125); }.btn-outline-secondary:not(:disabled):not(.disabled).active:focus, .btn-outline-secondary:not(:disabled):not(.disabled):active:focus, .show > .btn-outline-secondary.dropdown-toggle:focus { box-shadow: rgba(108, 117, 125, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-success { color: rgb(40, 167, 69); background-color: transparent; background-image: none; border-color: rgb(40, 167, 69); }.btn-outline-success:hover { color: rgb(255, 255, 255); background-color: rgb(40, 167, 69); border-color: rgb(40, 167, 69); }.btn-outline-success.focus, .btn-outline-success:focus { box-shadow: rgba(40, 167, 69, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-success.disabled, .btn-outline-success:disabled { color: rgb(40, 167, 69); background-color: transparent; }.btn-outline-success:not(:disabled):not(.disabled).active, .btn-outline-success:not(:disabled):not(.disabled):active, .show > .btn-outline-success.dropdown-toggle { color: rgb(255, 255, 255); background-color: rgb(40, 167, 69); border-color: rgb(40, 167, 69); }.btn-outline-success:not(:disabled):not(.disabled).active:focus, .btn-outline-success:not(:disabled):not(.disabled):active:focus, .show > .btn-outline-success.dropdown-toggle:focus { box-shadow: rgba(40, 167, 69, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-info { color: rgb(23, 162, 184); background-color: transparent; background-image: none; border-color: rgb(23, 162, 184); }.btn-outline-info:hover { color: rgb(255, 255, 255); background-color: rgb(23, 162, 184); border-color: rgb(23, 162, 184); }.btn-outline-info.focus, .btn-outline-info:focus { box-shadow: rgba(23, 162, 184, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-info.disabled, .btn-outline-info:disabled { color: rgb(23, 162, 184); background-color: transparent; }.btn-outline-info:not(:disabled):not(.disabled).active, .btn-outline-info:not(:disabled):not(.disabled):active, .show > .btn-outline-info.dropdown-toggle { color: rgb(255, 255, 255); background-color: rgb(23, 162, 184); border-color: rgb(23, 162, 184); }.btn-outline-info:not(:disabled):not(.disabled).active:focus, .btn-outline-info:not(:disabled):not(.disabled):active:focus, .show > .btn-outline-info.dropdown-toggle:focus { box-shadow: rgba(23, 162, 184, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-warning { color: rgb(255, 193, 7); background-color: transparent; background-image: none; border-color: rgb(255, 193, 7); }.btn-outline-warning:hover { color: rgb(33, 37, 41); background-color: rgb(255, 193, 7); border-color: rgb(255, 193, 7); }.btn-outline-warning.focus, .btn-outline-warning:focus { box-shadow: rgba(255, 193, 7, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-warning.disabled, .btn-outline-warning:disabled { color: rgb(255, 193, 7); background-color: transparent; }.btn-outline-warning:not(:disabled):not(.disabled).active, .btn-outline-warning:not(:disabled):not(.disabled):active, .show > .btn-outline-warning.dropdown-toggle { color: rgb(33, 37, 41); background-color: rgb(255, 193, 7); border-color: rgb(255, 193, 7); }.btn-outline-warning:not(:disabled):not(.disabled).active:focus, .btn-outline-warning:not(:disabled):not(.disabled):active:focus, .show > .btn-outline-warning.dropdown-toggle:focus { box-shadow: rgba(255, 193, 7, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-danger { color: rgb(220, 53, 69); background-color: transparent; background-image: none; border-color: rgb(220, 53, 69); }.btn-outline-danger:hover { color: rgb(255, 255, 255); background-color: rgb(220, 53, 69); border-color: rgb(220, 53, 69); }.btn-outline-danger.focus, .btn-outline-danger:focus { box-shadow: rgba(220, 53, 69, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-danger.disabled, .btn-outline-danger:disabled { color: rgb(220, 53, 69); background-color: transparent; }.btn-outline-danger:not(:disabled):not(.disabled).active, .btn-outline-danger:not(:disabled):not(.disabled):active, .show > .btn-outline-danger.dropdown-toggle { color: rgb(255, 255, 255); background-color: rgb(220, 53, 69); border-color: rgb(220, 53, 69); }.btn-outline-danger:not(:disabled):not(.disabled).active:focus, .btn-outline-danger:not(:disabled):not(.disabled):active:focus, .show > .btn-outline-danger.dropdown-toggle:focus { box-shadow: rgba(220, 53, 69, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-light { color: rgb(248, 249, 250); background-color: transparent; background-image: none; border-color: rgb(248, 249, 250); }.btn-outline-light:hover { color: rgb(33, 37, 41); background-color: rgb(248, 249, 250); border-color: rgb(248, 249, 250); }.btn-outline-light.focus, .btn-outline-light:focus { box-shadow: rgba(248, 249, 250, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-light.disabled, .btn-outline-light:disabled { color: rgb(248, 249, 250); background-color: transparent; }.btn-outline-light:not(:disabled):not(.disabled).active, .btn-outline-light:not(:disabled):not(.disabled):active, .show > .btn-outline-light.dropdown-toggle { color: rgb(33, 37, 41); background-color: rgb(248, 249, 250); border-color: rgb(248, 249, 250); }.btn-outline-light:not(:disabled):not(.disabled).active:focus, .btn-outline-light:not(:disabled):not(.disabled):active:focus, .show > .btn-outline-light.dropdown-toggle:focus { box-shadow: rgba(248, 249, 250, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-dark { color: rgb(52, 58, 64); background-color: transparent; background-image: none; border-color: rgb(52, 58, 64); }.btn-outline-dark:hover { color: rgb(255, 255, 255); background-color: rgb(52, 58, 64); border-color: rgb(52, 58, 64); }.btn-outline-dark.focus, .btn-outline-dark:focus { box-shadow: rgba(52, 58, 64, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-dark.disabled, .btn-outline-dark:disabled { color: rgb(52, 58, 64); background-color: transparent; }.btn-outline-dark:not(:disabled):not(.disabled).active, .btn-outline-dark:not(:disabled):not(.disabled):active, .show > .btn-outline-dark.dropdown-toggle { color: rgb(255, 255, 255); background-color: rgb(52, 58, 64); border-color: rgb(52, 58, 64); }.btn-outline-dark:not(:disabled):not(.disabled).active:focus, .btn-outline-dark:not(:disabled):not(.disabled):active:focus, .show > .btn-outline-dark.dropdown-toggle:focus { box-shadow: rgba(52, 58, 64, 0.5) 0px 0px 0px 0.2rem; }.btn-link { font-weight: 400; color: rgb(0, 123, 255); background-color: transparent; }.btn-link:hover { color: rgb(0, 86, 179); text-decoration: underline; background-color: transparent; border-color: transparent; }.btn-link.focus, .btn-link:focus { text-decoration: underline; border-color: transparent; box-shadow: none; }.btn-link.disabled, .btn-link:disabled { color: rgb(108, 117, 125); pointer-events: none; }.btn-group-lg > .btn, .btn-lg { padding: 0.5rem 1rem; font-size: 1.25rem; line-height: 1.5; border-radius: 0.3rem; }.btn-group-sm > .btn, .btn-sm { padding: 0.25rem 0.5rem; font-size: 0.875rem; line-height: 1.5; border-radius: 0.2rem; }.btn-block { display: block; width: 100%; }.btn-block + .btn-block { margin-top: 0.5rem; }input[type=\"button\"].btn-block, input[type=\"reset\"].btn-block, input[type=\"submit\"].btn-block { width: 100%; }.fade { transition: opacity 0.15s linear 0s; }@media not all {\n .fade { transition: none 0s ease 0s; }\n}.fade:not(.show) { opacity: 0; }.collapse:not(.show) { display: none; }.collapsing { position: relative; height: 0px; overflow: hidden; transition: height 0.35s ease 0s; }@media not all {\n .collapsing { transition: none 0s ease 0s; }\n}.dropdown, .dropleft, .dropright, .dropup { position: relative; }.dropdown-toggle::after { display: inline-block; width: 0px; height: 0px; margin-left: 0.255em; vertical-align: 0.255em; content: \"\"; border-width: 0.3em 0.3em 0px; border-top-style: solid; border-top-color: initial; border-right-style: solid; border-right-color: transparent; border-bottom-style: initial; border-bottom-color: initial; border-left-style: solid; border-left-color: transparent; }.dropdown-toggle:empty::after { margin-left: 0px; }.dropdown-menu { position: absolute; top: 100%; left: 0px; z-index: 1000; display: none; float: left; min-width: 10rem; padding: 0.5rem 0px; margin: 0.125rem 0px 0px; font-size: 1rem; color: rgb(33, 37, 41); text-align: left; list-style: none; background-color: rgb(255, 255, 255); background-clip: padding-box; border: 1px solid rgba(0, 0, 0, 0.15); border-radius: 0.25rem; }.dropdown-menu-right { right: 0px; left: auto; }.dropup .dropdown-menu { top: auto; bottom: 100%; margin-top: 0px; margin-bottom: 0.125rem; }.dropup .dropdown-toggle::after { display: inline-block; width: 0px; height: 0px; margin-left: 0.255em; vertical-align: 0.255em; content: \"\"; border-width: 0px 0.3em 0.3em; border-top-style: initial; border-top-color: initial; border-right-style: solid; border-right-color: transparent; border-bottom-style: solid; border-bottom-color: initial; border-left-style: solid; border-left-color: transparent; }.dropup .dropdown-toggle:empty::after { margin-left: 0px; }.dropright .dropdown-menu { top: 0px; right: auto; left: 100%; margin-top: 0px; margin-left: 0.125rem; }.dropright .dropdown-toggle::after { display: inline-block; width: 0px; height: 0px; margin-left: 0.255em; vertical-align: 0.255em; content: \"\"; border-width: 0.3em 0px 0.3em 0.3em; border-top-style: solid; border-top-color: transparent; border-right-style: initial; border-right-color: initial; border-bottom-style: solid; border-bottom-color: transparent; border-left-style: solid; border-left-color: initial; }.dropright .dropdown-toggle:empty::after { margin-left: 0px; }.dropright .dropdown-toggle::after { vertical-align: 0px; }.dropleft .dropdown-menu { top: 0px; right: 100%; left: auto; margin-top: 0px; margin-right: 0.125rem; }.dropleft .dropdown-toggle::after { display: inline-block; width: 0px; height: 0px; margin-left: 0.255em; vertical-align: 0.255em; content: \"\"; }.dropleft .dropdown-toggle::after { display: none; }.dropleft .dropdown-toggle::before { display: inline-block; width: 0px; height: 0px; margin-right: 0.255em; vertical-align: 0.255em; content: \"\"; border-top: 0.3em solid transparent; border-right: 0.3em solid; border-bottom: 0.3em solid transparent; }.dropleft .dropdown-toggle:empty::after { margin-left: 0px; }.dropleft .dropdown-toggle::before { vertical-align: 0px; }.dropdown-menu[x-placement^=\"bottom\"], .dropdown-menu[x-placement^=\"left\"], .dropdown-menu[x-placement^=\"right\"], .dropdown-menu[x-placement^=\"top\"] { right: auto; bottom: auto; }.dropdown-divider { height: 0px; margin: 0.5rem 0px; overflow: hidden; border-top: 1px solid rgb(233, 236, 239); }.dropdown-item { display: block; width: 100%; padding: 0.25rem 1.5rem; clear: both; font-weight: 400; color: rgb(33, 37, 41); text-align: inherit; white-space: nowrap; background-color: transparent; border: 0px; }.dropdown-item:focus, .dropdown-item:hover { color: rgb(22, 24, 27); text-decoration: none; background-color: rgb(248, 249, 250); }.dropdown-item.active, .dropdown-item:active { color: rgb(255, 255, 255); text-decoration: none; background-color: rgb(0, 123, 255); }.dropdown-item.disabled, .dropdown-item:disabled { color: rgb(108, 117, 125); background-color: transparent; }.dropdown-menu.show { display: block; }.dropdown-header { display: block; padding: 0.5rem 1.5rem; margin-bottom: 0px; font-size: 0.875rem; color: rgb(108, 117, 125); white-space: nowrap; }.dropdown-item-text { display: block; padding: 0.25rem 1.5rem; color: rgb(33, 37, 41); }.btn-group, .btn-group-vertical { position: relative; display: inline-flex; vertical-align: middle; }.btn-group-vertical > .btn, .btn-group > .btn { position: relative; flex: 0 1 auto; }.btn-group-vertical > .btn:hover, .btn-group > .btn:hover { z-index: 1; }.btn-group-vertical > .btn.active, .btn-group-vertical > .btn:active, .btn-group-vertical > .btn:focus, .btn-group > .btn.active, .btn-group > .btn:active, .btn-group > .btn:focus { z-index: 1; }.btn-group .btn + .btn, .btn-group .btn + .btn-group, .btn-group .btn-group + .btn, .btn-group .btn-group + .btn-group, .btn-group-vertical .btn + .btn, .btn-group-vertical .btn + .btn-group, .btn-group-vertical .btn-group + .btn, .btn-group-vertical .btn-group + .btn-group { margin-left: -1px; }.btn-toolbar { display: flex; flex-wrap: wrap; justify-content: flex-start; }.btn-toolbar .input-group { width: auto; }.btn-group > .btn:first-child { margin-left: 0px; }.btn-group > .btn-group:not(:last-child) > .btn, .btn-group > .btn:not(:last-child):not(.dropdown-toggle) { border-top-right-radius: 0px; border-bottom-right-radius: 0px; }.btn-group > .btn-group:not(:first-child) > .btn, .btn-group > .btn:not(:first-child) { border-top-left-radius: 0px; border-bottom-left-radius: 0px; }.dropdown-toggle-split { padding-right: 0.5625rem; padding-left: 0.5625rem; }.dropdown-toggle-split::after, .dropright .dropdown-toggle-split::after, .dropup .dropdown-toggle-split::after { margin-left: 0px; }.dropleft .dropdown-toggle-split::before { margin-right: 0px; }.btn-group-sm > .btn + .dropdown-toggle-split, .btn-sm + .dropdown-toggle-split { padding-right: 0.375rem; padding-left: 0.375rem; }.btn-group-lg > .btn + .dropdown-toggle-split, .btn-lg + .dropdown-toggle-split { padding-right: 0.75rem; padding-left: 0.75rem; }.btn-group-vertical { flex-direction: column; align-items: flex-start; justify-content: center; }.btn-group-vertical .btn, .btn-group-vertical .btn-group { width: 100%; }.btn-group-vertical > .btn + .btn, .btn-group-vertical > .btn + .btn-group, .btn-group-vertical > .btn-group + .btn, .btn-group-vertical > .btn-group + .btn-group { margin-top: -1px; margin-left: 0px; }.btn-group-vertical > .btn-group:not(:last-child) > .btn, .btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle) { border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; }.btn-group-vertical > .btn-group:not(:first-child) > .btn, .btn-group-vertical > .btn:not(:first-child) { border-top-left-radius: 0px; border-top-right-radius: 0px; }.btn-group-toggle > .btn, .btn-group-toggle > .btn-group > .btn { margin-bottom: 0px; }.btn-group-toggle > .btn input[type=\"checkbox\"], .btn-group-toggle > .btn input[type=\"radio\"], .btn-group-toggle > .btn-group > .btn input[type=\"checkbox\"], .btn-group-toggle > .btn-group > .btn input[type=\"radio\"] { position: absolute; clip: rect(0px, 0px, 0px, 0px); pointer-events: none; }.input-group { position: relative; display: flex; flex-wrap: wrap; align-items: stretch; width: 100%; }.input-group > .custom-file, .input-group > .custom-select, .input-group > .form-control { position: relative; flex: 1 1 auto; width: 1%; margin-bottom: 0px; }.input-group > .custom-file + .custom-file, .input-group > .custom-file + .custom-select, .input-group > .custom-file + .form-control, .input-group > .custom-select + .custom-file, .input-group > .custom-select + .custom-select, .input-group > .custom-select + .form-control, .input-group > .form-control + .custom-file, .input-group > .form-control + .custom-select, .input-group > .form-control + .form-control { margin-left: -1px; }.input-group > .custom-file .custom-file-input:focus ~ .custom-file-label, .input-group > .custom-select:focus, .input-group > .form-control:focus { z-index: 3; }.input-group > .custom-file .custom-file-input:focus { z-index: 4; }.input-group > .custom-select:not(:last-child), .input-group > .form-control:not(:last-child) { border-top-right-radius: 0px; border-bottom-right-radius: 0px; }.input-group > .custom-select:not(:first-child), .input-group > .form-control:not(:first-child) { border-top-left-radius: 0px; border-bottom-left-radius: 0px; }.input-group > .custom-file { display: flex; align-items: center; }.input-group > .custom-file:not(:last-child) .custom-file-label, .input-group > .custom-file:not(:last-child) .custom-file-label::after { border-top-right-radius: 0px; border-bottom-right-radius: 0px; }.input-group > .custom-file:not(:first-child) .custom-file-label { border-top-left-radius: 0px; border-bottom-left-radius: 0px; }.input-group-append, .input-group-prepend { display: flex; }.input-group-append .btn, .input-group-prepend .btn { position: relative; z-index: 2; }.input-group-append .btn + .btn, .input-group-append .btn + .input-group-text, .input-group-append .input-group-text + .btn, .input-group-append .input-group-text + .input-group-text, .input-group-prepend .btn + .btn, .input-group-prepend .btn + .input-group-text, .input-group-prepend .input-group-text + .btn, .input-group-prepend .input-group-text + .input-group-text { margin-left: -1px; }.input-group-prepend { margin-right: -1px; }.input-group-append { margin-left: -1px; }.input-group-text { display: flex; align-items: center; padding: 0.375rem 0.75rem; margin-bottom: 0px; font-size: 1rem; font-weight: 400; line-height: 1.5; color: rgb(73, 80, 87); text-align: center; white-space: nowrap; background-color: rgb(233, 236, 239); border: 1px solid rgb(206, 212, 218); border-radius: 0.25rem; }.input-group-text input[type=\"checkbox\"], .input-group-text input[type=\"radio\"] { margin-top: 0px; }.input-group-lg > .form-control, .input-group-lg > .input-group-append > .btn, .input-group-lg > .input-group-append > .input-group-text, .input-group-lg > .input-group-prepend > .btn, .input-group-lg > .input-group-prepend > .input-group-text { height: calc(2.875rem + 2px); padding: 0.5rem 1rem; font-size: 1.25rem; line-height: 1.5; border-radius: 0.3rem; }.input-group-sm > .form-control, .input-group-sm > .input-group-append > .btn, .input-group-sm > .input-group-append > .input-group-text, .input-group-sm > .input-group-prepend > .btn, .input-group-sm > .input-group-prepend > .input-group-text { height: calc(1.8125rem + 2px); padding: 0.25rem 0.5rem; font-size: 0.875rem; line-height: 1.5; border-radius: 0.2rem; }.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle), .input-group > .input-group-append:last-child > .input-group-text:not(:last-child), .input-group > .input-group-append:not(:last-child) > .btn, .input-group > .input-group-append:not(:last-child) > .input-group-text, .input-group > .input-group-prepend > .btn, .input-group > .input-group-prepend > .input-group-text { border-top-right-radius: 0px; border-bottom-right-radius: 0px; }.input-group > .input-group-append > .btn, .input-group > .input-group-append > .input-group-text, .input-group > .input-group-prepend:first-child > .btn:not(:first-child), .input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child), .input-group > .input-group-prepend:not(:first-child) > .btn, .input-group > .input-group-prepend:not(:first-child) > .input-group-text { border-top-left-radius: 0px; border-bottom-left-radius: 0px; }.custom-control { position: relative; display: block; min-height: 1.5rem; padding-left: 1.5rem; }.custom-control-inline { display: inline-flex; margin-right: 1rem; }.custom-control-input { position: absolute; z-index: -1; opacity: 0; }.custom-control-input:checked ~ .custom-control-label::before { color: rgb(255, 255, 255); background-color: rgb(0, 123, 255); }.custom-control-input:focus ~ .custom-control-label::before { box-shadow: rgb(255, 255, 255) 0px 0px 0px 1px, rgba(0, 123, 255, 0.25) 0px 0px 0px 0.2rem; }.custom-control-input:active ~ .custom-control-label::before { color: rgb(255, 255, 255); background-color: rgb(179, 215, 255); }.custom-control-input:disabled ~ .custom-control-label { color: rgb(108, 117, 125); }.custom-control-input:disabled ~ .custom-control-label::before { background-color: rgb(233, 236, 239); }.custom-control-label { position: relative; margin-bottom: 0px; }.custom-control-label::before { position: absolute; top: 0.25rem; left: -1.5rem; display: block; width: 1rem; height: 1rem; pointer-events: none; content: \"\"; user-select: none; background-color: rgb(222, 226, 230); }.custom-control-label::after { position: absolute; top: 0.25rem; left: -1.5rem; display: block; width: 1rem; height: 1rem; content: \"\"; background-repeat: no-repeat; background-position: center center; background-size: 50% 50%; }.custom-checkbox .custom-control-label::before { border-radius: 0.25rem; }.custom-checkbox .custom-control-input:checked ~ .custom-control-label::before { background-color: rgb(0, 123, 255); }.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after { background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E\"); }.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::before { background-color: rgb(0, 123, 255); }.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::after { background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E\"); }.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::before { background-color: rgba(0, 123, 255, 0.5); }.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::before { background-color: rgba(0, 123, 255, 0.5); }.custom-radio .custom-control-label::before { border-radius: 50%; }.custom-radio .custom-control-input:checked ~ .custom-control-label::before { background-color: rgb(0, 123, 255); }.custom-radio .custom-control-input:checked ~ .custom-control-label::after { background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E\"); }.custom-radio .custom-control-input:disabled:checked ~ .custom-control-label::before { background-color: rgba(0, 123, 255, 0.5); }.custom-select { display: inline-block; width: 100%; height: calc(2.25rem + 2px); padding: 0.375rem 1.75rem 0.375rem 0.75rem; line-height: 1.5; color: rgb(73, 80, 87); vertical-align: middle; background: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E\") right 0.75rem center / 8px 10px no-repeat rgb(255, 255, 255); border: 1px solid rgb(206, 212, 218); border-radius: 0.25rem; -webkit-appearance: none; }.custom-select:focus { border-color: rgb(128, 189, 255); outline: 0px; box-shadow: rgba(128, 189, 255, 0.5) 0px 0px 0px 0.2rem; }.custom-select[multiple], .custom-select[size]:not([size=\"1\"]) { height: auto; padding-right: 0.75rem; background-image: none; }.custom-select:disabled { color: rgb(108, 117, 125); background-color: rgb(233, 236, 239); }.custom-select-sm { height: calc(1.8125rem + 2px); padding-top: 0.375rem; padding-bottom: 0.375rem; font-size: 75%; }.custom-select-lg { height: calc(2.875rem + 2px); padding-top: 0.375rem; padding-bottom: 0.375rem; font-size: 125%; }.custom-file { position: relative; display: inline-block; width: 100%; height: calc(2.25rem + 2px); margin-bottom: 0px; }.custom-file-input { position: relative; z-index: 2; width: 100%; height: calc(2.25rem + 2px); margin: 0px; opacity: 0; }.custom-file-input:focus ~ .custom-file-label { border-color: rgb(128, 189, 255); box-shadow: rgba(0, 123, 255, 0.25) 0px 0px 0px 0.2rem; }.custom-file-input:focus ~ .custom-file-label::after { border-color: rgb(128, 189, 255); }.custom-file-input:disabled ~ .custom-file-label { background-color: rgb(233, 236, 239); }.custom-file-input:lang(en) ~ .custom-file-label::after { content: \"Browse\"; }.custom-file-label { position: absolute; top: 0px; right: 0px; left: 0px; z-index: 1; height: calc(2.25rem + 2px); padding: 0.375rem 0.75rem; line-height: 1.5; color: rgb(73, 80, 87); background-color: rgb(255, 255, 255); border: 1px solid rgb(206, 212, 218); border-radius: 0.25rem; }.custom-file-label::after { position: absolute; top: 0px; right: 0px; bottom: 0px; z-index: 3; display: block; height: 2.25rem; padding: 0.375rem 0.75rem; line-height: 1.5; color: rgb(73, 80, 87); content: \"Browse\"; background-color: rgb(233, 236, 239); border-left: 1px solid rgb(206, 212, 218); border-radius: 0px 0.25rem 0.25rem 0px; }.custom-range { width: 100%; padding-left: 0px; background-color: transparent; -webkit-appearance: none; }.custom-range:focus { outline: 0px; }.custom-range:focus::-webkit-slider-thumb { box-shadow: rgb(255, 255, 255) 0px 0px 0px 1px, rgba(0, 123, 255, 0.25) 0px 0px 0px 0.2rem; }.custom-range::-webkit-slider-thumb { width: 1rem; height: 1rem; margin-top: -0.25rem; background-color: rgb(0, 123, 255); border: 0px; border-radius: 1rem; transition: background-color 0.15s ease-in-out 0s, border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; -webkit-appearance: none; }@media not all {\n .custom-range::-webkit-slider-thumb { transition: none 0s ease 0s; }\n}.custom-range::-webkit-slider-thumb:active { background-color: rgb(179, 215, 255); }.custom-range::-webkit-slider-runnable-track { width: 100%; height: 0.5rem; color: transparent; cursor: pointer; background-color: rgb(222, 226, 230); border-color: transparent; border-radius: 1rem; }@media not all {\n}@media not all {\n}.custom-control-label::before, .custom-file-label, .custom-select { transition: background-color 0.15s ease-in-out 0s, border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; }@media not all {\n .custom-control-label::before, .custom-file-label, .custom-select { transition: none 0s ease 0s; }\n}.nav { display: flex; flex-wrap: wrap; padding-left: 0px; margin-bottom: 0px; list-style: none; }.nav-link { display: block; padding: 0.5rem 1rem; }.nav-link:focus, .nav-link:hover { text-decoration: none; }.nav-link.disabled { color: rgb(108, 117, 125); }.nav-tabs { border-bottom: 1px solid rgb(222, 226, 230); }.nav-tabs .nav-item { margin-bottom: -1px; }.nav-tabs .nav-link { border: 1px solid transparent; border-top-left-radius: 0.25rem; border-top-right-radius: 0.25rem; }.nav-tabs .nav-link:focus, .nav-tabs .nav-link:hover { border-color: rgb(233, 236, 239) rgb(233, 236, 239) rgb(222, 226, 230); }.nav-tabs .nav-link.disabled { color: rgb(108, 117, 125); background-color: transparent; border-color: transparent; }.nav-tabs .nav-item.show .nav-link, .nav-tabs .nav-link.active { color: rgb(73, 80, 87); background-color: rgb(255, 255, 255); border-color: rgb(222, 226, 230) rgb(222, 226, 230) rgb(255, 255, 255); }.nav-tabs .dropdown-menu { margin-top: -1px; border-top-left-radius: 0px; border-top-right-radius: 0px; }.nav-pills .nav-link { border-radius: 0.25rem; }.nav-pills .nav-link.active, .nav-pills .show > .nav-link { color: rgb(255, 255, 255); background-color: rgb(0, 123, 255); }.nav-fill .nav-item { flex: 1 1 auto; text-align: center; }.nav-justified .nav-item { flex-basis: 0px; flex-grow: 1; text-align: center; }.tab-content > .tab-pane { display: none; }.tab-content > .active { display: block; }.navbar { position: relative; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; padding: 0.5rem 1rem; }.navbar > .container, .navbar > .container-fluid { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; }.navbar-brand { display: inline-block; padding-top: 0.3125rem; padding-bottom: 0.3125rem; margin-right: 1rem; font-size: 1.25rem; line-height: inherit; white-space: nowrap; }.navbar-brand:focus, .navbar-brand:hover { text-decoration: none; }.navbar-nav { display: flex; flex-direction: column; padding-left: 0px; margin-bottom: 0px; list-style: none; }.navbar-nav .nav-link { padding-right: 0px; padding-left: 0px; }.navbar-nav .dropdown-menu { position: static; float: none; }.navbar-text { display: inline-block; padding-top: 0.5rem; padding-bottom: 0.5rem; }.navbar-collapse { flex-basis: 100%; flex-grow: 1; align-items: center; }.navbar-toggler { padding: 0.25rem 0.75rem; font-size: 1.25rem; line-height: 1; background-color: transparent; border: 1px solid transparent; border-radius: 0.25rem; }.navbar-toggler:focus, .navbar-toggler:hover { text-decoration: none; }.navbar-toggler:not(:disabled):not(.disabled) { cursor: pointer; }.navbar-toggler-icon { display: inline-block; width: 1.5em; height: 1.5em; vertical-align: middle; content: \"\"; background: center center / 100% 100% no-repeat; }@media (max-width: 575.98px) {\n .navbar-expand-sm > .container, .navbar-expand-sm > .container-fluid { padding-right: 0px; padding-left: 0px; }\n}@media (min-width: 576px) {\n .navbar-expand-sm { flex-flow: row nowrap; justify-content: flex-start; }\n .navbar-expand-sm .navbar-nav { flex-direction: row; }\n .navbar-expand-sm .navbar-nav .dropdown-menu { position: absolute; }\n .navbar-expand-sm .navbar-nav .nav-link { padding-right: 0.5rem; padding-left: 0.5rem; }\n .navbar-expand-sm > .container, .navbar-expand-sm > .container-fluid { flex-wrap: nowrap; }\n .navbar-expand-sm .navbar-collapse { flex-basis: auto; display: flex !important; }\n .navbar-expand-sm .navbar-toggler { display: none; }\n}@media (max-width: 767.98px) {\n .navbar-expand-md > .container, .navbar-expand-md > .container-fluid { padding-right: 0px; padding-left: 0px; }\n}@media (min-width: 768px) {\n .navbar-expand-md { flex-flow: row nowrap; justify-content: flex-start; }\n .navbar-expand-md .navbar-nav { flex-direction: row; }\n .navbar-expand-md .navbar-nav .dropdown-menu { position: absolute; }\n .navbar-expand-md .navbar-nav .nav-link { padding-right: 0.5rem; padding-left: 0.5rem; }\n .navbar-expand-md > .container, .navbar-expand-md > .container-fluid { flex-wrap: nowrap; }\n .navbar-expand-md .navbar-collapse { flex-basis: auto; display: flex !important; }\n .navbar-expand-md .navbar-toggler { display: none; }\n}@media (max-width: 991.98px) {\n .navbar-expand-lg > .container, .navbar-expand-lg > .container-fluid { padding-right: 0px; padding-left: 0px; }\n}@media (min-width: 992px) {\n .navbar-expand-lg { flex-flow: row nowrap; justify-content: flex-start; }\n .navbar-expand-lg .navbar-nav { flex-direction: row; }\n .navbar-expand-lg .navbar-nav .dropdown-menu { position: absolute; }\n .navbar-expand-lg .navbar-nav .nav-link { padding-right: 0.5rem; padding-left: 0.5rem; }\n .navbar-expand-lg > .container, .navbar-expand-lg > .container-fluid { flex-wrap: nowrap; }\n .navbar-expand-lg .navbar-collapse { flex-basis: auto; display: flex !important; }\n .navbar-expand-lg .navbar-toggler { display: none; }\n}@media (max-width: 1199.98px) {\n .navbar-expand-xl > .container, .navbar-expand-xl > .container-fluid { padding-right: 0px; padding-left: 0px; }\n}@media (min-width: 1200px) {\n .navbar-expand-xl { flex-flow: row nowrap; justify-content: flex-start; }\n .navbar-expand-xl .navbar-nav { flex-direction: row; }\n .navbar-expand-xl .navbar-nav .dropdown-menu { position: absolute; }\n .navbar-expand-xl .navbar-nav .nav-link { padding-right: 0.5rem; padding-left: 0.5rem; }\n .navbar-expand-xl > .container, .navbar-expand-xl > .container-fluid { flex-wrap: nowrap; }\n .navbar-expand-xl .navbar-collapse { flex-basis: auto; display: flex !important; }\n .navbar-expand-xl .navbar-toggler { display: none; }\n}.navbar-expand { flex-flow: row nowrap; justify-content: flex-start; }.navbar-expand > .container, .navbar-expand > .container-fluid { padding-right: 0px; padding-left: 0px; }.navbar-expand .navbar-nav { flex-direction: row; }.navbar-expand .navbar-nav .dropdown-menu { position: absolute; }.navbar-expand .navbar-nav .nav-link { padding-right: 0.5rem; padding-left: 0.5rem; }.navbar-expand > .container, .navbar-expand > .container-fluid { flex-wrap: nowrap; }.navbar-expand .navbar-collapse { flex-basis: auto; display: flex !important; }.navbar-expand .navbar-toggler { display: none; }.navbar-light .navbar-brand { color: rgba(0, 0, 0, 0.9); }.navbar-light .navbar-brand:focus, .navbar-light .navbar-brand:hover { color: rgba(0, 0, 0, 0.9); }.navbar-light .navbar-nav .nav-link { color: rgba(0, 0, 0, 0.5); }.navbar-light .navbar-nav .nav-link:focus, .navbar-light .navbar-nav .nav-link:hover { color: rgba(0, 0, 0, 0.7); }.navbar-light .navbar-nav .nav-link.disabled { color: rgba(0, 0, 0, 0.3); }.navbar-light .navbar-nav .active > .nav-link, .navbar-light .navbar-nav .nav-link.active, .navbar-light .navbar-nav .nav-link.show, .navbar-light .navbar-nav .show > .nav-link { color: rgba(0, 0, 0, 0.9); }.navbar-light .navbar-toggler { color: rgba(0, 0, 0, 0.5); border-color: rgba(0, 0, 0, 0.1); }.navbar-light .navbar-toggler-icon { background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E\"); }.navbar-light .navbar-text { color: rgba(0, 0, 0, 0.5); }.navbar-light .navbar-text a { color: rgba(0, 0, 0, 0.9); }.navbar-light .navbar-text a:focus, .navbar-light .navbar-text a:hover { color: rgba(0, 0, 0, 0.9); }.navbar-dark .navbar-brand { color: rgb(255, 255, 255); }.navbar-dark .navbar-brand:focus, .navbar-dark .navbar-brand:hover { color: rgb(255, 255, 255); }.navbar-dark .navbar-nav .nav-link { color: rgba(255, 255, 255, 0.5); }.navbar-dark .navbar-nav .nav-link:focus, .navbar-dark .navbar-nav .nav-link:hover { color: rgba(255, 255, 255, 0.75); }.navbar-dark .navbar-nav .nav-link.disabled { color: rgba(255, 255, 255, 0.25); }.navbar-dark .navbar-nav .active > .nav-link, .navbar-dark .navbar-nav .nav-link.active, .navbar-dark .navbar-nav .nav-link.show, .navbar-dark .navbar-nav .show > .nav-link { color: rgb(255, 255, 255); }.navbar-dark .navbar-toggler { color: rgba(255, 255, 255, 0.5); border-color: rgba(255, 255, 255, 0.1); }.navbar-dark .navbar-toggler-icon { background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E\"); }.navbar-dark .navbar-text { color: rgba(255, 255, 255, 0.5); }.navbar-dark .navbar-text a { color: rgb(255, 255, 255); }.navbar-dark .navbar-text a:focus, .navbar-dark .navbar-text a:hover { color: rgb(255, 255, 255); }.card { position: relative; display: flex; flex-direction: column; min-width: 0px; word-wrap: break-word; background-color: rgb(255, 255, 255); background-clip: border-box; border: 1px solid rgba(0, 0, 0, 0.125); border-radius: 0.25rem; }.card > hr { margin-right: 0px; margin-left: 0px; }.card > .list-group:first-child .list-group-item:first-child { border-top-left-radius: 0.25rem; border-top-right-radius: 0.25rem; }.card > .list-group:last-child .list-group-item:last-child { border-bottom-right-radius: 0.25rem; border-bottom-left-radius: 0.25rem; }.card-body { flex: 1 1 auto; padding: 1.25rem; }.card-title { margin-bottom: 0.75rem; }.card-subtitle { margin-top: -0.375rem; margin-bottom: 0px; }.card-text:last-child { margin-bottom: 0px; }.card-link:hover { text-decoration: none; }.card-link + .card-link { margin-left: 1.25rem; }.card-header { padding: 0.75rem 1.25rem; margin-bottom: 0px; background-color: rgba(0, 0, 0, 0.03); border-bottom: 1px solid rgba(0, 0, 0, 0.125); }.card-header:first-child { border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0px 0px; }.card-header + .list-group .list-group-item:first-child { border-top: 0px; }.card-footer { padding: 0.75rem 1.25rem; background-color: rgba(0, 0, 0, 0.03); border-top: 1px solid rgba(0, 0, 0, 0.125); }.card-footer:last-child { border-radius: 0px 0px calc(0.25rem - 1px) calc(0.25rem - 1px); }.card-header-tabs { margin-right: -0.625rem; margin-bottom: -0.75rem; margin-left: -0.625rem; border-bottom: 0px; }.card-header-pills { margin-right: -0.625rem; margin-left: -0.625rem; }.card-img-overlay { position: absolute; top: 0px; right: 0px; bottom: 0px; left: 0px; padding: 1.25rem; }.card-img { width: 100%; border-radius: calc(0.25rem - 1px); }.card-img-top { width: 100%; border-top-left-radius: calc(0.25rem - 1px); border-top-right-radius: calc(0.25rem - 1px); }.card-img-bottom { width: 100%; border-bottom-right-radius: calc(0.25rem - 1px); border-bottom-left-radius: calc(0.25rem - 1px); }.card-deck { display: flex; flex-direction: column; }.card-deck .card { margin-bottom: 15px; }@media (min-width: 576px) {\n .card-deck { flex-flow: row wrap; margin-right: -15px; margin-left: -15px; }\n .card-deck .card { display: flex; flex: 1 0 0%; flex-direction: column; margin-right: 15px; margin-bottom: 0px; margin-left: 15px; }\n}.card-group { display: flex; flex-direction: column; }.card-group > .card { margin-bottom: 15px; }@media (min-width: 576px) {\n .card-group { flex-flow: row wrap; }\n .card-group > .card { flex: 1 0 0%; margin-bottom: 0px; }\n .card-group > .card + .card { margin-left: 0px; border-left: 0px; }\n .card-group > .card:first-child { border-top-right-radius: 0px; border-bottom-right-radius: 0px; }\n .card-group > .card:first-child .card-header, .card-group > .card:first-child .card-img-top { border-top-right-radius: 0px; }\n .card-group > .card:first-child .card-footer, .card-group > .card:first-child .card-img-bottom { border-bottom-right-radius: 0px; }\n .card-group > .card:last-child { border-top-left-radius: 0px; border-bottom-left-radius: 0px; }\n .card-group > .card:last-child .card-header, .card-group > .card:last-child .card-img-top { border-top-left-radius: 0px; }\n .card-group > .card:last-child .card-footer, .card-group > .card:last-child .card-img-bottom { border-bottom-left-radius: 0px; }\n .card-group > .card:only-child { border-radius: 0.25rem; }\n .card-group > .card:only-child .card-header, .card-group > .card:only-child .card-img-top { border-top-left-radius: 0.25rem; border-top-right-radius: 0.25rem; }\n .card-group > .card:only-child .card-footer, .card-group > .card:only-child .card-img-bottom { border-bottom-right-radius: 0.25rem; border-bottom-left-radius: 0.25rem; }\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) { border-radius: 0px; }\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-footer, .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-header, .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom, .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-img-top { border-radius: 0px; }\n}.card-columns .card { margin-bottom: 0.75rem; }@media (min-width: 576px) {\n .card-columns { column-count: 3; column-gap: 1.25rem; orphans: 1; widows: 1; }\n .card-columns .card { display: inline-block; width: 100%; }\n}.accordion .card:not(:first-of-type):not(:last-of-type) { border-bottom: 0px; border-radius: 0px; }.accordion .card:not(:first-of-type) .card-header:first-child { border-radius: 0px; }.accordion .card:first-of-type { border-bottom: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; }.accordion .card:last-of-type { border-top-left-radius: 0px; border-top-right-radius: 0px; }.breadcrumb { display: flex; flex-wrap: wrap; padding: 0.75rem 1rem; margin-bottom: 1rem; list-style: none; background-color: rgb(233, 236, 239); border-radius: 0.25rem; }.breadcrumb-item + .breadcrumb-item { padding-left: 0.5rem; }.breadcrumb-item + .breadcrumb-item::before { display: inline-block; padding-right: 0.5rem; color: rgb(108, 117, 125); content: \"/\"; }.breadcrumb-item + .breadcrumb-item:hover::before { text-decoration: underline; }.breadcrumb-item + .breadcrumb-item:hover::before { text-decoration: none; }.breadcrumb-item.active { color: rgb(108, 117, 125); }.pagination { display: flex; padding-left: 0px; list-style: none; border-radius: 0.25rem; }.page-link { position: relative; display: block; padding: 0.5rem 0.75rem; margin-left: -1px; line-height: 1.25; color: rgb(0, 123, 255); background-color: rgb(255, 255, 255); border: 1px solid rgb(222, 226, 230); }.page-link:hover { z-index: 2; color: rgb(0, 86, 179); text-decoration: none; background-color: rgb(233, 236, 239); border-color: rgb(222, 226, 230); }.page-link:focus { z-index: 2; outline: 0px; box-shadow: rgba(0, 123, 255, 0.25) 0px 0px 0px 0.2rem; }.page-link:not(:disabled):not(.disabled) { cursor: pointer; }.page-item:first-child .page-link { margin-left: 0px; border-top-left-radius: 0.25rem; border-bottom-left-radius: 0.25rem; }.page-item:last-child .page-link { border-top-right-radius: 0.25rem; border-bottom-right-radius: 0.25rem; }.page-item.active .page-link { z-index: 1; color: rgb(255, 255, 255); background-color: rgb(0, 123, 255); border-color: rgb(0, 123, 255); }.page-item.disabled .page-link { color: rgb(108, 117, 125); pointer-events: none; cursor: auto; background-color: rgb(255, 255, 255); border-color: rgb(222, 226, 230); }.pagination-lg .page-link { padding: 0.75rem 1.5rem; font-size: 1.25rem; line-height: 1.5; }.pagination-lg .page-item:first-child .page-link { border-top-left-radius: 0.3rem; border-bottom-left-radius: 0.3rem; }.pagination-lg .page-item:last-child .page-link { border-top-right-radius: 0.3rem; border-bottom-right-radius: 0.3rem; }.pagination-sm .page-link { padding: 0.25rem 0.5rem; font-size: 0.875rem; line-height: 1.5; }.pagination-sm .page-item:first-child .page-link { border-top-left-radius: 0.2rem; border-bottom-left-radius: 0.2rem; }.pagination-sm .page-item:last-child .page-link { border-top-right-radius: 0.2rem; border-bottom-right-radius: 0.2rem; }.badge { display: inline-block; padding: 0.25em 0.4em; font-size: 75%; font-weight: 700; line-height: 1; text-align: center; white-space: nowrap; vertical-align: baseline; border-radius: 0.25rem; }.badge:empty { display: none; }.btn .badge { position: relative; top: -1px; }.badge-pill { padding-right: 0.6em; padding-left: 0.6em; border-radius: 10rem; }.badge-primary { color: rgb(255, 255, 255); background-color: rgb(0, 123, 255); }.badge-primary[href]:focus, .badge-primary[href]:hover { color: rgb(255, 255, 255); text-decoration: none; background-color: rgb(0, 98, 204); }.badge-secondary { color: rgb(255, 255, 255); background-color: rgb(108, 117, 125); }.badge-secondary[href]:focus, .badge-secondary[href]:hover { color: rgb(255, 255, 255); text-decoration: none; background-color: rgb(84, 91, 98); }.badge-success { color: rgb(255, 255, 255); background-color: rgb(40, 167, 69); }.badge-success[href]:focus, .badge-success[href]:hover { color: rgb(255, 255, 255); text-decoration: none; background-color: rgb(30, 126, 52); }.badge-info { color: rgb(255, 255, 255); background-color: rgb(23, 162, 184); }.badge-info[href]:focus, .badge-info[href]:hover { color: rgb(255, 255, 255); text-decoration: none; background-color: rgb(17, 122, 139); }.badge-warning { color: rgb(33, 37, 41); background-color: rgb(255, 193, 7); }.badge-warning[href]:focus, .badge-warning[href]:hover { color: rgb(33, 37, 41); text-decoration: none; background-color: rgb(211, 158, 0); }.badge-danger { color: rgb(255, 255, 255); background-color: rgb(220, 53, 69); }.badge-danger[href]:focus, .badge-danger[href]:hover { color: rgb(255, 255, 255); text-decoration: none; background-color: rgb(189, 33, 48); }.badge-light { color: rgb(33, 37, 41); background-color: rgb(248, 249, 250); }.badge-light[href]:focus, .badge-light[href]:hover { color: rgb(33, 37, 41); text-decoration: none; background-color: rgb(218, 224, 229); }.badge-dark { color: rgb(255, 255, 255); background-color: rgb(52, 58, 64); }.badge-dark[href]:focus, .badge-dark[href]:hover { color: rgb(255, 255, 255); text-decoration: none; background-color: rgb(29, 33, 36); }.jumbotron { padding: 2rem 1rem; margin-bottom: 2rem; background-color: rgb(233, 236, 239); border-radius: 0.3rem; }@media (min-width: 576px) {\n .jumbotron { padding: 4rem 2rem; }\n}.jumbotron-fluid { padding-right: 0px; padding-left: 0px; border-radius: 0px; }.alert { position: relative; padding: 0.75rem 1.25rem; margin-bottom: 1rem; border: 1px solid transparent; border-radius: 0.25rem; }.alert-heading { color: inherit; }.alert-link { font-weight: 700; }.alert-dismissible { padding-right: 4rem; }.alert-dismissible .close { position: absolute; top: 0px; right: 0px; padding: 0.75rem 1.25rem; color: inherit; }.alert-primary { color: rgb(0, 64, 133); background-color: rgb(204, 229, 255); border-color: rgb(184, 218, 255); }.alert-primary hr { border-top-color: rgb(159, 205, 255); }.alert-primary .alert-link { color: rgb(0, 39, 82); }.alert-secondary { color: rgb(56, 61, 65); background-color: rgb(226, 227, 229); border-color: rgb(214, 216, 219); }.alert-secondary hr { border-top-color: rgb(200, 203, 207); }.alert-secondary .alert-link { color: rgb(32, 35, 38); }.alert-success { color: rgb(21, 87, 36); background-color: rgb(212, 237, 218); border-color: rgb(195, 230, 203); }.alert-success hr { border-top-color: rgb(177, 223, 187); }.alert-success .alert-link { color: rgb(11, 46, 19); }.alert-info { color: rgb(12, 84, 96); background-color: rgb(209, 236, 241); border-color: rgb(190, 229, 235); }.alert-info hr { border-top-color: rgb(171, 221, 229); }.alert-info .alert-link { color: rgb(6, 44, 51); }.alert-warning { color: rgb(133, 100, 4); background-color: rgb(255, 243, 205); border-color: rgb(255, 238, 186); }.alert-warning hr { border-top-color: rgb(255, 232, 161); }.alert-warning .alert-link { color: rgb(83, 63, 3); }.alert-danger { color: rgb(114, 28, 36); background-color: rgb(248, 215, 218); border-color: rgb(245, 198, 203); }.alert-danger hr { border-top-color: rgb(241, 176, 183); }.alert-danger .alert-link { color: rgb(73, 18, 23); }.alert-light { color: rgb(129, 129, 130); background-color: rgb(254, 254, 254); border-color: rgb(253, 253, 254); }.alert-light hr { border-top-color: rgb(236, 236, 246); }.alert-light .alert-link { color: rgb(104, 104, 104); }.alert-dark { color: rgb(27, 30, 33); background-color: rgb(214, 216, 217); border-color: rgb(198, 200, 202); }.alert-dark hr { border-top-color: rgb(185, 187, 190); }.alert-dark .alert-link { color: rgb(4, 5, 5); }@-webkit-keyframes progress-bar-stripes { \n 0% { background-position: 1rem 0px; }\n 100% { background-position: 0px 0px; }\n}@keyframes progress-bar-stripes { \n 0% { background-position: 1rem 0px; }\n 100% { background-position: 0px 0px; }\n}.progress { display: flex; height: 1rem; overflow: hidden; font-size: 0.75rem; background-color: rgb(233, 236, 239); border-radius: 0.25rem; }.progress-bar { display: flex; flex-direction: column; justify-content: center; color: rgb(255, 255, 255); text-align: center; white-space: nowrap; background-color: rgb(0, 123, 255); transition: width 0.6s ease 0s; }@media not all {\n .progress-bar { transition: none 0s ease 0s; }\n}.progress-bar-striped { background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-size: 1rem 1rem; }.progress-bar-animated { animation: progress-bar-stripes 1s linear 0s infinite normal none running; }.media { display: flex; align-items: flex-start; }.media-body { flex: 1 1 0%; }.list-group { display: flex; flex-direction: column; padding-left: 0px; margin-bottom: 0px; }.list-group-item-action { width: 100%; color: rgb(73, 80, 87); text-align: inherit; }.list-group-item-action:focus, .list-group-item-action:hover { color: rgb(73, 80, 87); text-decoration: none; background-color: rgb(248, 249, 250); }.list-group-item-action:active { color: rgb(33, 37, 41); background-color: rgb(233, 236, 239); }.list-group-item { position: relative; display: block; padding: 0.75rem 1.25rem; margin-bottom: -1px; background-color: rgb(255, 255, 255); border: 1px solid rgba(0, 0, 0, 0.125); }.list-group-item:first-child { border-top-left-radius: 0.25rem; border-top-right-radius: 0.25rem; }.list-group-item:last-child { margin-bottom: 0px; border-bottom-right-radius: 0.25rem; border-bottom-left-radius: 0.25rem; }.list-group-item:focus, .list-group-item:hover { z-index: 1; text-decoration: none; }.list-group-item.disabled, .list-group-item:disabled { color: rgb(108, 117, 125); background-color: rgb(255, 255, 255); }.list-group-item.active { z-index: 2; color: rgb(255, 255, 255); background-color: rgb(0, 123, 255); border-color: rgb(0, 123, 255); }.list-group-flush .list-group-item { border-right: 0px; border-left: 0px; border-radius: 0px; }.list-group-flush:first-child .list-group-item:first-child { border-top: 0px; }.list-group-flush:last-child .list-group-item:last-child { border-bottom: 0px; }.list-group-item-primary { color: rgb(0, 64, 133); background-color: rgb(184, 218, 255); }.list-group-item-primary.list-group-item-action:focus, .list-group-item-primary.list-group-item-action:hover { color: rgb(0, 64, 133); background-color: rgb(159, 205, 255); }.list-group-item-primary.list-group-item-action.active { color: rgb(255, 255, 255); background-color: rgb(0, 64, 133); border-color: rgb(0, 64, 133); }.list-group-item-secondary { color: rgb(56, 61, 65); background-color: rgb(214, 216, 219); }.list-group-item-secondary.list-group-item-action:focus, .list-group-item-secondary.list-group-item-action:hover { color: rgb(56, 61, 65); background-color: rgb(200, 203, 207); }.list-group-item-secondary.list-group-item-action.active { color: rgb(255, 255, 255); background-color: rgb(56, 61, 65); border-color: rgb(56, 61, 65); }.list-group-item-success { color: rgb(21, 87, 36); background-color: rgb(195, 230, 203); }.list-group-item-success.list-group-item-action:focus, .list-group-item-success.list-group-item-action:hover { color: rgb(21, 87, 36); background-color: rgb(177, 223, 187); }.list-group-item-success.list-group-item-action.active { color: rgb(255, 255, 255); background-color: rgb(21, 87, 36); border-color: rgb(21, 87, 36); }.list-group-item-info { color: rgb(12, 84, 96); background-color: rgb(190, 229, 235); }.list-group-item-info.list-group-item-action:focus, .list-group-item-info.list-group-item-action:hover { color: rgb(12, 84, 96); background-color: rgb(171, 221, 229); }.list-group-item-info.list-group-item-action.active { color: rgb(255, 255, 255); background-color: rgb(12, 84, 96); border-color: rgb(12, 84, 96); }.list-group-item-warning { color: rgb(133, 100, 4); background-color: rgb(255, 238, 186); }.list-group-item-warning.list-group-item-action:focus, .list-group-item-warning.list-group-item-action:hover { color: rgb(133, 100, 4); background-color: rgb(255, 232, 161); }.list-group-item-warning.list-group-item-action.active { color: rgb(255, 255, 255); background-color: rgb(133, 100, 4); border-color: rgb(133, 100, 4); }.list-group-item-danger { color: rgb(114, 28, 36); background-color: rgb(245, 198, 203); }.list-group-item-danger.list-group-item-action:focus, .list-group-item-danger.list-group-item-action:hover { color: rgb(114, 28, 36); background-color: rgb(241, 176, 183); }.list-group-item-danger.list-group-item-action.active { color: rgb(255, 255, 255); background-color: rgb(114, 28, 36); border-color: rgb(114, 28, 36); }.list-group-item-light { color: rgb(129, 129, 130); background-color: rgb(253, 253, 254); }.list-group-item-light.list-group-item-action:focus, .list-group-item-light.list-group-item-action:hover { color: rgb(129, 129, 130); background-color: rgb(236, 236, 246); }.list-group-item-light.list-group-item-action.active { color: rgb(255, 255, 255); background-color: rgb(129, 129, 130); border-color: rgb(129, 129, 130); }.list-group-item-dark { color: rgb(27, 30, 33); background-color: rgb(198, 200, 202); }.list-group-item-dark.list-group-item-action:focus, .list-group-item-dark.list-group-item-action:hover { color: rgb(27, 30, 33); background-color: rgb(185, 187, 190); }.list-group-item-dark.list-group-item-action.active { color: rgb(255, 255, 255); background-color: rgb(27, 30, 33); border-color: rgb(27, 30, 33); }.close { float: right; font-size: 1.5rem; font-weight: 700; line-height: 1; color: rgb(0, 0, 0); text-shadow: rgb(255, 255, 255) 0px 1px 0px; opacity: 0.5; }.close:not(:disabled):not(.disabled) { cursor: pointer; }.close:not(:disabled):not(.disabled):focus, .close:not(:disabled):not(.disabled):hover { color: rgb(0, 0, 0); text-decoration: none; opacity: 0.75; }button.close { padding: 0px; background-color: transparent; border: 0px; -webkit-appearance: none; }.modal-open { overflow: hidden; }.modal-open .modal { overflow: hidden auto; }.modal { position: fixed; top: 0px; right: 0px; bottom: 0px; left: 0px; z-index: 1050; display: none; overflow: hidden; outline: 0px; }.modal-dialog { position: relative; width: auto; margin: 0.5rem; pointer-events: none; }.modal.fade .modal-dialog { transition: transform 0.3s ease-out 0s, -webkit-transform 0.3s ease-out 0s; transform: translate(0px, -25%); }@media not all {\n .modal.fade .modal-dialog { transition: none 0s ease 0s; }\n}.modal.show .modal-dialog { transform: translate(0px, 0px); }.modal-dialog-centered { display: flex; align-items: center; min-height: calc(100% - 1rem); }.modal-dialog-centered::before { display: block; height: calc(100vh - 1rem); content: \"\"; }.modal-content { position: relative; display: flex; flex-direction: column; width: 100%; pointer-events: auto; background-color: rgb(255, 255, 255); background-clip: padding-box; border: 1px solid rgba(0, 0, 0, 0.2); border-radius: 0.3rem; outline: 0px; }.modal-backdrop { position: fixed; top: 0px; right: 0px; bottom: 0px; left: 0px; z-index: 1040; background-color: rgb(0, 0, 0); }.modal-backdrop.fade { opacity: 0; }.modal-backdrop.show { opacity: 0.5; }.modal-header { display: flex; align-items: flex-start; justify-content: space-between; padding: 1rem; border-bottom: 1px solid rgb(233, 236, 239); border-top-left-radius: 0.3rem; border-top-right-radius: 0.3rem; }.modal-header .close { padding: 1rem; margin: -1rem -1rem -1rem auto; }.modal-title { margin-bottom: 0px; line-height: 1.5; }.modal-body { position: relative; flex: 1 1 auto; padding: 1rem; }.modal-footer { display: flex; align-items: center; justify-content: flex-end; padding: 1rem; border-top: 1px solid rgb(233, 236, 239); }.modal-footer > :not(:first-child) { margin-left: 0.25rem; }.modal-footer > :not(:last-child) { margin-right: 0.25rem; }.modal-scrollbar-measure { position: absolute; top: -9999px; width: 50px; height: 50px; overflow: scroll; }@media (min-width: 576px) {\n .modal-dialog { max-width: 500px; margin: 1.75rem auto; }\n .modal-dialog-centered { min-height: calc(100% - 3.5rem); }\n .modal-dialog-centered::before { height: calc(100vh - 3.5rem); }\n .modal-sm { max-width: 300px; }\n}@media (min-width: 992px) {\n .modal-lg { max-width: 800px; }\n}.tooltip { position: absolute; z-index: 1070; display: block; margin: 0px; font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\"; font-style: normal; font-weight: 400; line-height: 1.5; text-align: start; text-decoration: none; text-shadow: none; text-transform: none; letter-spacing: normal; word-break: normal; word-spacing: normal; white-space: normal; line-break: auto; font-size: 0.875rem; word-wrap: break-word; opacity: 0; }.tooltip.show { opacity: 0.9; }.tooltip .arrow { position: absolute; display: block; width: 0.8rem; height: 0.4rem; }.tooltip .arrow::before { position: absolute; content: \"\"; border-color: transparent; border-style: solid; }.bs-tooltip-auto[x-placement^=\"top\"], .bs-tooltip-top { padding: 0.4rem 0px; }.bs-tooltip-auto[x-placement^=\"top\"] .arrow, .bs-tooltip-top .arrow { bottom: 0px; }.bs-tooltip-auto[x-placement^=\"top\"] .arrow::before, .bs-tooltip-top .arrow::before { top: 0px; border-width: 0.4rem 0.4rem 0px; border-top-color: rgb(0, 0, 0); }.bs-tooltip-auto[x-placement^=\"right\"], .bs-tooltip-right { padding: 0px 0.4rem; }.bs-tooltip-auto[x-placement^=\"right\"] .arrow, .bs-tooltip-right .arrow { left: 0px; width: 0.4rem; height: 0.8rem; }.bs-tooltip-auto[x-placement^=\"right\"] .arrow::before, .bs-tooltip-right .arrow::before { right: 0px; border-width: 0.4rem 0.4rem 0.4rem 0px; border-right-color: rgb(0, 0, 0); }.bs-tooltip-auto[x-placement^=\"bottom\"], .bs-tooltip-bottom { padding: 0.4rem 0px; }.bs-tooltip-auto[x-placement^=\"bottom\"] .arrow, .bs-tooltip-bottom .arrow { top: 0px; }.bs-tooltip-auto[x-placement^=\"bottom\"] .arrow::before, .bs-tooltip-bottom .arrow::before { bottom: 0px; border-width: 0px 0.4rem 0.4rem; border-bottom-color: rgb(0, 0, 0); }.bs-tooltip-auto[x-placement^=\"left\"], .bs-tooltip-left { padding: 0px 0.4rem; }.bs-tooltip-auto[x-placement^=\"left\"] .arrow, .bs-tooltip-left .arrow { right: 0px; width: 0.4rem; height: 0.8rem; }.bs-tooltip-auto[x-placement^=\"left\"] .arrow::before, .bs-tooltip-left .arrow::before { left: 0px; border-width: 0.4rem 0px 0.4rem 0.4rem; border-left-color: rgb(0, 0, 0); }.tooltip-inner { max-width: 200px; padding: 0.25rem 0.5rem; color: rgb(255, 255, 255); text-align: center; background-color: rgb(0, 0, 0); border-radius: 0.25rem; }.popover { position: absolute; top: 0px; left: 0px; z-index: 1060; display: block; max-width: 276px; font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\"; font-style: normal; font-weight: 400; line-height: 1.5; text-align: start; text-decoration: none; text-shadow: none; text-transform: none; letter-spacing: normal; word-break: normal; word-spacing: normal; white-space: normal; line-break: auto; font-size: 0.875rem; word-wrap: break-word; background-color: rgb(255, 255, 255); background-clip: padding-box; border: 1px solid rgba(0, 0, 0, 0.2); border-radius: 0.3rem; }.popover .arrow { position: absolute; display: block; width: 1rem; height: 0.5rem; margin: 0px 0.3rem; }.popover .arrow::after, .popover .arrow::before { position: absolute; display: block; content: \"\"; border-color: transparent; border-style: solid; }.bs-popover-auto[x-placement^=\"top\"], .bs-popover-top { margin-bottom: 0.5rem; }.bs-popover-auto[x-placement^=\"top\"] .arrow, .bs-popover-top .arrow { bottom: calc((0.5rem + 1px) * -1); }.bs-popover-auto[x-placement^=\"top\"] .arrow::after, .bs-popover-auto[x-placement^=\"top\"] .arrow::before, .bs-popover-top .arrow::after, .bs-popover-top .arrow::before { border-width: 0.5rem 0.5rem 0px; }.bs-popover-auto[x-placement^=\"top\"] .arrow::before, .bs-popover-top .arrow::before { bottom: 0px; border-top-color: rgba(0, 0, 0, 0.25); }.bs-popover-auto[x-placement^=\"top\"] .arrow::after, .bs-popover-top .arrow::after { bottom: 1px; border-top-color: rgb(255, 255, 255); }.bs-popover-auto[x-placement^=\"right\"], .bs-popover-right { margin-left: 0.5rem; }.bs-popover-auto[x-placement^=\"right\"] .arrow, .bs-popover-right .arrow { left: calc((0.5rem + 1px) * -1); width: 0.5rem; height: 1rem; margin: 0.3rem 0px; }.bs-popover-auto[x-placement^=\"right\"] .arrow::after, .bs-popover-auto[x-placement^=\"right\"] .arrow::before, .bs-popover-right .arrow::after, .bs-popover-right .arrow::before { border-width: 0.5rem 0.5rem 0.5rem 0px; }.bs-popover-auto[x-placement^=\"right\"] .arrow::before, .bs-popover-right .arrow::before { left: 0px; border-right-color: rgba(0, 0, 0, 0.25); }.bs-popover-auto[x-placement^=\"right\"] .arrow::after, .bs-popover-right .arrow::after { left: 1px; border-right-color: rgb(255, 255, 255); }.bs-popover-auto[x-placement^=\"bottom\"], .bs-popover-bottom { margin-top: 0.5rem; }.bs-popover-auto[x-placement^=\"bottom\"] .arrow, .bs-popover-bottom .arrow { top: calc((0.5rem + 1px) * -1); }.bs-popover-auto[x-placement^=\"bottom\"] .arrow::after, .bs-popover-auto[x-placement^=\"bottom\"] .arrow::before, .bs-popover-bottom .arrow::after, .bs-popover-bottom .arrow::before { border-width: 0px 0.5rem 0.5rem; }.bs-popover-auto[x-placement^=\"bottom\"] .arrow::before, .bs-popover-bottom .arrow::before { top: 0px; border-bottom-color: rgba(0, 0, 0, 0.25); }.bs-popover-auto[x-placement^=\"bottom\"] .arrow::after, .bs-popover-bottom .arrow::after { top: 1px; border-bottom-color: rgb(255, 255, 255); }.bs-popover-auto[x-placement^=\"bottom\"] .popover-header::before, .bs-popover-bottom .popover-header::before { position: absolute; top: 0px; left: 50%; display: block; width: 1rem; margin-left: -0.5rem; content: \"\"; border-bottom: 1px solid rgb(247, 247, 247); }.bs-popover-auto[x-placement^=\"left\"], .bs-popover-left { margin-right: 0.5rem; }.bs-popover-auto[x-placement^=\"left\"] .arrow, .bs-popover-left .arrow { right: calc((0.5rem + 1px) * -1); width: 0.5rem; height: 1rem; margin: 0.3rem 0px; }.bs-popover-auto[x-placement^=\"left\"] .arrow::after, .bs-popover-auto[x-placement^=\"left\"] .arrow::before, .bs-popover-left .arrow::after, .bs-popover-left .arrow::before { border-width: 0.5rem 0px 0.5rem 0.5rem; }.bs-popover-auto[x-placement^=\"left\"] .arrow::before, .bs-popover-left .arrow::before { right: 0px; border-left-color: rgba(0, 0, 0, 0.25); }.bs-popover-auto[x-placement^=\"left\"] .arrow::after, .bs-popover-left .arrow::after { right: 1px; border-left-color: rgb(255, 255, 255); }.popover-header { padding: 0.5rem 0.75rem; margin-bottom: 0px; font-size: 1rem; color: inherit; background-color: rgb(247, 247, 247); border-bottom: 1px solid rgb(235, 235, 235); border-top-left-radius: calc(0.3rem - 1px); border-top-right-radius: calc(0.3rem - 1px); }.popover-header:empty { display: none; }.popover-body { padding: 0.5rem 0.75rem; color: rgb(33, 37, 41); }.carousel { position: relative; }.carousel-inner { position: relative; width: 100%; overflow: hidden; }.carousel-item { position: relative; display: none; align-items: center; width: 100%; backface-visibility: hidden; perspective: 1000px; }.carousel-item-next, .carousel-item-prev, .carousel-item.active { display: block; transition: transform 0.6s ease 0s, -webkit-transform 0.6s ease 0s; }@media not all {\n .carousel-item-next, .carousel-item-prev, .carousel-item.active { transition: none 0s ease 0s; }\n}.carousel-item-next, .carousel-item-prev { position: absolute; top: 0px; }.carousel-item-next.carousel-item-left, .carousel-item-prev.carousel-item-right { transform: translateX(0px); }@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)) {\n .carousel-item-next.carousel-item-left, .carousel-item-prev.carousel-item-right { transform: translate3d(0px, 0px, 0px); }\n}.active.carousel-item-right, .carousel-item-next { transform: translateX(100%); }@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)) {\n .active.carousel-item-right, .carousel-item-next { transform: translate3d(100%, 0px, 0px); }\n}.active.carousel-item-left, .carousel-item-prev { transform: translateX(-100%); }@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)) {\n .active.carousel-item-left, .carousel-item-prev { transform: translate3d(-100%, 0px, 0px); }\n}.carousel-fade .carousel-item { opacity: 0; transition-duration: 0.6s; transition-property: opacity; }.carousel-fade .carousel-item-next.carousel-item-left, .carousel-fade .carousel-item-prev.carousel-item-right, .carousel-fade .carousel-item.active { opacity: 1; }.carousel-fade .active.carousel-item-left, .carousel-fade .active.carousel-item-right { opacity: 0; }.carousel-fade .active.carousel-item-left, .carousel-fade .active.carousel-item-prev, .carousel-fade .carousel-item-next, .carousel-fade .carousel-item-prev, .carousel-fade .carousel-item.active { transform: translateX(0px); }@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)) {\n .carousel-fade .active.carousel-item-left, .carousel-fade .active.carousel-item-prev, .carousel-fade .carousel-item-next, .carousel-fade .carousel-item-prev, .carousel-fade .carousel-item.active { transform: translate3d(0px, 0px, 0px); }\n}.carousel-control-next, .carousel-control-prev { position: absolute; top: 0px; bottom: 0px; display: flex; align-items: center; justify-content: center; width: 15%; color: rgb(255, 255, 255); text-align: center; opacity: 0.5; }.carousel-control-next:focus, .carousel-control-next:hover, .carousel-control-prev:focus, .carousel-control-prev:hover { color: rgb(255, 255, 255); text-decoration: none; outline: 0px; opacity: 0.9; }.carousel-control-prev { left: 0px; }.carousel-control-next { right: 0px; }.carousel-control-next-icon, .carousel-control-prev-icon { display: inline-block; width: 20px; height: 20px; background: center center / 100% 100% no-repeat transparent; }.carousel-control-prev-icon { background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E\"); }.carousel-control-next-icon { background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E\"); }.carousel-indicators { position: absolute; right: 0px; bottom: 10px; left: 0px; z-index: 15; display: flex; justify-content: center; padding-left: 0px; margin-right: 15%; margin-left: 15%; list-style: none; }.carousel-indicators li { position: relative; flex: 0 1 auto; width: 30px; height: 3px; margin-right: 3px; margin-left: 3px; text-indent: -999px; cursor: pointer; background-color: rgba(255, 255, 255, 0.5); }.carousel-indicators li::before { position: absolute; top: -10px; left: 0px; display: inline-block; width: 100%; height: 10px; content: \"\"; }.carousel-indicators li::after { position: absolute; bottom: -10px; left: 0px; display: inline-block; width: 100%; height: 10px; content: \"\"; }.carousel-indicators .active { background-color: rgb(255, 255, 255); }.carousel-caption { position: absolute; right: 15%; bottom: 20px; left: 15%; z-index: 10; padding-top: 20px; padding-bottom: 20px; color: rgb(255, 255, 255); text-align: center; }.align-baseline { vertical-align: baseline !important; }.align-top { vertical-align: top !important; }.align-middle { vertical-align: middle !important; }.align-bottom { vertical-align: bottom !important; }.align-text-bottom { vertical-align: text-bottom !important; }.align-text-top { vertical-align: text-top !important; }.bg-primary { background-color: rgb(0, 123, 255) !important; }a.bg-primary:focus, a.bg-primary:hover, button.bg-primary:focus, button.bg-primary:hover { background-color: rgb(0, 98, 204) !important; }.bg-secondary { background-color: rgb(108, 117, 125) !important; }a.bg-secondary:focus, a.bg-secondary:hover, button.bg-secondary:focus, button.bg-secondary:hover { background-color: rgb(84, 91, 98) !important; }.bg-success { background-color: rgb(40, 167, 69) !important; }a.bg-success:focus, a.bg-success:hover, button.bg-success:focus, button.bg-success:hover { background-color: rgb(30, 126, 52) !important; }.bg-info { background-color: rgb(23, 162, 184) !important; }a.bg-info:focus, a.bg-info:hover, button.bg-info:focus, button.bg-info:hover { background-color: rgb(17, 122, 139) !important; }.bg-warning { background-color: rgb(255, 193, 7) !important; }a.bg-warning:focus, a.bg-warning:hover, button.bg-warning:focus, button.bg-warning:hover { background-color: rgb(211, 158, 0) !important; }.bg-danger { background-color: rgb(220, 53, 69) !important; }a.bg-danger:focus, a.bg-danger:hover, button.bg-danger:focus, button.bg-danger:hover { background-color: rgb(189, 33, 48) !important; }.bg-light { background-color: rgb(248, 249, 250) !important; }a.bg-light:focus, a.bg-light:hover, button.bg-light:focus, button.bg-light:hover { background-color: rgb(218, 224, 229) !important; }.bg-dark { background-color: rgb(52, 58, 64) !important; }a.bg-dark:focus, a.bg-dark:hover, button.bg-dark:focus, button.bg-dark:hover { background-color: rgb(29, 33, 36) !important; }.bg-white { background-color: rgb(255, 255, 255) !important; }.bg-transparent { background-color: transparent !important; }.border { border: 1px solid rgb(222, 226, 230) !important; }.border-top { border-top: 1px solid rgb(222, 226, 230) !important; }.border-right { border-right: 1px solid rgb(222, 226, 230) !important; }.border-bottom { border-bottom: 1px solid rgb(222, 226, 230) !important; }.border-left { border-left: 1px solid rgb(222, 226, 230) !important; }.border-0 { border: 0px !important; }.border-top-0 { border-top: 0px !important; }.border-right-0 { border-right: 0px !important; }.border-bottom-0 { border-bottom: 0px !important; }.border-left-0 { border-left: 0px !important; }.border-primary { border-color: rgb(0, 123, 255) !important; }.border-secondary { border-color: rgb(108, 117, 125) !important; }.border-success { border-color: rgb(40, 167, 69) !important; }.border-info { border-color: rgb(23, 162, 184) !important; }.border-warning { border-color: rgb(255, 193, 7) !important; }.border-danger { border-color: rgb(220, 53, 69) !important; }.border-light { border-color: rgb(248, 249, 250) !important; }.border-dark { border-color: rgb(52, 58, 64) !important; }.border-white { border-color: rgb(255, 255, 255) !important; }.rounded { border-radius: 0.25rem !important; }.rounded-top { border-top-left-radius: 0.25rem !important; border-top-right-radius: 0.25rem !important; }.rounded-right { border-top-right-radius: 0.25rem !important; border-bottom-right-radius: 0.25rem !important; }.rounded-bottom { border-bottom-right-radius: 0.25rem !important; border-bottom-left-radius: 0.25rem !important; }.rounded-left { border-top-left-radius: 0.25rem !important; border-bottom-left-radius: 0.25rem !important; }.rounded-circle { border-radius: 50% !important; }.rounded-0 { border-radius: 0px !important; }.clearfix::after { display: block; clear: both; content: \"\"; }.d-none { display: none !important; }.d-inline { display: inline !important; }.d-inline-block { display: inline-block !important; }.d-block { display: block !important; }.d-table { display: table !important; }.d-table-row { display: table-row !important; }.d-table-cell { display: table-cell !important; }.d-flex { display: flex !important; }.d-inline-flex { display: inline-flex !important; }@media (min-width: 576px) {\n .d-sm-none { display: none !important; }\n .d-sm-inline { display: inline !important; }\n .d-sm-inline-block { display: inline-block !important; }\n .d-sm-block { display: block !important; }\n .d-sm-table { display: table !important; }\n .d-sm-table-row { display: table-row !important; }\n .d-sm-table-cell { display: table-cell !important; }\n .d-sm-flex { display: flex !important; }\n .d-sm-inline-flex { display: inline-flex !important; }\n}@media (min-width: 768px) {\n .d-md-none { display: none !important; }\n .d-md-inline { display: inline !important; }\n .d-md-inline-block { display: inline-block !important; }\n .d-md-block { display: block !important; }\n .d-md-table { display: table !important; }\n .d-md-table-row { display: table-row !important; }\n .d-md-table-cell { display: table-cell !important; }\n .d-md-flex { display: flex !important; }\n .d-md-inline-flex { display: inline-flex !important; }\n}@media (min-width: 992px) {\n .d-lg-none { display: none !important; }\n .d-lg-inline { display: inline !important; }\n .d-lg-inline-block { display: inline-block !important; }\n .d-lg-block { display: block !important; }\n .d-lg-table { display: table !important; }\n .d-lg-table-row { display: table-row !important; }\n .d-lg-table-cell { display: table-cell !important; }\n .d-lg-flex { display: flex !important; }\n .d-lg-inline-flex { display: inline-flex !important; }\n}@media (min-width: 1200px) {\n .d-xl-none { display: none !important; }\n .d-xl-inline { display: inline !important; }\n .d-xl-inline-block { display: inline-block !important; }\n .d-xl-block { display: block !important; }\n .d-xl-table { display: table !important; }\n .d-xl-table-row { display: table-row !important; }\n .d-xl-table-cell { display: table-cell !important; }\n .d-xl-flex { display: flex !important; }\n .d-xl-inline-flex { display: inline-flex !important; }\n}@media print {\n .d-print-none { display: none !important; }\n .d-print-inline { display: inline !important; }\n .d-print-inline-block { display: inline-block !important; }\n .d-print-block { display: block !important; }\n .d-print-table { display: table !important; }\n .d-print-table-row { display: table-row !important; }\n .d-print-table-cell { display: table-cell !important; }\n .d-print-flex { display: flex !important; }\n .d-print-inline-flex { display: inline-flex !important; }\n}.embed-responsive { position: relative; display: block; width: 100%; padding: 0px; overflow: hidden; }.embed-responsive::before { display: block; content: \"\"; }.embed-responsive .embed-responsive-item, .embed-responsive embed, .embed-responsive iframe, .embed-responsive object, .embed-responsive video { position: absolute; top: 0px; bottom: 0px; left: 0px; width: 100%; height: 100%; border: 0px; }.embed-responsive-21by9::before { padding-top: 42.8571%; }.embed-responsive-16by9::before { padding-top: 56.25%; }.embed-responsive-4by3::before { padding-top: 75%; }.embed-responsive-1by1::before { padding-top: 100%; }.flex-row { flex-direction: row !important; }.flex-column { flex-direction: column !important; }.flex-row-reverse { flex-direction: row-reverse !important; }.flex-column-reverse { flex-direction: column-reverse !important; }.flex-wrap { flex-wrap: wrap !important; }.flex-nowrap { flex-wrap: nowrap !important; }.flex-wrap-reverse { flex-wrap: wrap-reverse !important; }.flex-fill { flex: 1 1 auto !important; }.flex-grow-0 { flex-grow: 0 !important; }.flex-grow-1 { flex-grow: 1 !important; }.flex-shrink-0 { flex-shrink: 0 !important; }.flex-shrink-1 { flex-shrink: 1 !important; }.justify-content-start { justify-content: flex-start !important; }.justify-content-end { justify-content: flex-end !important; }.justify-content-center { justify-content: center !important; }.justify-content-between { justify-content: space-between !important; }.justify-content-around { justify-content: space-around !important; }.align-items-start { align-items: flex-start !important; }.align-items-end { align-items: flex-end !important; }.align-items-center { align-items: center !important; }.align-items-baseline { align-items: baseline !important; }.align-items-stretch { align-items: stretch !important; }.align-content-start { align-content: flex-start !important; }.align-content-end { align-content: flex-end !important; }.align-content-center { align-content: center !important; }.align-content-between { align-content: space-between !important; }.align-content-around { align-content: space-around !important; }.align-content-stretch { align-content: stretch !important; }.align-self-auto { align-self: auto !important; }.align-self-start { align-self: flex-start !important; }.align-self-end { align-self: flex-end !important; }.align-self-center { align-self: center !important; }.align-self-baseline { align-self: baseline !important; }.align-self-stretch { align-self: stretch !important; }@media (min-width: 576px) {\n .flex-sm-row { flex-direction: row !important; }\n .flex-sm-column { flex-direction: column !important; }\n .flex-sm-row-reverse { flex-direction: row-reverse !important; }\n .flex-sm-column-reverse { flex-direction: column-reverse !important; }\n .flex-sm-wrap { flex-wrap: wrap !important; }\n .flex-sm-nowrap { flex-wrap: nowrap !important; }\n .flex-sm-wrap-reverse { flex-wrap: wrap-reverse !important; }\n .flex-sm-fill { flex: 1 1 auto !important; }\n .flex-sm-grow-0 { flex-grow: 0 !important; }\n .flex-sm-grow-1 { flex-grow: 1 !important; }\n .flex-sm-shrink-0 { flex-shrink: 0 !important; }\n .flex-sm-shrink-1 { flex-shrink: 1 !important; }\n .justify-content-sm-start { justify-content: flex-start !important; }\n .justify-content-sm-end { justify-content: flex-end !important; }\n .justify-content-sm-center { justify-content: center !important; }\n .justify-content-sm-between { justify-content: space-between !important; }\n .justify-content-sm-around { justify-content: space-around !important; }\n .align-items-sm-start { align-items: flex-start !important; }\n .align-items-sm-end { align-items: flex-end !important; }\n .align-items-sm-center { align-items: center !important; }\n .align-items-sm-baseline { align-items: baseline !important; }\n .align-items-sm-stretch { align-items: stretch !important; }\n .align-content-sm-start { align-content: flex-start !important; }\n .align-content-sm-end { align-content: flex-end !important; }\n .align-content-sm-center { align-content: center !important; }\n .align-content-sm-between { align-content: space-between !important; }\n .align-content-sm-around { align-content: space-around !important; }\n .align-content-sm-stretch { align-content: stretch !important; }\n .align-self-sm-auto { align-self: auto !important; }\n .align-self-sm-start { align-self: flex-start !important; }\n .align-self-sm-end { align-self: flex-end !important; }\n .align-self-sm-center { align-self: center !important; }\n .align-self-sm-baseline { align-self: baseline !important; }\n .align-self-sm-stretch { align-self: stretch !important; }\n}@media (min-width: 768px) {\n .flex-md-row { flex-direction: row !important; }\n .flex-md-column { flex-direction: column !important; }\n .flex-md-row-reverse { flex-direction: row-reverse !important; }\n .flex-md-column-reverse { flex-direction: column-reverse !important; }\n .flex-md-wrap { flex-wrap: wrap !important; }\n .flex-md-nowrap { flex-wrap: nowrap !important; }\n .flex-md-wrap-reverse { flex-wrap: wrap-reverse !important; }\n .flex-md-fill { flex: 1 1 auto !important; }\n .flex-md-grow-0 { flex-grow: 0 !important; }\n .flex-md-grow-1 { flex-grow: 1 !important; }\n .flex-md-shrink-0 { flex-shrink: 0 !important; }\n .flex-md-shrink-1 { flex-shrink: 1 !important; }\n .justify-content-md-start { justify-content: flex-start !important; }\n .justify-content-md-end { justify-content: flex-end !important; }\n .justify-content-md-center { justify-content: center !important; }\n .justify-content-md-between { justify-content: space-between !important; }\n .justify-content-md-around { justify-content: space-around !important; }\n .align-items-md-start { align-items: flex-start !important; }\n .align-items-md-end { align-items: flex-end !important; }\n .align-items-md-center { align-items: center !important; }\n .align-items-md-baseline { align-items: baseline !important; }\n .align-items-md-stretch { align-items: stretch !important; }\n .align-content-md-start { align-content: flex-start !important; }\n .align-content-md-end { align-content: flex-end !important; }\n .align-content-md-center { align-content: center !important; }\n .align-content-md-between { align-content: space-between !important; }\n .align-content-md-around { align-content: space-around !important; }\n .align-content-md-stretch { align-content: stretch !important; }\n .align-self-md-auto { align-self: auto !important; }\n .align-self-md-start { align-self: flex-start !important; }\n .align-self-md-end { align-self: flex-end !important; }\n .align-self-md-center { align-self: center !important; }\n .align-self-md-baseline { align-self: baseline !important; }\n .align-self-md-stretch { align-self: stretch !important; }\n}@media (min-width: 992px) {\n .flex-lg-row { flex-direction: row !important; }\n .flex-lg-column { flex-direction: column !important; }\n .flex-lg-row-reverse { flex-direction: row-reverse !important; }\n .flex-lg-column-reverse { flex-direction: column-reverse !important; }\n .flex-lg-wrap { flex-wrap: wrap !important; }\n .flex-lg-nowrap { flex-wrap: nowrap !important; }\n .flex-lg-wrap-reverse { flex-wrap: wrap-reverse !important; }\n .flex-lg-fill { flex: 1 1 auto !important; }\n .flex-lg-grow-0 { flex-grow: 0 !important; }\n .flex-lg-grow-1 { flex-grow: 1 !important; }\n .flex-lg-shrink-0 { flex-shrink: 0 !important; }\n .flex-lg-shrink-1 { flex-shrink: 1 !important; }\n .justify-content-lg-start { justify-content: flex-start !important; }\n .justify-content-lg-end { justify-content: flex-end !important; }\n .justify-content-lg-center { justify-content: center !important; }\n .justify-content-lg-between { justify-content: space-between !important; }\n .justify-content-lg-around { justify-content: space-around !important; }\n .align-items-lg-start { align-items: flex-start !important; }\n .align-items-lg-end { align-items: flex-end !important; }\n .align-items-lg-center { align-items: center !important; }\n .align-items-lg-baseline { align-items: baseline !important; }\n .align-items-lg-stretch { align-items: stretch !important; }\n .align-content-lg-start { align-content: flex-start !important; }\n .align-content-lg-end { align-content: flex-end !important; }\n .align-content-lg-center { align-content: center !important; }\n .align-content-lg-between { align-content: space-between !important; }\n .align-content-lg-around { align-content: space-around !important; }\n .align-content-lg-stretch { align-content: stretch !important; }\n .align-self-lg-auto { align-self: auto !important; }\n .align-self-lg-start { align-self: flex-start !important; }\n .align-self-lg-end { align-self: flex-end !important; }\n .align-self-lg-center { align-self: center !important; }\n .align-self-lg-baseline { align-self: baseline !important; }\n .align-self-lg-stretch { align-self: stretch !important; }\n}@media (min-width: 1200px) {\n .flex-xl-row { flex-direction: row !important; }\n .flex-xl-column { flex-direction: column !important; }\n .flex-xl-row-reverse { flex-direction: row-reverse !important; }\n .flex-xl-column-reverse { flex-direction: column-reverse !important; }\n .flex-xl-wrap { flex-wrap: wrap !important; }\n .flex-xl-nowrap { flex-wrap: nowrap !important; }\n .flex-xl-wrap-reverse { flex-wrap: wrap-reverse !important; }\n .flex-xl-fill { flex: 1 1 auto !important; }\n .flex-xl-grow-0 { flex-grow: 0 !important; }\n .flex-xl-grow-1 { flex-grow: 1 !important; }\n .flex-xl-shrink-0 { flex-shrink: 0 !important; }\n .flex-xl-shrink-1 { flex-shrink: 1 !important; }\n .justify-content-xl-start { justify-content: flex-start !important; }\n .justify-content-xl-end { justify-content: flex-end !important; }\n .justify-content-xl-center { justify-content: center !important; }\n .justify-content-xl-between { justify-content: space-between !important; }\n .justify-content-xl-around { justify-content: space-around !important; }\n .align-items-xl-start { align-items: flex-start !important; }\n .align-items-xl-end { align-items: flex-end !important; }\n .align-items-xl-center { align-items: center !important; }\n .align-items-xl-baseline { align-items: baseline !important; }\n .align-items-xl-stretch { align-items: stretch !important; }\n .align-content-xl-start { align-content: flex-start !important; }\n .align-content-xl-end { align-content: flex-end !important; }\n .align-content-xl-center { align-content: center !important; }\n .align-content-xl-between { align-content: space-between !important; }\n .align-content-xl-around { align-content: space-around !important; }\n .align-content-xl-stretch { align-content: stretch !important; }\n .align-self-xl-auto { align-self: auto !important; }\n .align-self-xl-start { align-self: flex-start !important; }\n .align-self-xl-end { align-self: flex-end !important; }\n .align-self-xl-center { align-self: center !important; }\n .align-self-xl-baseline { align-self: baseline !important; }\n .align-self-xl-stretch { align-self: stretch !important; }\n}.float-left { float: left !important; }.float-right { float: right !important; }.float-none { float: none !important; }@media (min-width: 576px) {\n .float-sm-left { float: left !important; }\n .float-sm-right { float: right !important; }\n .float-sm-none { float: none !important; }\n}@media (min-width: 768px) {\n .float-md-left { float: left !important; }\n .float-md-right { float: right !important; }\n .float-md-none { float: none !important; }\n}@media (min-width: 992px) {\n .float-lg-left { float: left !important; }\n .float-lg-right { float: right !important; }\n .float-lg-none { float: none !important; }\n}@media (min-width: 1200px) {\n .float-xl-left { float: left !important; }\n .float-xl-right { float: right !important; }\n .float-xl-none { float: none !important; }\n}.position-static { position: static !important; }.position-relative { position: relative !important; }.position-absolute { position: absolute !important; }.position-fixed { position: fixed !important; }.position-sticky { position: sticky !important; }.fixed-top { position: fixed; top: 0px; right: 0px; left: 0px; z-index: 1030; }.fixed-bottom { position: fixed; right: 0px; bottom: 0px; left: 0px; z-index: 1030; }@supports ((position:-webkit-sticky) or (position:sticky)) {\n .sticky-top { position: sticky; top: 0px; z-index: 1020; }\n}.sr-only { position: absolute; width: 1px; height: 1px; padding: 0px; overflow: hidden; clip: rect(0px, 0px, 0px, 0px); white-space: nowrap; border: 0px; }.sr-only-focusable:active, .sr-only-focusable:focus { position: static; width: auto; height: auto; overflow: visible; clip: auto; white-space: normal; }.shadow-sm { box-shadow: rgba(0, 0, 0, 0.075) 0px 0.125rem 0.25rem !important; }.shadow { box-shadow: rgba(0, 0, 0, 0.15) 0px 0.5rem 1rem !important; }.shadow-lg { box-shadow: rgba(0, 0, 0, 0.176) 0px 1rem 3rem !important; }.shadow-none { box-shadow: none !important; }.w-25 { width: 25% !important; }.w-50 { width: 50% !important; }.w-75 { width: 75% !important; }.w-100 { width: 100% !important; }.w-auto { width: auto !important; }.h-25 { height: 25% !important; }.h-50 { height: 50% !important; }.h-75 { height: 75% !important; }.h-100 { height: 100% !important; }.h-auto { height: auto !important; }.mw-100 { max-width: 100% !important; }.mh-100 { max-height: 100% !important; }.m-0 { margin: 0px !important; }.mt-0, .my-0 { margin-top: 0px !important; }.mr-0, .mx-0 { margin-right: 0px !important; }.mb-0, .my-0 { margin-bottom: 0px !important; }.ml-0, .mx-0 { margin-left: 0px !important; }.m-1 { margin: 0.25rem !important; }.mt-1, .my-1 { margin-top: 0.25rem !important; }.mr-1, .mx-1 { margin-right: 0.25rem !important; }.mb-1, .my-1 { margin-bottom: 0.25rem !important; }.ml-1, .mx-1 { margin-left: 0.25rem !important; }.m-2 { margin: 0.5rem !important; }.mt-2, .my-2 { margin-top: 0.5rem !important; }.mr-2, .mx-2 { margin-right: 0.5rem !important; }.mb-2, .my-2 { margin-bottom: 0.5rem !important; }.ml-2, .mx-2 { margin-left: 0.5rem !important; }.m-3 { margin: 1rem !important; }.mt-3, .my-3 { margin-top: 1rem !important; }.mr-3, .mx-3 { margin-right: 1rem !important; }.mb-3, .my-3 { margin-bottom: 1rem !important; }.ml-3, .mx-3 { margin-left: 1rem !important; }.m-4 { margin: 1.5rem !important; }.mt-4, .my-4 { margin-top: 1.5rem !important; }.mr-4, .mx-4 { margin-right: 1.5rem !important; }.mb-4, .my-4 { margin-bottom: 1.5rem !important; }.ml-4, .mx-4 { margin-left: 1.5rem !important; }.m-5 { margin: 3rem !important; }.mt-5, .my-5 { margin-top: 3rem !important; }.mr-5, .mx-5 { margin-right: 3rem !important; }.mb-5, .my-5 { margin-bottom: 3rem !important; }.ml-5, .mx-5 { margin-left: 3rem !important; }.p-0 { padding: 0px !important; }.pt-0, .py-0 { padding-top: 0px !important; }.pr-0, .px-0 { padding-right: 0px !important; }.pb-0, .py-0 { padding-bottom: 0px !important; }.pl-0, .px-0 { padding-left: 0px !important; }.p-1 { padding: 0.25rem !important; }.pt-1, .py-1 { padding-top: 0.25rem !important; }.pr-1, .px-1 { padding-right: 0.25rem !important; }.pb-1, .py-1 { padding-bottom: 0.25rem !important; }.pl-1, .px-1 { padding-left: 0.25rem !important; }.p-2 { padding: 0.5rem !important; }.pt-2, .py-2 { padding-top: 0.5rem !important; }.pr-2, .px-2 { padding-right: 0.5rem !important; }.pb-2, .py-2 { padding-bottom: 0.5rem !important; }.pl-2, .px-2 { padding-left: 0.5rem !important; }.p-3 { padding: 1rem !important; }.pt-3, .py-3 { padding-top: 1rem !important; }.pr-3, .px-3 { padding-right: 1rem !important; }.pb-3, .py-3 { padding-bottom: 1rem !important; }.pl-3, .px-3 { padding-left: 1rem !important; }.p-4 { padding: 1.5rem !important; }.pt-4, .py-4 { padding-top: 1.5rem !important; }.pr-4, .px-4 { padding-right: 1.5rem !important; }.pb-4, .py-4 { padding-bottom: 1.5rem !important; }.pl-4, .px-4 { padding-left: 1.5rem !important; }.p-5 { padding: 3rem !important; }.pt-5, .py-5 { padding-top: 3rem !important; }.pr-5, .px-5 { padding-right: 3rem !important; }.pb-5, .py-5 { padding-bottom: 3rem !important; }.pl-5, .px-5 { padding-left: 3rem !important; }.m-auto { margin: auto !important; }.mt-auto, .my-auto { margin-top: auto !important; }.mr-auto, .mx-auto { margin-right: auto !important; }.mb-auto, .my-auto { margin-bottom: auto !important; }.ml-auto, .mx-auto { margin-left: auto !important; }@media (min-width: 576px) {\n .m-sm-0 { margin: 0px !important; }\n .mt-sm-0, .my-sm-0 { margin-top: 0px !important; }\n .mr-sm-0, .mx-sm-0 { margin-right: 0px !important; }\n .mb-sm-0, .my-sm-0 { margin-bottom: 0px !important; }\n .ml-sm-0, .mx-sm-0 { margin-left: 0px !important; }\n .m-sm-1 { margin: 0.25rem !important; }\n .mt-sm-1, .my-sm-1 { margin-top: 0.25rem !important; }\n .mr-sm-1, .mx-sm-1 { margin-right: 0.25rem !important; }\n .mb-sm-1, .my-sm-1 { margin-bottom: 0.25rem !important; }\n .ml-sm-1, .mx-sm-1 { margin-left: 0.25rem !important; }\n .m-sm-2 { margin: 0.5rem !important; }\n .mt-sm-2, .my-sm-2 { margin-top: 0.5rem !important; }\n .mr-sm-2, .mx-sm-2 { margin-right: 0.5rem !important; }\n .mb-sm-2, .my-sm-2 { margin-bottom: 0.5rem !important; }\n .ml-sm-2, .mx-sm-2 { margin-left: 0.5rem !important; }\n .m-sm-3 { margin: 1rem !important; }\n .mt-sm-3, .my-sm-3 { margin-top: 1rem !important; }\n .mr-sm-3, .mx-sm-3 { margin-right: 1rem !important; }\n .mb-sm-3, .my-sm-3 { margin-bottom: 1rem !important; }\n .ml-sm-3, .mx-sm-3 { margin-left: 1rem !important; }\n .m-sm-4 { margin: 1.5rem !important; }\n .mt-sm-4, .my-sm-4 { margin-top: 1.5rem !important; }\n .mr-sm-4, .mx-sm-4 { margin-right: 1.5rem !important; }\n .mb-sm-4, .my-sm-4 { margin-bottom: 1.5rem !important; }\n .ml-sm-4, .mx-sm-4 { margin-left: 1.5rem !important; }\n .m-sm-5 { margin: 3rem !important; }\n .mt-sm-5, .my-sm-5 { margin-top: 3rem !important; }\n .mr-sm-5, .mx-sm-5 { margin-right: 3rem !important; }\n .mb-sm-5, .my-sm-5 { margin-bottom: 3rem !important; }\n .ml-sm-5, .mx-sm-5 { margin-left: 3rem !important; }\n .p-sm-0 { padding: 0px !important; }\n .pt-sm-0, .py-sm-0 { padding-top: 0px !important; }\n .pr-sm-0, .px-sm-0 { padding-right: 0px !important; }\n .pb-sm-0, .py-sm-0 { padding-bottom: 0px !important; }\n .pl-sm-0, .px-sm-0 { padding-left: 0px !important; }\n .p-sm-1 { padding: 0.25rem !important; }\n .pt-sm-1, .py-sm-1 { padding-top: 0.25rem !important; }\n .pr-sm-1, .px-sm-1 { padding-right: 0.25rem !important; }\n .pb-sm-1, .py-sm-1 { padding-bottom: 0.25rem !important; }\n .pl-sm-1, .px-sm-1 { padding-left: 0.25rem !important; }\n .p-sm-2 { padding: 0.5rem !important; }\n .pt-sm-2, .py-sm-2 { padding-top: 0.5rem !important; }\n .pr-sm-2, .px-sm-2 { padding-right: 0.5rem !important; }\n .pb-sm-2, .py-sm-2 { padding-bottom: 0.5rem !important; }\n .pl-sm-2, .px-sm-2 { padding-left: 0.5rem !important; }\n .p-sm-3 { padding: 1rem !important; }\n .pt-sm-3, .py-sm-3 { padding-top: 1rem !important; }\n .pr-sm-3, .px-sm-3 { padding-right: 1rem !important; }\n .pb-sm-3, .py-sm-3 { padding-bottom: 1rem !important; }\n .pl-sm-3, .px-sm-3 { padding-left: 1rem !important; }\n .p-sm-4 { padding: 1.5rem !important; }\n .pt-sm-4, .py-sm-4 { padding-top: 1.5rem !important; }\n .pr-sm-4, .px-sm-4 { padding-right: 1.5rem !important; }\n .pb-sm-4, .py-sm-4 { padding-bottom: 1.5rem !important; }\n .pl-sm-4, .px-sm-4 { padding-left: 1.5rem !important; }\n .p-sm-5 { padding: 3rem !important; }\n .pt-sm-5, .py-sm-5 { padding-top: 3rem !important; }\n .pr-sm-5, .px-sm-5 { padding-right: 3rem !important; }\n .pb-sm-5, .py-sm-5 { padding-bottom: 3rem !important; }\n .pl-sm-5, .px-sm-5 { padding-left: 3rem !important; }\n .m-sm-auto { margin: auto !important; }\n .mt-sm-auto, .my-sm-auto { margin-top: auto !important; }\n .mr-sm-auto, .mx-sm-auto { margin-right: auto !important; }\n .mb-sm-auto, .my-sm-auto { margin-bottom: auto !important; }\n .ml-sm-auto, .mx-sm-auto { margin-left: auto !important; }\n}@media (min-width: 768px) {\n .m-md-0 { margin: 0px !important; }\n .mt-md-0, .my-md-0 { margin-top: 0px !important; }\n .mr-md-0, .mx-md-0 { margin-right: 0px !important; }\n .mb-md-0, .my-md-0 { margin-bottom: 0px !important; }\n .ml-md-0, .mx-md-0 { margin-left: 0px !important; }\n .m-md-1 { margin: 0.25rem !important; }\n .mt-md-1, .my-md-1 { margin-top: 0.25rem !important; }\n .mr-md-1, .mx-md-1 { margin-right: 0.25rem !important; }\n .mb-md-1, .my-md-1 { margin-bottom: 0.25rem !important; }\n .ml-md-1, .mx-md-1 { margin-left: 0.25rem !important; }\n .m-md-2 { margin: 0.5rem !important; }\n .mt-md-2, .my-md-2 { margin-top: 0.5rem !important; }\n .mr-md-2, .mx-md-2 { margin-right: 0.5rem !important; }\n .mb-md-2, .my-md-2 { margin-bottom: 0.5rem !important; }\n .ml-md-2, .mx-md-2 { margin-left: 0.5rem !important; }\n .m-md-3 { margin: 1rem !important; }\n .mt-md-3, .my-md-3 { margin-top: 1rem !important; }\n .mr-md-3, .mx-md-3 { margin-right: 1rem !important; }\n .mb-md-3, .my-md-3 { margin-bottom: 1rem !important; }\n .ml-md-3, .mx-md-3 { margin-left: 1rem !important; }\n .m-md-4 { margin: 1.5rem !important; }\n .mt-md-4, .my-md-4 { margin-top: 1.5rem !important; }\n .mr-md-4, .mx-md-4 { margin-right: 1.5rem !important; }\n .mb-md-4, .my-md-4 { margin-bottom: 1.5rem !important; }\n .ml-md-4, .mx-md-4 { margin-left: 1.5rem !important; }\n .m-md-5 { margin: 3rem !important; }\n .mt-md-5, .my-md-5 { margin-top: 3rem !important; }\n .mr-md-5, .mx-md-5 { margin-right: 3rem !important; }\n .mb-md-5, .my-md-5 { margin-bottom: 3rem !important; }\n .ml-md-5, .mx-md-5 { margin-left: 3rem !important; }\n .p-md-0 { padding: 0px !important; }\n .pt-md-0, .py-md-0 { padding-top: 0px !important; }\n .pr-md-0, .px-md-0 { padding-right: 0px !important; }\n .pb-md-0, .py-md-0 { padding-bottom: 0px !important; }\n .pl-md-0, .px-md-0 { padding-left: 0px !important; }\n .p-md-1 { padding: 0.25rem !important; }\n .pt-md-1, .py-md-1 { padding-top: 0.25rem !important; }\n .pr-md-1, .px-md-1 { padding-right: 0.25rem !important; }\n .pb-md-1, .py-md-1 { padding-bottom: 0.25rem !important; }\n .pl-md-1, .px-md-1 { padding-left: 0.25rem !important; }\n .p-md-2 { padding: 0.5rem !important; }\n .pt-md-2, .py-md-2 { padding-top: 0.5rem !important; }\n .pr-md-2, .px-md-2 { padding-right: 0.5rem !important; }\n .pb-md-2, .py-md-2 { padding-bottom: 0.5rem !important; }\n .pl-md-2, .px-md-2 { padding-left: 0.5rem !important; }\n .p-md-3 { padding: 1rem !important; }\n .pt-md-3, .py-md-3 { padding-top: 1rem !important; }\n .pr-md-3, .px-md-3 { padding-right: 1rem !important; }\n .pb-md-3, .py-md-3 { padding-bottom: 1rem !important; }\n .pl-md-3, .px-md-3 { padding-left: 1rem !important; }\n .p-md-4 { padding: 1.5rem !important; }\n .pt-md-4, .py-md-4 { padding-top: 1.5rem !important; }\n .pr-md-4, .px-md-4 { padding-right: 1.5rem !important; }\n .pb-md-4, .py-md-4 { padding-bottom: 1.5rem !important; }\n .pl-md-4, .px-md-4 { padding-left: 1.5rem !important; }\n .p-md-5 { padding: 3rem !important; }\n .pt-md-5, .py-md-5 { padding-top: 3rem !important; }\n .pr-md-5, .px-md-5 { padding-right: 3rem !important; }\n .pb-md-5, .py-md-5 { padding-bottom: 3rem !important; }\n .pl-md-5, .px-md-5 { padding-left: 3rem !important; }\n .m-md-auto { margin: auto !important; }\n .mt-md-auto, .my-md-auto { margin-top: auto !important; }\n .mr-md-auto, .mx-md-auto { margin-right: auto !important; }\n .mb-md-auto, .my-md-auto { margin-bottom: auto !important; }\n .ml-md-auto, .mx-md-auto { margin-left: auto !important; }\n}@media (min-width: 992px) {\n .m-lg-0 { margin: 0px !important; }\n .mt-lg-0, .my-lg-0 { margin-top: 0px !important; }\n .mr-lg-0, .mx-lg-0 { margin-right: 0px !important; }\n .mb-lg-0, .my-lg-0 { margin-bottom: 0px !important; }\n .ml-lg-0, .mx-lg-0 { margin-left: 0px !important; }\n .m-lg-1 { margin: 0.25rem !important; }\n .mt-lg-1, .my-lg-1 { margin-top: 0.25rem !important; }\n .mr-lg-1, .mx-lg-1 { margin-right: 0.25rem !important; }\n .mb-lg-1, .my-lg-1 { margin-bottom: 0.25rem !important; }\n .ml-lg-1, .mx-lg-1 { margin-left: 0.25rem !important; }\n .m-lg-2 { margin: 0.5rem !important; }\n .mt-lg-2, .my-lg-2 { margin-top: 0.5rem !important; }\n .mr-lg-2, .mx-lg-2 { margin-right: 0.5rem !important; }\n .mb-lg-2, .my-lg-2 { margin-bottom: 0.5rem !important; }\n .ml-lg-2, .mx-lg-2 { margin-left: 0.5rem !important; }\n .m-lg-3 { margin: 1rem !important; }\n .mt-lg-3, .my-lg-3 { margin-top: 1rem !important; }\n .mr-lg-3, .mx-lg-3 { margin-right: 1rem !important; }\n .mb-lg-3, .my-lg-3 { margin-bottom: 1rem !important; }\n .ml-lg-3, .mx-lg-3 { margin-left: 1rem !important; }\n .m-lg-4 { margin: 1.5rem !important; }\n .mt-lg-4, .my-lg-4 { margin-top: 1.5rem !important; }\n .mr-lg-4, .mx-lg-4 { margin-right: 1.5rem !important; }\n .mb-lg-4, .my-lg-4 { margin-bottom: 1.5rem !important; }\n .ml-lg-4, .mx-lg-4 { margin-left: 1.5rem !important; }\n .m-lg-5 { margin: 3rem !important; }\n .mt-lg-5, .my-lg-5 { margin-top: 3rem !important; }\n .mr-lg-5, .mx-lg-5 { margin-right: 3rem !important; }\n .mb-lg-5, .my-lg-5 { margin-bottom: 3rem !important; }\n .ml-lg-5, .mx-lg-5 { margin-left: 3rem !important; }\n .p-lg-0 { padding: 0px !important; }\n .pt-lg-0, .py-lg-0 { padding-top: 0px !important; }\n .pr-lg-0, .px-lg-0 { padding-right: 0px !important; }\n .pb-lg-0, .py-lg-0 { padding-bottom: 0px !important; }\n .pl-lg-0, .px-lg-0 { padding-left: 0px !important; }\n .p-lg-1 { padding: 0.25rem !important; }\n .pt-lg-1, .py-lg-1 { padding-top: 0.25rem !important; }\n .pr-lg-1, .px-lg-1 { padding-right: 0.25rem !important; }\n .pb-lg-1, .py-lg-1 { padding-bottom: 0.25rem !important; }\n .pl-lg-1, .px-lg-1 { padding-left: 0.25rem !important; }\n .p-lg-2 { padding: 0.5rem !important; }\n .pt-lg-2, .py-lg-2 { padding-top: 0.5rem !important; }\n .pr-lg-2, .px-lg-2 { padding-right: 0.5rem !important; }\n .pb-lg-2, .py-lg-2 { padding-bottom: 0.5rem !important; }\n .pl-lg-2, .px-lg-2 { padding-left: 0.5rem !important; }\n .p-lg-3 { padding: 1rem !important; }\n .pt-lg-3, .py-lg-3 { padding-top: 1rem !important; }\n .pr-lg-3, .px-lg-3 { padding-right: 1rem !important; }\n .pb-lg-3, .py-lg-3 { padding-bottom: 1rem !important; }\n .pl-lg-3, .px-lg-3 { padding-left: 1rem !important; }\n .p-lg-4 { padding: 1.5rem !important; }\n .pt-lg-4, .py-lg-4 { padding-top: 1.5rem !important; }\n .pr-lg-4, .px-lg-4 { padding-right: 1.5rem !important; }\n .pb-lg-4, .py-lg-4 { padding-bottom: 1.5rem !important; }\n .pl-lg-4, .px-lg-4 { padding-left: 1.5rem !important; }\n .p-lg-5 { padding: 3rem !important; }\n .pt-lg-5, .py-lg-5 { padding-top: 3rem !important; }\n .pr-lg-5, .px-lg-5 { padding-right: 3rem !important; }\n .pb-lg-5, .py-lg-5 { padding-bottom: 3rem !important; }\n .pl-lg-5, .px-lg-5 { padding-left: 3rem !important; }\n .m-lg-auto { margin: auto !important; }\n .mt-lg-auto, .my-lg-auto { margin-top: auto !important; }\n .mr-lg-auto, .mx-lg-auto { margin-right: auto !important; }\n .mb-lg-auto, .my-lg-auto { margin-bottom: auto !important; }\n .ml-lg-auto, .mx-lg-auto { margin-left: auto !important; }\n}@media (min-width: 1200px) {\n .m-xl-0 { margin: 0px !important; }\n .mt-xl-0, .my-xl-0 { margin-top: 0px !important; }\n .mr-xl-0, .mx-xl-0 { margin-right: 0px !important; }\n .mb-xl-0, .my-xl-0 { margin-bottom: 0px !important; }\n .ml-xl-0, .mx-xl-0 { margin-left: 0px !important; }\n .m-xl-1 { margin: 0.25rem !important; }\n .mt-xl-1, .my-xl-1 { margin-top: 0.25rem !important; }\n .mr-xl-1, .mx-xl-1 { margin-right: 0.25rem !important; }\n .mb-xl-1, .my-xl-1 { margin-bottom: 0.25rem !important; }\n .ml-xl-1, .mx-xl-1 { margin-left: 0.25rem !important; }\n .m-xl-2 { margin: 0.5rem !important; }\n .mt-xl-2, .my-xl-2 { margin-top: 0.5rem !important; }\n .mr-xl-2, .mx-xl-2 { margin-right: 0.5rem !important; }\n .mb-xl-2, .my-xl-2 { margin-bottom: 0.5rem !important; }\n .ml-xl-2, .mx-xl-2 { margin-left: 0.5rem !important; }\n .m-xl-3 { margin: 1rem !important; }\n .mt-xl-3, .my-xl-3 { margin-top: 1rem !important; }\n .mr-xl-3, .mx-xl-3 { margin-right: 1rem !important; }\n .mb-xl-3, .my-xl-3 { margin-bottom: 1rem !important; }\n .ml-xl-3, .mx-xl-3 { margin-left: 1rem !important; }\n .m-xl-4 { margin: 1.5rem !important; }\n .mt-xl-4, .my-xl-4 { margin-top: 1.5rem !important; }\n .mr-xl-4, .mx-xl-4 { margin-right: 1.5rem !important; }\n .mb-xl-4, .my-xl-4 { margin-bottom: 1.5rem !important; }\n .ml-xl-4, .mx-xl-4 { margin-left: 1.5rem !important; }\n .m-xl-5 { margin: 3rem !important; }\n .mt-xl-5, .my-xl-5 { margin-top: 3rem !important; }\n .mr-xl-5, .mx-xl-5 { margin-right: 3rem !important; }\n .mb-xl-5, .my-xl-5 { margin-bottom: 3rem !important; }\n .ml-xl-5, .mx-xl-5 { margin-left: 3rem !important; }\n .p-xl-0 { padding: 0px !important; }\n .pt-xl-0, .py-xl-0 { padding-top: 0px !important; }\n .pr-xl-0, .px-xl-0 { padding-right: 0px !important; }\n .pb-xl-0, .py-xl-0 { padding-bottom: 0px !important; }\n .pl-xl-0, .px-xl-0 { padding-left: 0px !important; }\n .p-xl-1 { padding: 0.25rem !important; }\n .pt-xl-1, .py-xl-1 { padding-top: 0.25rem !important; }\n .pr-xl-1, .px-xl-1 { padding-right: 0.25rem !important; }\n .pb-xl-1, .py-xl-1 { padding-bottom: 0.25rem !important; }\n .pl-xl-1, .px-xl-1 { padding-left: 0.25rem !important; }\n .p-xl-2 { padding: 0.5rem !important; }\n .pt-xl-2, .py-xl-2 { padding-top: 0.5rem !important; }\n .pr-xl-2, .px-xl-2 { padding-right: 0.5rem !important; }\n .pb-xl-2, .py-xl-2 { padding-bottom: 0.5rem !important; }\n .pl-xl-2, .px-xl-2 { padding-left: 0.5rem !important; }\n .p-xl-3 { padding: 1rem !important; }\n .pt-xl-3, .py-xl-3 { padding-top: 1rem !important; }\n .pr-xl-3, .px-xl-3 { padding-right: 1rem !important; }\n .pb-xl-3, .py-xl-3 { padding-bottom: 1rem !important; }\n .pl-xl-3, .px-xl-3 { padding-left: 1rem !important; }\n .p-xl-4 { padding: 1.5rem !important; }\n .pt-xl-4, .py-xl-4 { padding-top: 1.5rem !important; }\n .pr-xl-4, .px-xl-4 { padding-right: 1.5rem !important; }\n .pb-xl-4, .py-xl-4 { padding-bottom: 1.5rem !important; }\n .pl-xl-4, .px-xl-4 { padding-left: 1.5rem !important; }\n .p-xl-5 { padding: 3rem !important; }\n .pt-xl-5, .py-xl-5 { padding-top: 3rem !important; }\n .pr-xl-5, .px-xl-5 { padding-right: 3rem !important; }\n .pb-xl-5, .py-xl-5 { padding-bottom: 3rem !important; }\n .pl-xl-5, .px-xl-5 { padding-left: 3rem !important; }\n .m-xl-auto { margin: auto !important; }\n .mt-xl-auto, .my-xl-auto { margin-top: auto !important; }\n .mr-xl-auto, .mx-xl-auto { margin-right: auto !important; }\n .mb-xl-auto, .my-xl-auto { margin-bottom: auto !important; }\n .ml-xl-auto, .mx-xl-auto { margin-left: auto !important; }\n}.text-monospace { font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; }.text-justify { text-align: justify !important; }.text-nowrap { white-space: nowrap !important; }.text-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }.text-left { text-align: left !important; }.text-right { text-align: right !important; }.text-center { text-align: center !important; }@media (min-width: 576px) {\n .text-sm-left { text-align: left !important; }\n .text-sm-right { text-align: right !important; }\n .text-sm-center { text-align: center !important; }\n}@media (min-width: 768px) {\n .text-md-left { text-align: left !important; }\n .text-md-right { text-align: right !important; }\n .text-md-center { text-align: center !important; }\n}@media (min-width: 992px) {\n .text-lg-left { text-align: left !important; }\n .text-lg-right { text-align: right !important; }\n .text-lg-center { text-align: center !important; }\n}@media (min-width: 1200px) {\n .text-xl-left { text-align: left !important; }\n .text-xl-right { text-align: right !important; }\n .text-xl-center { text-align: center !important; }\n}.text-lowercase { text-transform: lowercase !important; }.text-uppercase { text-transform: uppercase !important; }.text-capitalize { text-transform: capitalize !important; }.font-weight-light { font-weight: 300 !important; }.font-weight-normal { font-weight: 400 !important; }.font-weight-bold { font-weight: 700 !important; }.font-italic { font-style: italic !important; }.text-white { color: rgb(255, 255, 255) !important; }.text-primary { color: rgb(0, 123, 255) !important; }a.text-primary:focus, a.text-primary:hover { color: rgb(0, 98, 204) !important; }.text-secondary { color: rgb(108, 117, 125) !important; }a.text-secondary:focus, a.text-secondary:hover { color: rgb(84, 91, 98) !important; }.text-success { color: rgb(40, 167, 69) !important; }a.text-success:focus, a.text-success:hover { color: rgb(30, 126, 52) !important; }.text-info { color: rgb(23, 162, 184) !important; }a.text-info:focus, a.text-info:hover { color: rgb(17, 122, 139) !important; }.text-warning { color: rgb(255, 193, 7) !important; }a.text-warning:focus, a.text-warning:hover { color: rgb(211, 158, 0) !important; }.text-danger { color: rgb(220, 53, 69) !important; }a.text-danger:focus, a.text-danger:hover { color: rgb(189, 33, 48) !important; }.text-light { color: rgb(248, 249, 250) !important; }a.text-light:focus, a.text-light:hover { color: rgb(218, 224, 229) !important; }.text-dark { color: rgb(52, 58, 64) !important; }a.text-dark:focus, a.text-dark:hover { color: rgb(29, 33, 36) !important; }.text-body { color: rgb(33, 37, 41) !important; }.text-muted { color: rgb(108, 117, 125) !important; }.text-black-50 { color: rgba(0, 0, 0, 0.5) !important; }.text-white-50 { color: rgba(255, 255, 255, 0.5) !important; }.text-hide { font: 0px/0 a; color: transparent; text-shadow: none; background-color: transparent; border: 0px; }.visible { visibility: visible !important; }.invisible { visibility: hidden !important; }@media print {\n *, ::after, ::before { text-shadow: none !important; box-shadow: none !important; }\n a:not(.btn) { text-decoration: underline; }\n abbr[title]::after { content: \" (\" attr(title) \")\"; }\n pre { white-space: pre-wrap !important; }\n blockquote, pre { border: 1px solid rgb(173, 181, 189); break-inside: avoid; }\n thead { display: table-header-group; }\n img, tr { break-inside: avoid; }\n h2, h3, p { orphans: 3; widows: 3; }\n h2, h3 { break-after: avoid; }\n @page { size: a3; }\n body { min-width: 992px !important; }\n .container { min-width: 992px !important; }\n .navbar { display: none; }\n .badge { border: 1px solid rgb(0, 0, 0); }\n .table { border-collapse: collapse !important; }\n .table td, .table th { background-color: rgb(255, 255, 255) !important; }\n .table-bordered td, .table-bordered th { border: 1px solid rgb(222, 226, 230) !important; }\n .table-dark { color: inherit; }\n .table-dark tbody + tbody, .table-dark td, .table-dark th, .table-dark thead th { border-color: rgb(222, 226, 230); }\n .table .thead-dark th { color: inherit; border-color: rgb(222, 226, 230); }\n}"},"childNodes":[],"id":22},{"type":3,"textContent":"\n\n ","id":23},{"type":5,"textContent":" Custom styles for this template ","id":24},{"type":3,"textContent":"\n ","id":25},{"type":2,"tagName":"link","attributes":{"_cssText":".container { max-width: 960px; }.lh-condensed { line-height: 1.25; }"},"childNodes":[],"id":26},{"type":3,"textContent":"\n","id":27}],"id":5},{"type":3,"textContent":"\n\n","id":28},{"type":2,"tagName":"body","attributes":{"class":"bg-light"},"childNodes":[{"type":3,"textContent":"\n\n ","id":30},{"type":2,"tagName":"div","attributes":{"class":"container"},"childNodes":[{"type":3,"textContent":"\n ","id":32},{"type":2,"tagName":"div","attributes":{"class":"py-5 text-center"},"childNodes":[{"type":3,"textContent":"\n ","id":34},{"type":2,"tagName":"img","attributes":{"class":"d-block mx-auto mb-4","src":"http://127.0.0.1:5500/checkout-demo/index_files/bootstrap-solid.svg","alt":"","width":"72","height":"72"},"childNodes":[],"id":35},{"type":3,"textContent":"\n ","id":36},{"type":2,"tagName":"h2","attributes":{},"childNodes":[{"type":3,"textContent":"Checkout form","id":38}],"id":37},{"type":3,"textContent":"\n ","id":39},{"type":2,"tagName":"p","attributes":{"class":"lead"},"childNodes":[{"type":3,"textContent":"Below is an example form built entirely with Bootstrap's form controls. Each required form group\n has\n a validation state that can be triggered by attempting to submit the form without completing it.","id":41}],"id":40},{"type":3,"textContent":"\n ","id":42}],"id":33},{"type":3,"textContent":"\n\n ","id":43},{"type":2,"tagName":"div","attributes":{"class":"row"},"childNodes":[{"type":3,"textContent":"\n ","id":45},{"type":2,"tagName":"div","attributes":{"class":"col-md-4 order-md-2 mb-4"},"childNodes":[{"type":3,"textContent":"\n ","id":47},{"type":2,"tagName":"h4","attributes":{"class":"d-flex justify-content-between align-items-center mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":49},{"type":2,"tagName":"span","attributes":{"class":"text-muted"},"childNodes":[{"type":3,"textContent":"Your cart","id":51}],"id":50},{"type":3,"textContent":"\n ","id":52},{"type":2,"tagName":"span","attributes":{"class":"badge badge-secondary badge-pill"},"childNodes":[{"type":3,"textContent":"3","id":54}],"id":53},{"type":3,"textContent":"\n ","id":55}],"id":48},{"type":3,"textContent":"\n ","id":56},{"type":2,"tagName":"ul","attributes":{"class":"list-group mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":58},{"type":2,"tagName":"li","attributes":{"class":"list-group-item d-flex justify-content-between lh-condensed"},"childNodes":[{"type":3,"textContent":"\n ","id":60},{"type":2,"tagName":"div","attributes":{},"childNodes":[{"type":3,"textContent":"\n ","id":62},{"type":2,"tagName":"h6","attributes":{"class":"my-0"},"childNodes":[{"type":3,"textContent":"Product name","id":64}],"id":63},{"type":3,"textContent":"\n ","id":65},{"type":2,"tagName":"small","attributes":{"class":"text-muted"},"childNodes":[{"type":3,"textContent":"Brief description","id":67}],"id":66},{"type":3,"textContent":"\n ","id":68}],"id":61},{"type":3,"textContent":"\n ","id":69},{"type":2,"tagName":"span","attributes":{"class":"text-muted"},"childNodes":[{"type":3,"textContent":"$12","id":71}],"id":70},{"type":3,"textContent":"\n ","id":72}],"id":59},{"type":3,"textContent":"\n ","id":73},{"type":2,"tagName":"li","attributes":{"class":"list-group-item d-flex justify-content-between lh-condensed"},"childNodes":[{"type":3,"textContent":"\n ","id":75},{"type":2,"tagName":"div","attributes":{},"childNodes":[{"type":3,"textContent":"\n ","id":77},{"type":2,"tagName":"h6","attributes":{"class":"my-0"},"childNodes":[{"type":3,"textContent":"Second product","id":79}],"id":78},{"type":3,"textContent":"\n ","id":80},{"type":2,"tagName":"small","attributes":{"class":"text-muted"},"childNodes":[{"type":3,"textContent":"Brief description","id":82}],"id":81},{"type":3,"textContent":"\n ","id":83}],"id":76},{"type":3,"textContent":"\n ","id":84},{"type":2,"tagName":"span","attributes":{"class":"text-muted"},"childNodes":[{"type":3,"textContent":"$8","id":86}],"id":85},{"type":3,"textContent":"\n ","id":87}],"id":74},{"type":3,"textContent":"\n ","id":88},{"type":2,"tagName":"li","attributes":{"class":"list-group-item d-flex justify-content-between lh-condensed"},"childNodes":[{"type":3,"textContent":"\n ","id":90},{"type":2,"tagName":"div","attributes":{},"childNodes":[{"type":3,"textContent":"\n ","id":92},{"type":2,"tagName":"h6","attributes":{"class":"my-0"},"childNodes":[{"type":3,"textContent":"Third item","id":94}],"id":93},{"type":3,"textContent":"\n ","id":95},{"type":2,"tagName":"small","attributes":{"class":"text-muted"},"childNodes":[{"type":3,"textContent":"Brief description","id":97}],"id":96},{"type":3,"textContent":"\n ","id":98}],"id":91},{"type":3,"textContent":"\n ","id":99},{"type":2,"tagName":"span","attributes":{"class":"text-muted"},"childNodes":[{"type":3,"textContent":"$5","id":101}],"id":100},{"type":3,"textContent":"\n ","id":102}],"id":89},{"type":3,"textContent":"\n ","id":103},{"type":2,"tagName":"li","attributes":{"class":"list-group-item d-flex justify-content-between bg-light"},"childNodes":[{"type":3,"textContent":"\n ","id":105},{"type":2,"tagName":"div","attributes":{"class":"text-success"},"childNodes":[{"type":3,"textContent":"\n ","id":107},{"type":2,"tagName":"h6","attributes":{"class":"my-0"},"childNodes":[{"type":3,"textContent":"Promo code","id":109}],"id":108},{"type":3,"textContent":"\n ","id":110},{"type":2,"tagName":"small","attributes":{},"childNodes":[{"type":3,"textContent":"EXAMPLECODE","id":112}],"id":111},{"type":3,"textContent":"\n ","id":113}],"id":106},{"type":3,"textContent":"\n ","id":114},{"type":2,"tagName":"span","attributes":{"class":"text-success"},"childNodes":[{"type":3,"textContent":"-$5","id":116}],"id":115},{"type":3,"textContent":"\n ","id":117}],"id":104},{"type":3,"textContent":"\n ","id":118},{"type":2,"tagName":"li","attributes":{"class":"list-group-item d-flex justify-content-between"},"childNodes":[{"type":3,"textContent":"\n ","id":120},{"type":2,"tagName":"span","attributes":{},"childNodes":[{"type":3,"textContent":"Total (USD)","id":122}],"id":121},{"type":3,"textContent":"\n ","id":123},{"type":2,"tagName":"strong","attributes":{},"childNodes":[{"type":3,"textContent":"$20","id":125}],"id":124},{"type":3,"textContent":"\n ","id":126}],"id":119},{"type":3,"textContent":"\n ","id":127}],"id":57},{"type":3,"textContent":"\n\n ","id":128},{"type":2,"tagName":"form","attributes":{"class":"card p-2"},"childNodes":[{"type":3,"textContent":"\n ","id":130},{"type":2,"tagName":"div","attributes":{"class":"input-group"},"childNodes":[{"type":3,"textContent":"\n ","id":132},{"type":2,"tagName":"input","attributes":{"type":"text","class":"form-control","placeholder":"Promo code"},"childNodes":[],"id":133},{"type":3,"textContent":"\n ","id":134},{"type":2,"tagName":"div","attributes":{"class":"input-group-append"},"childNodes":[{"type":3,"textContent":"\n ","id":136},{"type":2,"tagName":"button","attributes":{"type":"submit","class":"btn btn-secondary"},"childNodes":[{"type":3,"textContent":"Redeem","id":138}],"id":137},{"type":3,"textContent":"\n ","id":139}],"id":135},{"type":3,"textContent":"\n ","id":140}],"id":131},{"type":3,"textContent":"\n ","id":141}],"id":129},{"type":3,"textContent":"\n ","id":142}],"id":46},{"type":3,"textContent":"\n ","id":143},{"type":2,"tagName":"div","attributes":{"class":"col-md-8 order-md-1"},"childNodes":[{"type":3,"textContent":"\n ","id":145},{"type":2,"tagName":"h4","attributes":{"class":"mb-3"},"childNodes":[{"type":3,"textContent":"Billing address","id":147}],"id":146},{"type":3,"textContent":"\n ","id":148},{"type":2,"tagName":"form","attributes":{"class":"needs-validation","novalidate":""},"childNodes":[{"type":3,"textContent":"\n ","id":150},{"type":2,"tagName":"div","attributes":{"class":"row"},"childNodes":[{"type":3,"textContent":"\n ","id":152},{"type":2,"tagName":"div","attributes":{"class":"col-md-6 mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":154},{"type":2,"tagName":"label","attributes":{"for":"firstName"},"childNodes":[{"type":3,"textContent":"First name","id":156}],"id":155},{"type":3,"textContent":"\n ","id":157},{"type":2,"tagName":"input","attributes":{"type":"text","class":"form-control","id":"firstName","placeholder":"","value":"","required":""},"childNodes":[],"id":158},{"type":3,"textContent":"\n ","id":159},{"type":2,"tagName":"div","attributes":{"class":"invalid-feedback"},"childNodes":[{"type":3,"textContent":"\n Valid first name is required.\n ","id":161}],"id":160},{"type":3,"textContent":"\n ","id":162}],"id":153},{"type":3,"textContent":"\n ","id":163},{"type":2,"tagName":"div","attributes":{"class":"col-md-6 mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":165},{"type":2,"tagName":"label","attributes":{"for":"lastName"},"childNodes":[{"type":3,"textContent":"Last name","id":167}],"id":166},{"type":3,"textContent":"\n ","id":168},{"type":2,"tagName":"input","attributes":{"type":"text","class":"form-control","id":"lastName","placeholder":"","value":"","required":""},"childNodes":[],"id":169},{"type":3,"textContent":"\n ","id":170},{"type":2,"tagName":"div","attributes":{"class":"invalid-feedback"},"childNodes":[{"type":3,"textContent":"\n Valid last name is required.\n ","id":172}],"id":171},{"type":3,"textContent":"\n ","id":173}],"id":164},{"type":3,"textContent":"\n ","id":174}],"id":151},{"type":3,"textContent":"\n\n ","id":175},{"type":2,"tagName":"div","attributes":{"class":"mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":177},{"type":2,"tagName":"label","attributes":{"for":"username"},"childNodes":[{"type":3,"textContent":"Username","id":179}],"id":178},{"type":3,"textContent":"\n ","id":180},{"type":2,"tagName":"div","attributes":{"class":"input-group"},"childNodes":[{"type":3,"textContent":"\n ","id":182},{"type":2,"tagName":"div","attributes":{"class":"input-group-prepend"},"childNodes":[{"type":3,"textContent":"\n ","id":184},{"type":2,"tagName":"span","attributes":{"class":"input-group-text"},"childNodes":[{"type":3,"textContent":"@","id":186}],"id":185},{"type":3,"textContent":"\n ","id":187}],"id":183},{"type":3,"textContent":"\n ","id":188},{"type":2,"tagName":"input","attributes":{"type":"text","class":"form-control","id":"username","placeholder":"Username","required":""},"childNodes":[],"id":189},{"type":3,"textContent":"\n ","id":190},{"type":2,"tagName":"div","attributes":{"class":"invalid-feedback","style":"width: 100%;"},"childNodes":[{"type":3,"textContent":"\n Your username is required.\n ","id":192}],"id":191},{"type":3,"textContent":"\n ","id":193}],"id":181},{"type":3,"textContent":"\n ","id":194}],"id":176},{"type":3,"textContent":"\n\n ","id":195},{"type":2,"tagName":"div","attributes":{"class":"mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":197},{"type":2,"tagName":"label","attributes":{"for":"email"},"childNodes":[{"type":3,"textContent":"Email ","id":199},{"type":2,"tagName":"span","attributes":{"class":"text-muted"},"childNodes":[{"type":3,"textContent":"(Optional)","id":201}],"id":200}],"id":198},{"type":3,"textContent":"\n ","id":202},{"type":2,"tagName":"input","attributes":{"type":"email","class":"form-control","id":"email","placeholder":"you@example.com"},"childNodes":[],"id":203},{"type":3,"textContent":"\n ","id":204},{"type":2,"tagName":"div","attributes":{"class":"invalid-feedback"},"childNodes":[{"type":3,"textContent":"\n Please enter a valid email address for shipping updates.\n ","id":206}],"id":205},{"type":3,"textContent":"\n ","id":207}],"id":196},{"type":3,"textContent":"\n\n ","id":208},{"type":2,"tagName":"div","attributes":{"class":"mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":210},{"type":2,"tagName":"label","attributes":{"for":"address"},"childNodes":[{"type":3,"textContent":"Address","id":212}],"id":211},{"type":3,"textContent":"\n ","id":213},{"type":2,"tagName":"input","attributes":{"type":"text","class":"form-control","id":"address","placeholder":"1234 Main St","required":""},"childNodes":[],"id":214},{"type":3,"textContent":"\n ","id":215},{"type":2,"tagName":"div","attributes":{"class":"invalid-feedback"},"childNodes":[{"type":3,"textContent":"\n Please enter your shipping address.\n ","id":217}],"id":216},{"type":3,"textContent":"\n ","id":218}],"id":209},{"type":3,"textContent":"\n\n ","id":219},{"type":2,"tagName":"div","attributes":{"class":"mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":221},{"type":2,"tagName":"label","attributes":{"for":"address2"},"childNodes":[{"type":3,"textContent":"Address 2 ","id":223},{"type":2,"tagName":"span","attributes":{"class":"text-muted"},"childNodes":[{"type":3,"textContent":"(Optional)","id":225}],"id":224}],"id":222},{"type":3,"textContent":"\n ","id":226},{"type":2,"tagName":"input","attributes":{"type":"text","class":"form-control","id":"address2","placeholder":"Apartment or suite"},"childNodes":[],"id":227},{"type":3,"textContent":"\n ","id":228}],"id":220},{"type":3,"textContent":"\n\n ","id":229},{"type":2,"tagName":"div","attributes":{"class":"row"},"childNodes":[{"type":3,"textContent":"\n ","id":231},{"type":2,"tagName":"div","attributes":{"class":"col-md-5 mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":233},{"type":2,"tagName":"label","attributes":{"for":"country"},"childNodes":[{"type":3,"textContent":"Country","id":235}],"id":234},{"type":3,"textContent":"\n ","id":236},{"type":2,"tagName":"select","attributes":{"class":"custom-select d-block w-100","id":"country","required":""},"childNodes":[{"type":3,"textContent":"\n ","id":238},{"type":2,"tagName":"option","attributes":{"value":"","selected":true},"childNodes":[{"type":3,"textContent":"Choose...","id":240}],"id":239},{"type":3,"textContent":"\n ","id":241},{"type":2,"tagName":"option","attributes":{},"childNodes":[{"type":3,"textContent":"United States","id":243}],"id":242},{"type":3,"textContent":"\n ","id":244}],"id":237},{"type":3,"textContent":"\n ","id":245},{"type":2,"tagName":"div","attributes":{"class":"invalid-feedback"},"childNodes":[{"type":3,"textContent":"\n Please select a valid country.\n ","id":247}],"id":246},{"type":3,"textContent":"\n ","id":248}],"id":232},{"type":3,"textContent":"\n ","id":249},{"type":2,"tagName":"div","attributes":{"class":"col-md-4 mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":251},{"type":2,"tagName":"label","attributes":{"for":"state"},"childNodes":[{"type":3,"textContent":"State","id":253}],"id":252},{"type":3,"textContent":"\n ","id":254},{"type":2,"tagName":"select","attributes":{"class":"custom-select d-block w-100","id":"state","required":""},"childNodes":[{"type":3,"textContent":"\n ","id":256},{"type":2,"tagName":"option","attributes":{"value":"","selected":true},"childNodes":[{"type":3,"textContent":"Choose...","id":258}],"id":257},{"type":3,"textContent":"\n ","id":259},{"type":2,"tagName":"option","attributes":{},"childNodes":[{"type":3,"textContent":"California","id":261}],"id":260},{"type":3,"textContent":"\n ","id":262}],"id":255},{"type":3,"textContent":"\n ","id":263},{"type":2,"tagName":"div","attributes":{"class":"invalid-feedback"},"childNodes":[{"type":3,"textContent":"\n Please provide a valid state.\n ","id":265}],"id":264},{"type":3,"textContent":"\n ","id":266}],"id":250},{"type":3,"textContent":"\n ","id":267},{"type":2,"tagName":"div","attributes":{"class":"col-md-3 mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":269},{"type":2,"tagName":"label","attributes":{"for":"zip"},"childNodes":[{"type":3,"textContent":"Zip","id":271}],"id":270},{"type":3,"textContent":"\n ","id":272},{"type":2,"tagName":"input","attributes":{"type":"text","class":"form-control","id":"zip","placeholder":"","required":""},"childNodes":[],"id":273},{"type":3,"textContent":"\n ","id":274},{"type":2,"tagName":"div","attributes":{"class":"invalid-feedback"},"childNodes":[{"type":3,"textContent":"\n Zip code required.\n ","id":276}],"id":275},{"type":3,"textContent":"\n ","id":277}],"id":268},{"type":3,"textContent":"\n ","id":278}],"id":230},{"type":3,"textContent":"\n ","id":279},{"type":2,"tagName":"hr","attributes":{"class":"mb-4"},"childNodes":[],"id":280},{"type":3,"textContent":"\n ","id":281},{"type":2,"tagName":"div","attributes":{"class":"custom-control custom-checkbox"},"childNodes":[{"type":3,"textContent":"\n ","id":283},{"type":2,"tagName":"input","attributes":{"type":"checkbox","class":"custom-control-input","id":"same-address"},"childNodes":[],"id":284},{"type":3,"textContent":"\n ","id":285},{"type":2,"tagName":"label","attributes":{"class":"custom-control-label","for":"same-address"},"childNodes":[{"type":3,"textContent":"Shipping address is the same as my billing address","id":287}],"id":286},{"type":3,"textContent":"\n ","id":288}],"id":282},{"type":3,"textContent":"\n ","id":289},{"type":2,"tagName":"div","attributes":{"class":"custom-control custom-checkbox"},"childNodes":[{"type":3,"textContent":"\n ","id":291},{"type":2,"tagName":"input","attributes":{"type":"checkbox","class":"custom-control-input","id":"save-info"},"childNodes":[],"id":292},{"type":3,"textContent":"\n ","id":293},{"type":2,"tagName":"label","attributes":{"class":"custom-control-label","for":"save-info"},"childNodes":[{"type":3,"textContent":"Save this information for next time","id":295}],"id":294},{"type":3,"textContent":"\n ","id":296}],"id":290},{"type":3,"textContent":"\n ","id":297},{"type":2,"tagName":"hr","attributes":{"class":"mb-4"},"childNodes":[],"id":298},{"type":3,"textContent":"\n\n ","id":299},{"type":2,"tagName":"h4","attributes":{"class":"mb-3"},"childNodes":[{"type":3,"textContent":"Payment","id":301}],"id":300},{"type":3,"textContent":"\n\n ","id":302},{"type":2,"tagName":"div","attributes":{"class":"d-block my-3"},"childNodes":[{"type":3,"textContent":"\n ","id":304},{"type":2,"tagName":"div","attributes":{"class":"custom-control custom-radio"},"childNodes":[{"type":3,"textContent":"\n ","id":306},{"type":2,"tagName":"input","attributes":{"id":"credit","name":"paymentMethod","type":"radio","class":"custom-control-input","checked":true,"required":""},"childNodes":[],"id":307},{"type":3,"textContent":"\n ","id":308},{"type":2,"tagName":"label","attributes":{"class":"custom-control-label","for":"credit"},"childNodes":[{"type":3,"textContent":"Credit card","id":310}],"id":309},{"type":3,"textContent":"\n ","id":311}],"id":305},{"type":3,"textContent":"\n ","id":312},{"type":2,"tagName":"div","attributes":{"class":"custom-control custom-radio"},"childNodes":[{"type":3,"textContent":"\n ","id":314},{"type":2,"tagName":"input","attributes":{"id":"debit","name":"paymentMethod","type":"radio","class":"custom-control-input","required":""},"childNodes":[],"id":315},{"type":3,"textContent":"\n ","id":316},{"type":2,"tagName":"label","attributes":{"class":"custom-control-label","for":"debit"},"childNodes":[{"type":3,"textContent":"Debit card","id":318}],"id":317},{"type":3,"textContent":"\n ","id":319}],"id":313},{"type":3,"textContent":"\n ","id":320},{"type":2,"tagName":"div","attributes":{"class":"custom-control custom-radio"},"childNodes":[{"type":3,"textContent":"\n ","id":322},{"type":2,"tagName":"input","attributes":{"id":"paypal","name":"paymentMethod","type":"radio","class":"custom-control-input","required":""},"childNodes":[],"id":323},{"type":3,"textContent":"\n ","id":324},{"type":2,"tagName":"label","attributes":{"class":"custom-control-label","for":"paypal"},"childNodes":[{"type":3,"textContent":"PayPal","id":326}],"id":325},{"type":3,"textContent":"\n ","id":327}],"id":321},{"type":3,"textContent":"\n ","id":328}],"id":303},{"type":3,"textContent":"\n ","id":329},{"type":2,"tagName":"div","attributes":{"class":"row"},"childNodes":[{"type":3,"textContent":"\n ","id":331},{"type":2,"tagName":"div","attributes":{"class":"col-md-6 mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":333},{"type":2,"tagName":"label","attributes":{"for":"cc-name"},"childNodes":[{"type":3,"textContent":"Name on card","id":335}],"id":334},{"type":3,"textContent":"\n ","id":336},{"type":2,"tagName":"input","attributes":{"type":"text","class":"form-control","id":"cc-name","placeholder":"","required":""},"childNodes":[],"id":337},{"type":3,"textContent":"\n ","id":338},{"type":2,"tagName":"small","attributes":{"class":"text-muted"},"childNodes":[{"type":3,"textContent":"Full name as displayed on card","id":340}],"id":339},{"type":3,"textContent":"\n ","id":341},{"type":2,"tagName":"div","attributes":{"class":"invalid-feedback"},"childNodes":[{"type":3,"textContent":"\n Name on card is required\n ","id":343}],"id":342},{"type":3,"textContent":"\n ","id":344}],"id":332},{"type":3,"textContent":"\n ","id":345},{"type":2,"tagName":"div","attributes":{"class":"col-md-6 mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":347},{"type":2,"tagName":"label","attributes":{"for":"cc-number"},"childNodes":[{"type":3,"textContent":"Credit card number","id":349}],"id":348},{"type":3,"textContent":"\n ","id":350},{"type":2,"tagName":"input","attributes":{"type":"text","class":"form-control","id":"cc-number","placeholder":"","required":""},"childNodes":[],"id":351},{"type":3,"textContent":"\n ","id":352},{"type":2,"tagName":"div","attributes":{"class":"invalid-feedback"},"childNodes":[{"type":3,"textContent":"\n Credit card number is required\n ","id":354}],"id":353},{"type":3,"textContent":"\n ","id":355}],"id":346},{"type":3,"textContent":"\n ","id":356}],"id":330},{"type":3,"textContent":"\n ","id":357},{"type":2,"tagName":"div","attributes":{"class":"row"},"childNodes":[{"type":3,"textContent":"\n ","id":359},{"type":2,"tagName":"div","attributes":{"class":"col-md-3 mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":361},{"type":2,"tagName":"label","attributes":{"for":"cc-expiration"},"childNodes":[{"type":3,"textContent":"Expiration","id":363}],"id":362},{"type":3,"textContent":"\n ","id":364},{"type":2,"tagName":"input","attributes":{"type":"text","class":"form-control","id":"cc-expiration","placeholder":"","required":""},"childNodes":[],"id":365},{"type":3,"textContent":"\n ","id":366},{"type":2,"tagName":"div","attributes":{"class":"invalid-feedback"},"childNodes":[{"type":3,"textContent":"\n Expiration date required\n ","id":368}],"id":367},{"type":3,"textContent":"\n ","id":369}],"id":360},{"type":3,"textContent":"\n ","id":370},{"type":2,"tagName":"div","attributes":{"class":"col-md-3 mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":372},{"type":2,"tagName":"label","attributes":{"for":"cc-cvv"},"childNodes":[{"type":3,"textContent":"CVV","id":374}],"id":373},{"type":3,"textContent":"\n ","id":375},{"type":2,"tagName":"input","attributes":{"type":"text","class":"form-control","id":"cc-cvv","placeholder":"","required":""},"childNodes":[],"id":376},{"type":3,"textContent":"\n ","id":377},{"type":2,"tagName":"div","attributes":{"class":"invalid-feedback"},"childNodes":[{"type":3,"textContent":"\n Security code required\n ","id":379}],"id":378},{"type":3,"textContent":"\n ","id":380}],"id":371},{"type":3,"textContent":"\n ","id":381}],"id":358},{"type":3,"textContent":"\n ","id":382},{"type":2,"tagName":"div","attributes":{"class":"mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":384},{"type":2,"tagName":"label","attributes":{"for":"email"},"childNodes":[{"type":3,"textContent":"textarea ","id":386},{"type":2,"tagName":"span","attributes":{"class":"text-muted"},"childNodes":[{"type":3,"textContent":"(Optional)","id":388}],"id":387}],"id":385},{"type":3,"textContent":"\n ","id":389},{"type":2,"tagName":"textarea","attributes":{"name":"","id":"","cols":"30","rows":"10"},"childNodes":[],"id":390},{"type":3,"textContent":"\n ","id":391}],"id":383},{"type":3,"textContent":"\n ","id":392},{"type":2,"tagName":"hr","attributes":{"class":"mb-4"},"childNodes":[],"id":393},{"type":3,"textContent":"\n ","id":394},{"type":2,"tagName":"button","attributes":{"class":"btn btn-primary btn-lg btn-block","type":"submit"},"childNodes":[{"type":3,"textContent":"Continue to checkout","id":396}],"id":395},{"type":3,"textContent":"\n ","id":397}],"id":149},{"type":3,"textContent":"\n ","id":398}],"id":144},{"type":3,"textContent":"\n ","id":399}],"id":44},{"type":3,"textContent":"\n\n ","id":400},{"type":2,"tagName":"footer","attributes":{"class":"my-5 pt-5 text-muted text-center text-small"},"childNodes":[{"type":3,"textContent":"\n ","id":402},{"type":2,"tagName":"p","attributes":{"class":"mb-1"},"childNodes":[{"type":3,"textContent":"© 2017-2018 Company Name","id":404}],"id":403},{"type":3,"textContent":"\n ","id":405},{"type":2,"tagName":"ul","attributes":{"class":"list-inline"},"childNodes":[{"type":3,"textContent":"\n ","id":407},{"type":2,"tagName":"li","attributes":{"class":"list-inline-item"},"childNodes":[{"type":2,"tagName":"a","attributes":{"href":"https://getbootstrap.com/docs/4.1/examples/checkout/#"},"childNodes":[{"type":3,"textContent":"Privacy","id":410}],"id":409}],"id":408},{"type":3,"textContent":"\n ","id":411},{"type":2,"tagName":"li","attributes":{"class":"list-inline-item"},"childNodes":[{"type":2,"tagName":"a","attributes":{"href":"https://getbootstrap.com/docs/4.1/examples/checkout/#"},"childNodes":[{"type":3,"textContent":"Terms","id":414}],"id":413}],"id":412},{"type":3,"textContent":"\n ","id":415},{"type":2,"tagName":"li","attributes":{"class":"list-inline-item"},"childNodes":[{"type":2,"tagName":"a","attributes":{"href":"https://getbootstrap.com/docs/4.1/examples/checkout/#"},"childNodes":[{"type":3,"textContent":"Support","id":418}],"id":417}],"id":416},{"type":3,"textContent":"\n ","id":419}],"id":406},{"type":3,"textContent":"\n ","id":420}],"id":401},{"type":3,"textContent":"\n ","id":421}],"id":31},{"type":3,"textContent":"\n\n ","id":422},{"type":5,"textContent":" Bootstrap core JavaScript\n ================================================== ","id":423},{"type":3,"textContent":"\n ","id":424},{"type":5,"textContent":" Placed at the end of the document so the pages load faster ","id":425},{"type":3,"textContent":"\n ","id":426},{"type":2,"tagName":"script","attributes":{"src":"http://127.0.0.1:5500/checkout-demo/index_files/jquery-3.3.1.slim.min.js","integrity":"sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo","crossorigin":"anonymous"},"childNodes":[],"id":427},{"type":3,"textContent":"\n ","id":428},{"type":2,"tagName":"script","attributes":{},"childNodes":[{"type":3,"textContent":"SCRIPT_PLACEHOLDER","id":430}],"id":429},{"type":3,"textContent":"\n ","id":431},{"type":2,"tagName":"script","attributes":{"src":"http://127.0.0.1:5500/checkout-demo/index_files/popper.min.js"},"childNodes":[],"id":432},{"type":3,"textContent":"\n ","id":433},{"type":2,"tagName":"script","attributes":{"src":"http://127.0.0.1:5500/checkout-demo/index_files/bootstrap.min.js"},"childNodes":[],"id":434},{"type":3,"textContent":"\n ","id":435},{"type":2,"tagName":"script","attributes":{"src":"http://127.0.0.1:5500/checkout-demo/index_files/holder.min.js"},"childNodes":[],"id":436},{"type":3,"textContent":"\n ","id":437},{"type":2,"tagName":"script","attributes":{},"childNodes":[{"type":3,"textContent":"SCRIPT_PLACEHOLDER","id":439}],"id":438},{"type":3,"textContent":"\n\n ","id":440},{"type":5,"textContent":" logrocket ","id":441},{"type":3,"textContent":"\n\n ","id":442},{"type":5,"textContent":" \n ","id":443},{"type":3,"textContent":"\n\n ","id":444},{"type":5,"textContent":" fundebug ","id":445},{"type":3,"textContent":"\n\n ","id":446},{"type":5,"textContent":" \n ","id":447},{"type":3,"textContent":"\n\n ","id":448},{"type":5,"textContent":" fullstory ","id":449},{"type":3,"textContent":"\n\n ","id":450},{"type":5,"textContent":" ","id":451},{"type":3,"textContent":"\n\n ","id":452},{"type":2,"tagName":"script","attributes":{"src":"http://127.0.0.1:5500/src/record.js"},"childNodes":[],"id":453},{"type":3,"textContent":"\n ","id":454},{"type":2,"tagName":"script","attributes":{},"childNodes":[{"type":3,"textContent":"SCRIPT_PLACEHOLDER","id":456}],"id":455},{"type":3,"textContent":"\n\n","id":457},{"type":5,"textContent":" Code injected by live-server ","id":458},{"type":3,"textContent":"\n","id":459},{"type":2,"tagName":"script","attributes":{"type":"text/javascript"},"childNodes":[{"type":3,"textContent":"SCRIPT_PLACEHOLDER","id":461}],"id":460},{"type":3,"textContent":"\n\n","id":462}],"id":29}],"id":4}],"id":1},"initialOffset":{"left":0,"top":583}},"timestamp":1539674870338},{"type":3,"data":{"source":3,"id":1,"x":0,"y":582},"timestamp":1539674871058},{"type":3,"data":{"source":3,"id":1,"x":0,"y":528},"timestamp":1539674871158},{"type":3,"data":{"source":3,"id":1,"x":0,"y":375},"timestamp":1539674871258},{"type":3,"data":{"source":3,"id":1,"x":0,"y":318},"timestamp":1539674871358},{"type":3,"data":{"source":3,"id":1,"x":0,"y":317},"timestamp":1539674871523},{"type":3,"data":{"source":3,"id":1,"x":0,"y":275},"timestamp":1539674871624},{"type":3,"data":{"source":3,"id":1,"x":0,"y":148},"timestamp":1539674871724},{"type":3,"data":{"source":3,"id":1,"x":0,"y":59},"timestamp":1539674871824},{"type":3,"data":{"source":3,"id":1,"x":0,"y":53},"timestamp":1539674871923},{"type":3,"data":{"source":3,"id":1,"x":0,"y":54},"timestamp":1539674872190},{"type":3,"data":{"source":1,"positions":[{"x":1065,"y":237,"timeOffset":0}]},"timestamp":1539674872291},{"type":3,"data":{"source":3,"id":1,"x":0,"y":156},"timestamp":1539674872291},{"type":3,"data":{"source":3,"id":1,"x":0,"y":468},"timestamp":1539674872392},{"type":3,"data":{"source":3,"id":1,"x":0,"y":477},"timestamp":1539674872492},{"type":3,"data":{"source":3,"id":1,"x":0,"y":478},"timestamp":1539674872641},{"type":3,"data":{"source":3,"id":1,"x":0,"y":527},"timestamp":1539674872741},{"type":3,"data":{"source":1,"positions":[{"x":1064,"y":239,"timeOffset":-467}]},"timestamp":1539674872792},{"type":3,"data":{"source":3,"id":1,"x":0,"y":699},"timestamp":1539674872841},{"type":3,"data":{"source":3,"id":1,"x":0,"y":742},"timestamp":1539674872942},{"type":3,"data":{"source":1,"positions":[{"x":1064,"y":239,"timeOffset":-417},{"x":1065,"y":239,"timeOffset":-384},{"x":1066,"y":239,"timeOffset":-336},{"x":1066,"y":238,"timeOffset":-116},{"x":1066,"y":236,"timeOffset":-85},{"x":1068,"y":229,"timeOffset":-35},{"x":1077,"y":205,"timeOffset":-2}]},"timestamp":1539674873292},{"type":3,"data":{"source":1,"positions":[{"x":1088,"y":163,"timeOffset":-470},{"x":1098,"y":115,"timeOffset":-437},{"x":1104,"y":80,"timeOffset":-403},{"x":1104,"y":50,"timeOffset":-370},{"x":1104,"y":43,"timeOffset":-336},{"x":1104,"y":42,"timeOffset":-237},{"x":1104,"y":32,"timeOffset":-203},{"x":1105,"y":11,"timeOffset":-170}]},"timestamp":1539674873793}]; + const app = new App({ target: document.body, data: { - name: 'world', + events, }, }); From e99bd3245f07340143e022cdadb7675657e0e6ea Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Wed, 17 Oct 2018 19:10:45 +0800 Subject: [PATCH 028/524] add player controller --- src/App.html | 3 -- src/Controller.html | 108 +++++++++++++++++++++++++++++++++++++++++ src/Player.html | 114 +++++++++++++++++++++++++------------------- src/util.js | 7 --- src/utils.js | 33 +++++++++++++ 5 files changed, 206 insertions(+), 59 deletions(-) create mode 100644 src/Controller.html delete mode 100644 src/util.js create mode 100644 src/utils.js diff --git a/src/App.html b/src/App.html index c54fde621a..f19586f42b 100644 --- a/src/App.html +++ b/src/App.html @@ -1,6 +1,3 @@ -

- rrweb player playground -

\ No newline at end of file diff --git a/src/Player.html b/src/Player.html index 1d5a561759..b47fe52ab6 100644 --- a/src/Player.html +++ b/src/Player.html @@ -1,60 +1,24 @@
+ {#if replayer} + + {/if}
- - \ No newline at end of file + + + \ No newline at end of file diff --git a/src/util.js b/src/util.js deleted file mode 100644 index da07ec1932..0000000000 --- a/src/util.js +++ /dev/null @@ -1,7 +0,0 @@ -export function inlineCss(cssObj) { - let style = ''; - Object.keys(cssObj).forEach(key => { - style += `${key}: ${cssObj[key]};`; - }); - return style; -} diff --git a/src/utils.js b/src/utils.js new file mode 100644 index 0000000000..b19c460383 --- /dev/null +++ b/src/utils.js @@ -0,0 +1,33 @@ +export function inlineCss(cssObj) { + let style = ''; + Object.keys(cssObj).forEach(key => { + style += `${key}: ${cssObj[key]};`; + }); + return style; +} + +function padZero(num, len = 2) { + const threshold = Math.pow(10, len - 1); + if (num < threshold) { + num = String(num); + while (String(threshold).length > num.length) { + num = '0' + num; + } + } + return num; +} + +const SECOND = 1000; +const MINUTE = 60 * SECOND; +const HOUR = 60 * MINUTE; +export function formatTime(ms) { + const hour = Math.floor(ms / HOUR); + ms = ms % HOUR; + const minute = Math.floor(ms / MINUTE); + ms = ms % MINUTE; + const second = Math.floor(ms / SECOND); + if (hour) { + return `${padZero(hour)}:${padZero(minute)}:${padZero(minute)}`; + } + return `${padZero(hour)}:${padZero(second)}`; +} From 0f7fa678712637b66bbe735f88503d7e26bb5e4c Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Thu, 18 Oct 2018 15:21:51 +0800 Subject: [PATCH 029/524] impl controller play, pause and speed --- src/Controller.html | 62 ++++++++++++++++++++++++++++++++++++++------- src/main.js | 2 +- 2 files changed, 54 insertions(+), 10 deletions(-) diff --git a/src/Controller.html b/src/Controller.html index 6a62eb1e3a..fae075420c 100644 --- a/src/Controller.html +++ b/src/Controller.html @@ -7,7 +7,14 @@
{formatTime(meta.totalTime)} - +
+ + {#each [1, 2, 4, 8] as s} + + {/each} +
\n ","id":443},{"type":3,"textContent":"\n\n ","id":444},{"type":5,"textContent":" fundebug ","id":445},{"type":3,"textContent":"\n\n ","id":446},{"type":5,"textContent":" \n ","id":447},{"type":3,"textContent":"\n\n ","id":448},{"type":5,"textContent":" fullstory ","id":449},{"type":3,"textContent":"\n\n ","id":450},{"type":5,"textContent":" ","id":451},{"type":3,"textContent":"\n\n ","id":452},{"type":2,"tagName":"script","attributes":{"src":"http://127.0.0.1:5500/src/record.js"},"childNodes":[],"id":453},{"type":3,"textContent":"\n ","id":454},{"type":2,"tagName":"script","attributes":{},"childNodes":[{"type":3,"textContent":"SCRIPT_PLACEHOLDER","id":456}],"id":455},{"type":3,"textContent":"\n\n","id":457},{"type":5,"textContent":" Code injected by live-server ","id":458},{"type":3,"textContent":"\n","id":459},{"type":2,"tagName":"script","attributes":{"type":"text/javascript"},"childNodes":[{"type":3,"textContent":"SCRIPT_PLACEHOLDER","id":461}],"id":460},{"type":3,"textContent":"\n\n","id":462}],"id":29}],"id":4}],"id":1},"initialOffset":{"left":0,"top":583}},"timestamp":1539674870338},{"type":3,"data":{"source":3,"id":1,"x":0,"y":582},"timestamp":1539674871058},{"type":3,"data":{"source":3,"id":1,"x":0,"y":528},"timestamp":1539674871158},{"type":3,"data":{"source":3,"id":1,"x":0,"y":375},"timestamp":1539674871258},{"type":3,"data":{"source":3,"id":1,"x":0,"y":318},"timestamp":1539674871358},{"type":3,"data":{"source":3,"id":1,"x":0,"y":317},"timestamp":1539674871523},{"type":3,"data":{"source":3,"id":1,"x":0,"y":275},"timestamp":1539674871624},{"type":3,"data":{"source":3,"id":1,"x":0,"y":148},"timestamp":1539674871724},{"type":3,"data":{"source":3,"id":1,"x":0,"y":59},"timestamp":1539674871824},{"type":3,"data":{"source":3,"id":1,"x":0,"y":53},"timestamp":1539674871923},{"type":3,"data":{"source":3,"id":1,"x":0,"y":54},"timestamp":1539674872190},{"type":3,"data":{"source":1,"positions":[{"x":1065,"y":237,"timeOffset":0}]},"timestamp":1539674872291},{"type":3,"data":{"source":3,"id":1,"x":0,"y":156},"timestamp":1539674872291},{"type":3,"data":{"source":3,"id":1,"x":0,"y":468},"timestamp":1539674872392},{"type":3,"data":{"source":3,"id":1,"x":0,"y":477},"timestamp":1539674872492},{"type":3,"data":{"source":3,"id":1,"x":0,"y":478},"timestamp":1539674872641},{"type":3,"data":{"source":3,"id":1,"x":0,"y":527},"timestamp":1539674872741},{"type":3,"data":{"source":1,"positions":[{"x":1064,"y":239,"timeOffset":-467}]},"timestamp":1539674872792},{"type":3,"data":{"source":3,"id":1,"x":0,"y":699},"timestamp":1539674872841},{"type":3,"data":{"source":3,"id":1,"x":0,"y":742},"timestamp":1539674872942},{"type":3,"data":{"source":1,"positions":[{"x":1064,"y":239,"timeOffset":-417},{"x":1065,"y":239,"timeOffset":-384},{"x":1066,"y":239,"timeOffset":-336},{"x":1066,"y":238,"timeOffset":-116},{"x":1066,"y":236,"timeOffset":-85},{"x":1068,"y":229,"timeOffset":-35},{"x":1077,"y":205,"timeOffset":-2}]},"timestamp":1539674873292},{"type":3,"data":{"source":1,"positions":[{"x":1088,"y":163,"timeOffset":-470},{"x":1098,"y":115,"timeOffset":-437},{"x":1104,"y":80,"timeOffset":-403},{"x":1104,"y":50,"timeOffset":-370},{"x":1104,"y":43,"timeOffset":-336},{"x":1104,"y":42,"timeOffset":-237},{"x":1104,"y":32,"timeOffset":-203},{"x":1105,"y":11,"timeOffset":-170}]},"timestamp":1539674873793}]; + [{"type":0,"data":{"href":"http://localhost:5500/checkout-demo/"},"timestamp":1539774745277},{"type":1,"data":{"width":1600,"height":711},"timestamp":1539774745283},{"type":2,"data":{"node":{"type":0,"childNodes":[{"type":1,"name":"html","publicId":"","systemId":"","id":2},{"type":5,"textContent":" saved from url=(0052)https://getbootstrap.com/docs/4.1/examples/checkout/ ","id":3},{"type":2,"tagName":"html","attributes":{"lang":"en"},"childNodes":[{"type":2,"tagName":"head","attributes":{},"childNodes":[{"type":3,"textContent":"\n ","id":6},{"type":2,"tagName":"meta","attributes":{"http-equiv":"Content-Type","content":"text/html; charset=UTF-8"},"childNodes":[],"id":7},{"type":3,"textContent":"\n\n ","id":8},{"type":2,"tagName":"meta","attributes":{"name":"viewport","content":"width=device-width, initial-scale=1, shrink-to-fit=no"},"childNodes":[],"id":9},{"type":3,"textContent":"\n ","id":10},{"type":2,"tagName":"meta","attributes":{"name":"description","content":""},"childNodes":[],"id":11},{"type":3,"textContent":"\n ","id":12},{"type":2,"tagName":"meta","attributes":{"name":"author","content":""},"childNodes":[],"id":13},{"type":3,"textContent":"\n ","id":14},{"type":2,"tagName":"link","attributes":{"rel":"icon","href":"https://getbootstrap.com/favicon.ico"},"childNodes":[],"id":15},{"type":3,"textContent":"\n\n ","id":16},{"type":2,"tagName":"title","attributes":{},"childNodes":[{"type":3,"textContent":"Checkout example for Bootstrap","id":18}],"id":17},{"type":3,"textContent":"\n\n ","id":19},{"type":5,"textContent":" Bootstrap core CSS ","id":20},{"type":3,"textContent":"\n ","id":21},{"type":2,"tagName":"link","attributes":{"_cssText":":root { --blue:#007bff; --indigo:#6610f2; --purple:#6f42c1; --pink:#e83e8c; --red:#dc3545; --orange:#fd7e14; --yellow:#ffc107; --green:#28a745; --teal:#20c997; --cyan:#17a2b8; --white:#fff; --gray:#6c757d; --gray-dark:#343a40; --primary:#007bff; --secondary:#6c757d; --success:#28a745; --info:#17a2b8; --warning:#ffc107; --danger:#dc3545; --light:#f8f9fa; --dark:#343a40; --breakpoint-xs:0; --breakpoint-sm:576px; --breakpoint-md:768px; --breakpoint-lg:992px; --breakpoint-xl:1200px; --font-family-sans-serif:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\",\"Noto Color Emoji\"; --font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace; }*, ::after, ::before { box-sizing: border-box; }html { font-family: sans-serif; line-height: 1.15; text-size-adjust: 100%; -webkit-tap-highlight-color: transparent; }article, aside, figcaption, figure, footer, header, hgroup, main, nav, section { display: block; }body { margin: 0px; font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\"; font-size: 1rem; font-weight: 400; line-height: 1.5; color: rgb(33, 37, 41); text-align: left; background-color: rgb(255, 255, 255); }[tabindex=\"-1\"]:focus { outline: 0px !important; }hr { box-sizing: content-box; height: 0px; overflow: visible; }h1, h2, h3, h4, h5, h6 { margin-top: 0px; margin-bottom: 0.5rem; }p { margin-top: 0px; margin-bottom: 1rem; }abbr[data-original-title], abbr[title] { text-decoration: underline dotted; cursor: help; border-bottom: 0px; }address { margin-bottom: 1rem; font-style: normal; line-height: inherit; }dl, ol, ul { margin-top: 0px; margin-bottom: 1rem; }ol ol, ol ul, ul ol, ul ul { margin-bottom: 0px; }dt { font-weight: 700; }dd { margin-bottom: 0.5rem; margin-left: 0px; }blockquote { margin: 0px 0px 1rem; }dfn { font-style: italic; }b, strong { font-weight: bolder; }small { font-size: 80%; }sub, sup { position: relative; font-size: 75%; line-height: 0; vertical-align: baseline; }sub { bottom: -0.25em; }sup { top: -0.5em; }a { color: rgb(0, 123, 255); text-decoration: none; background-color: transparent; }a:hover { color: rgb(0, 86, 179); text-decoration: underline; }a:not([href]):not([tabindex]) { color: inherit; text-decoration: none; }a:not([href]):not([tabindex]):focus, a:not([href]):not([tabindex]):hover { color: inherit; text-decoration: none; }a:not([href]):not([tabindex]):focus { outline: 0px; }code, kbd, pre, samp { font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; font-size: 1em; }pre { margin-top: 0px; margin-bottom: 1rem; overflow: auto; }figure { margin: 0px 0px 1rem; }img { vertical-align: middle; border-style: none; }svg { overflow: hidden; vertical-align: middle; }table { border-collapse: collapse; }caption { padding-top: 0.75rem; padding-bottom: 0.75rem; color: rgb(108, 117, 125); text-align: left; caption-side: bottom; }th { text-align: inherit; }label { display: inline-block; margin-bottom: 0.5rem; }button { border-radius: 0px; }button:focus { outline: -webkit-focus-ring-color auto 5px; }button, input, optgroup, select, textarea { margin: 0px; font-family: inherit; font-size: inherit; line-height: inherit; }button, input { overflow: visible; }button, select { text-transform: none; }[type=\"reset\"], [type=\"submit\"], button, html [type=\"button\"] { -webkit-appearance: button; }input[type=\"checkbox\"], input[type=\"radio\"] { box-sizing: border-box; padding: 0px; }input[type=\"date\"], input[type=\"datetime-local\"], input[type=\"month\"], input[type=\"time\"] { -webkit-appearance: listbox; }textarea { overflow: auto; resize: vertical; }fieldset { min-width: 0px; padding: 0px; margin: 0px; border: 0px; }legend { display: block; width: 100%; max-width: 100%; padding: 0px; margin-bottom: 0.5rem; font-size: 1.5rem; line-height: inherit; color: inherit; white-space: normal; }progress { vertical-align: baseline; }[type=\"number\"]::-webkit-inner-spin-button, [type=\"number\"]::-webkit-outer-spin-button { height: auto; }[type=\"search\"] { outline-offset: -2px; -webkit-appearance: none; }[type=\"search\"]::-webkit-search-cancel-button, [type=\"search\"]::-webkit-search-decoration { -webkit-appearance: none; }::-webkit-file-upload-button { font: inherit; -webkit-appearance: button; }output { display: inline-block; }summary { display: list-item; cursor: pointer; }template { display: none; }[hidden] { display: none !important; }.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 { margin-bottom: 0.5rem; font-family: inherit; font-weight: 500; line-height: 1.2; color: inherit; }.h1, h1 { font-size: 2.5rem; }.h2, h2 { font-size: 2rem; }.h3, h3 { font-size: 1.75rem; }.h4, h4 { font-size: 1.5rem; }.h5, h5 { font-size: 1.25rem; }.h6, h6 { font-size: 1rem; }.lead { font-size: 1.25rem; font-weight: 300; }.display-1 { font-size: 6rem; font-weight: 300; line-height: 1.2; }.display-2 { font-size: 5.5rem; font-weight: 300; line-height: 1.2; }.display-3 { font-size: 4.5rem; font-weight: 300; line-height: 1.2; }.display-4 { font-size: 3.5rem; font-weight: 300; line-height: 1.2; }hr { margin-top: 1rem; margin-bottom: 1rem; border-width: 1px 0px 0px; border-right-style: initial; border-bottom-style: initial; border-left-style: initial; border-right-color: initial; border-bottom-color: initial; border-left-color: initial; border-image: initial; border-top-style: solid; border-top-color: rgba(0, 0, 0, 0.1); }.small, small { font-size: 80%; font-weight: 400; }.mark, mark { padding: 0.2em; background-color: rgb(252, 248, 227); }.list-unstyled { padding-left: 0px; list-style: none; }.list-inline { padding-left: 0px; list-style: none; }.list-inline-item { display: inline-block; }.list-inline-item:not(:last-child) { margin-right: 0.5rem; }.initialism { font-size: 90%; text-transform: uppercase; }.blockquote { margin-bottom: 1rem; font-size: 1.25rem; }.blockquote-footer { display: block; font-size: 80%; color: rgb(108, 117, 125); }.blockquote-footer::before { content: \"— \"; }.img-fluid { max-width: 100%; height: auto; }.img-thumbnail { padding: 0.25rem; background-color: rgb(255, 255, 255); border: 1px solid rgb(222, 226, 230); border-radius: 0.25rem; max-width: 100%; height: auto; }.figure { display: inline-block; }.figure-img { margin-bottom: 0.5rem; line-height: 1; }.figure-caption { font-size: 90%; color: rgb(108, 117, 125); }code { font-size: 87.5%; color: rgb(232, 62, 140); word-break: break-word; }a > code { color: inherit; }kbd { padding: 0.2rem 0.4rem; font-size: 87.5%; color: rgb(255, 255, 255); background-color: rgb(33, 37, 41); border-radius: 0.2rem; }kbd kbd { padding: 0px; font-size: 100%; font-weight: 700; }pre { display: block; font-size: 87.5%; color: rgb(33, 37, 41); }pre code { font-size: inherit; color: inherit; word-break: normal; }.pre-scrollable { max-height: 340px; overflow-y: scroll; }.container { width: 100%; padding-right: 15px; padding-left: 15px; margin-right: auto; margin-left: auto; }@media (min-width: 576px) {\n .container { max-width: 540px; }\n}@media (min-width: 768px) {\n .container { max-width: 720px; }\n}@media (min-width: 992px) {\n .container { max-width: 960px; }\n}@media (min-width: 1200px) {\n .container { max-width: 1140px; }\n}.container-fluid { width: 100%; padding-right: 15px; padding-left: 15px; margin-right: auto; margin-left: auto; }.row { display: flex; flex-wrap: wrap; margin-right: -15px; margin-left: -15px; }.no-gutters { margin-right: 0px; margin-left: 0px; }.no-gutters > .col, .no-gutters > [class*=\"col-\"] { padding-right: 0px; padding-left: 0px; }.col, .col-1, .col-10, .col-11, .col-12, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-auto, .col-lg, .col-lg-1, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-auto, .col-md, .col-md-1, .col-md-10, .col-md-11, .col-md-12, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-auto, .col-sm, .col-sm-1, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-auto, .col-xl, .col-xl-1, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-auto { position: relative; width: 100%; min-height: 1px; padding-right: 15px; padding-left: 15px; }.col { flex-basis: 0px; flex-grow: 1; max-width: 100%; }.col-auto { flex: 0 0 auto; width: auto; max-width: none; }.col-1 { flex: 0 0 8.33333%; max-width: 8.33333%; }.col-2 { flex: 0 0 16.6667%; max-width: 16.6667%; }.col-3 { flex: 0 0 25%; max-width: 25%; }.col-4 { flex: 0 0 33.3333%; max-width: 33.3333%; }.col-5 { flex: 0 0 41.6667%; max-width: 41.6667%; }.col-6 { flex: 0 0 50%; max-width: 50%; }.col-7 { flex: 0 0 58.3333%; max-width: 58.3333%; }.col-8 { flex: 0 0 66.6667%; max-width: 66.6667%; }.col-9 { flex: 0 0 75%; max-width: 75%; }.col-10 { flex: 0 0 83.3333%; max-width: 83.3333%; }.col-11 { flex: 0 0 91.6667%; max-width: 91.6667%; }.col-12 { flex: 0 0 100%; max-width: 100%; }.order-first { order: -1; }.order-last { order: 13; }.order-0 { order: 0; }.order-1 { order: 1; }.order-2 { order: 2; }.order-3 { order: 3; }.order-4 { order: 4; }.order-5 { order: 5; }.order-6 { order: 6; }.order-7 { order: 7; }.order-8 { order: 8; }.order-9 { order: 9; }.order-10 { order: 10; }.order-11 { order: 11; }.order-12 { order: 12; }.offset-1 { margin-left: 8.33333%; }.offset-2 { margin-left: 16.6667%; }.offset-3 { margin-left: 25%; }.offset-4 { margin-left: 33.3333%; }.offset-5 { margin-left: 41.6667%; }.offset-6 { margin-left: 50%; }.offset-7 { margin-left: 58.3333%; }.offset-8 { margin-left: 66.6667%; }.offset-9 { margin-left: 75%; }.offset-10 { margin-left: 83.3333%; }.offset-11 { margin-left: 91.6667%; }@media (min-width: 576px) {\n .col-sm { flex-basis: 0px; flex-grow: 1; max-width: 100%; }\n .col-sm-auto { flex: 0 0 auto; width: auto; max-width: none; }\n .col-sm-1 { flex: 0 0 8.33333%; max-width: 8.33333%; }\n .col-sm-2 { flex: 0 0 16.6667%; max-width: 16.6667%; }\n .col-sm-3 { flex: 0 0 25%; max-width: 25%; }\n .col-sm-4 { flex: 0 0 33.3333%; max-width: 33.3333%; }\n .col-sm-5 { flex: 0 0 41.6667%; max-width: 41.6667%; }\n .col-sm-6 { flex: 0 0 50%; max-width: 50%; }\n .col-sm-7 { flex: 0 0 58.3333%; max-width: 58.3333%; }\n .col-sm-8 { flex: 0 0 66.6667%; max-width: 66.6667%; }\n .col-sm-9 { flex: 0 0 75%; max-width: 75%; }\n .col-sm-10 { flex: 0 0 83.3333%; max-width: 83.3333%; }\n .col-sm-11 { flex: 0 0 91.6667%; max-width: 91.6667%; }\n .col-sm-12 { flex: 0 0 100%; max-width: 100%; }\n .order-sm-first { order: -1; }\n .order-sm-last { order: 13; }\n .order-sm-0 { order: 0; }\n .order-sm-1 { order: 1; }\n .order-sm-2 { order: 2; }\n .order-sm-3 { order: 3; }\n .order-sm-4 { order: 4; }\n .order-sm-5 { order: 5; }\n .order-sm-6 { order: 6; }\n .order-sm-7 { order: 7; }\n .order-sm-8 { order: 8; }\n .order-sm-9 { order: 9; }\n .order-sm-10 { order: 10; }\n .order-sm-11 { order: 11; }\n .order-sm-12 { order: 12; }\n .offset-sm-0 { margin-left: 0px; }\n .offset-sm-1 { margin-left: 8.33333%; }\n .offset-sm-2 { margin-left: 16.6667%; }\n .offset-sm-3 { margin-left: 25%; }\n .offset-sm-4 { margin-left: 33.3333%; }\n .offset-sm-5 { margin-left: 41.6667%; }\n .offset-sm-6 { margin-left: 50%; }\n .offset-sm-7 { margin-left: 58.3333%; }\n .offset-sm-8 { margin-left: 66.6667%; }\n .offset-sm-9 { margin-left: 75%; }\n .offset-sm-10 { margin-left: 83.3333%; }\n .offset-sm-11 { margin-left: 91.6667%; }\n}@media (min-width: 768px) {\n .col-md { flex-basis: 0px; flex-grow: 1; max-width: 100%; }\n .col-md-auto { flex: 0 0 auto; width: auto; max-width: none; }\n .col-md-1 { flex: 0 0 8.33333%; max-width: 8.33333%; }\n .col-md-2 { flex: 0 0 16.6667%; max-width: 16.6667%; }\n .col-md-3 { flex: 0 0 25%; max-width: 25%; }\n .col-md-4 { flex: 0 0 33.3333%; max-width: 33.3333%; }\n .col-md-5 { flex: 0 0 41.6667%; max-width: 41.6667%; }\n .col-md-6 { flex: 0 0 50%; max-width: 50%; }\n .col-md-7 { flex: 0 0 58.3333%; max-width: 58.3333%; }\n .col-md-8 { flex: 0 0 66.6667%; max-width: 66.6667%; }\n .col-md-9 { flex: 0 0 75%; max-width: 75%; }\n .col-md-10 { flex: 0 0 83.3333%; max-width: 83.3333%; }\n .col-md-11 { flex: 0 0 91.6667%; max-width: 91.6667%; }\n .col-md-12 { flex: 0 0 100%; max-width: 100%; }\n .order-md-first { order: -1; }\n .order-md-last { order: 13; }\n .order-md-0 { order: 0; }\n .order-md-1 { order: 1; }\n .order-md-2 { order: 2; }\n .order-md-3 { order: 3; }\n .order-md-4 { order: 4; }\n .order-md-5 { order: 5; }\n .order-md-6 { order: 6; }\n .order-md-7 { order: 7; }\n .order-md-8 { order: 8; }\n .order-md-9 { order: 9; }\n .order-md-10 { order: 10; }\n .order-md-11 { order: 11; }\n .order-md-12 { order: 12; }\n .offset-md-0 { margin-left: 0px; }\n .offset-md-1 { margin-left: 8.33333%; }\n .offset-md-2 { margin-left: 16.6667%; }\n .offset-md-3 { margin-left: 25%; }\n .offset-md-4 { margin-left: 33.3333%; }\n .offset-md-5 { margin-left: 41.6667%; }\n .offset-md-6 { margin-left: 50%; }\n .offset-md-7 { margin-left: 58.3333%; }\n .offset-md-8 { margin-left: 66.6667%; }\n .offset-md-9 { margin-left: 75%; }\n .offset-md-10 { margin-left: 83.3333%; }\n .offset-md-11 { margin-left: 91.6667%; }\n}@media (min-width: 992px) {\n .col-lg { flex-basis: 0px; flex-grow: 1; max-width: 100%; }\n .col-lg-auto { flex: 0 0 auto; width: auto; max-width: none; }\n .col-lg-1 { flex: 0 0 8.33333%; max-width: 8.33333%; }\n .col-lg-2 { flex: 0 0 16.6667%; max-width: 16.6667%; }\n .col-lg-3 { flex: 0 0 25%; max-width: 25%; }\n .col-lg-4 { flex: 0 0 33.3333%; max-width: 33.3333%; }\n .col-lg-5 { flex: 0 0 41.6667%; max-width: 41.6667%; }\n .col-lg-6 { flex: 0 0 50%; max-width: 50%; }\n .col-lg-7 { flex: 0 0 58.3333%; max-width: 58.3333%; }\n .col-lg-8 { flex: 0 0 66.6667%; max-width: 66.6667%; }\n .col-lg-9 { flex: 0 0 75%; max-width: 75%; }\n .col-lg-10 { flex: 0 0 83.3333%; max-width: 83.3333%; }\n .col-lg-11 { flex: 0 0 91.6667%; max-width: 91.6667%; }\n .col-lg-12 { flex: 0 0 100%; max-width: 100%; }\n .order-lg-first { order: -1; }\n .order-lg-last { order: 13; }\n .order-lg-0 { order: 0; }\n .order-lg-1 { order: 1; }\n .order-lg-2 { order: 2; }\n .order-lg-3 { order: 3; }\n .order-lg-4 { order: 4; }\n .order-lg-5 { order: 5; }\n .order-lg-6 { order: 6; }\n .order-lg-7 { order: 7; }\n .order-lg-8 { order: 8; }\n .order-lg-9 { order: 9; }\n .order-lg-10 { order: 10; }\n .order-lg-11 { order: 11; }\n .order-lg-12 { order: 12; }\n .offset-lg-0 { margin-left: 0px; }\n .offset-lg-1 { margin-left: 8.33333%; }\n .offset-lg-2 { margin-left: 16.6667%; }\n .offset-lg-3 { margin-left: 25%; }\n .offset-lg-4 { margin-left: 33.3333%; }\n .offset-lg-5 { margin-left: 41.6667%; }\n .offset-lg-6 { margin-left: 50%; }\n .offset-lg-7 { margin-left: 58.3333%; }\n .offset-lg-8 { margin-left: 66.6667%; }\n .offset-lg-9 { margin-left: 75%; }\n .offset-lg-10 { margin-left: 83.3333%; }\n .offset-lg-11 { margin-left: 91.6667%; }\n}@media (min-width: 1200px) {\n .col-xl { flex-basis: 0px; flex-grow: 1; max-width: 100%; }\n .col-xl-auto { flex: 0 0 auto; width: auto; max-width: none; }\n .col-xl-1 { flex: 0 0 8.33333%; max-width: 8.33333%; }\n .col-xl-2 { flex: 0 0 16.6667%; max-width: 16.6667%; }\n .col-xl-3 { flex: 0 0 25%; max-width: 25%; }\n .col-xl-4 { flex: 0 0 33.3333%; max-width: 33.3333%; }\n .col-xl-5 { flex: 0 0 41.6667%; max-width: 41.6667%; }\n .col-xl-6 { flex: 0 0 50%; max-width: 50%; }\n .col-xl-7 { flex: 0 0 58.3333%; max-width: 58.3333%; }\n .col-xl-8 { flex: 0 0 66.6667%; max-width: 66.6667%; }\n .col-xl-9 { flex: 0 0 75%; max-width: 75%; }\n .col-xl-10 { flex: 0 0 83.3333%; max-width: 83.3333%; }\n .col-xl-11 { flex: 0 0 91.6667%; max-width: 91.6667%; }\n .col-xl-12 { flex: 0 0 100%; max-width: 100%; }\n .order-xl-first { order: -1; }\n .order-xl-last { order: 13; }\n .order-xl-0 { order: 0; }\n .order-xl-1 { order: 1; }\n .order-xl-2 { order: 2; }\n .order-xl-3 { order: 3; }\n .order-xl-4 { order: 4; }\n .order-xl-5 { order: 5; }\n .order-xl-6 { order: 6; }\n .order-xl-7 { order: 7; }\n .order-xl-8 { order: 8; }\n .order-xl-9 { order: 9; }\n .order-xl-10 { order: 10; }\n .order-xl-11 { order: 11; }\n .order-xl-12 { order: 12; }\n .offset-xl-0 { margin-left: 0px; }\n .offset-xl-1 { margin-left: 8.33333%; }\n .offset-xl-2 { margin-left: 16.6667%; }\n .offset-xl-3 { margin-left: 25%; }\n .offset-xl-4 { margin-left: 33.3333%; }\n .offset-xl-5 { margin-left: 41.6667%; }\n .offset-xl-6 { margin-left: 50%; }\n .offset-xl-7 { margin-left: 58.3333%; }\n .offset-xl-8 { margin-left: 66.6667%; }\n .offset-xl-9 { margin-left: 75%; }\n .offset-xl-10 { margin-left: 83.3333%; }\n .offset-xl-11 { margin-left: 91.6667%; }\n}.table { width: 100%; margin-bottom: 1rem; background-color: transparent; }.table td, .table th { padding: 0.75rem; vertical-align: top; border-top: 1px solid rgb(222, 226, 230); }.table thead th { vertical-align: bottom; border-bottom: 2px solid rgb(222, 226, 230); }.table tbody + tbody { border-top: 2px solid rgb(222, 226, 230); }.table .table { background-color: rgb(255, 255, 255); }.table-sm td, .table-sm th { padding: 0.3rem; }.table-bordered { border: 1px solid rgb(222, 226, 230); }.table-bordered td, .table-bordered th { border: 1px solid rgb(222, 226, 230); }.table-bordered thead td, .table-bordered thead th { border-bottom-width: 2px; }.table-borderless tbody + tbody, .table-borderless td, .table-borderless th, .table-borderless thead th { border: 0px; }.table-striped tbody tr:nth-of-type(2n+1) { background-color: rgba(0, 0, 0, 0.05); }.table-hover tbody tr:hover { background-color: rgba(0, 0, 0, 0.075); }.table-primary, .table-primary > td, .table-primary > th { background-color: rgb(184, 218, 255); }.table-hover .table-primary:hover { background-color: rgb(159, 205, 255); }.table-hover .table-primary:hover > td, .table-hover .table-primary:hover > th { background-color: rgb(159, 205, 255); }.table-secondary, .table-secondary > td, .table-secondary > th { background-color: rgb(214, 216, 219); }.table-hover .table-secondary:hover { background-color: rgb(200, 203, 207); }.table-hover .table-secondary:hover > td, .table-hover .table-secondary:hover > th { background-color: rgb(200, 203, 207); }.table-success, .table-success > td, .table-success > th { background-color: rgb(195, 230, 203); }.table-hover .table-success:hover { background-color: rgb(177, 223, 187); }.table-hover .table-success:hover > td, .table-hover .table-success:hover > th { background-color: rgb(177, 223, 187); }.table-info, .table-info > td, .table-info > th { background-color: rgb(190, 229, 235); }.table-hover .table-info:hover { background-color: rgb(171, 221, 229); }.table-hover .table-info:hover > td, .table-hover .table-info:hover > th { background-color: rgb(171, 221, 229); }.table-warning, .table-warning > td, .table-warning > th { background-color: rgb(255, 238, 186); }.table-hover .table-warning:hover { background-color: rgb(255, 232, 161); }.table-hover .table-warning:hover > td, .table-hover .table-warning:hover > th { background-color: rgb(255, 232, 161); }.table-danger, .table-danger > td, .table-danger > th { background-color: rgb(245, 198, 203); }.table-hover .table-danger:hover { background-color: rgb(241, 176, 183); }.table-hover .table-danger:hover > td, .table-hover .table-danger:hover > th { background-color: rgb(241, 176, 183); }.table-light, .table-light > td, .table-light > th { background-color: rgb(253, 253, 254); }.table-hover .table-light:hover { background-color: rgb(236, 236, 246); }.table-hover .table-light:hover > td, .table-hover .table-light:hover > th { background-color: rgb(236, 236, 246); }.table-dark, .table-dark > td, .table-dark > th { background-color: rgb(198, 200, 202); }.table-hover .table-dark:hover { background-color: rgb(185, 187, 190); }.table-hover .table-dark:hover > td, .table-hover .table-dark:hover > th { background-color: rgb(185, 187, 190); }.table-active, .table-active > td, .table-active > th { background-color: rgba(0, 0, 0, 0.075); }.table-hover .table-active:hover { background-color: rgba(0, 0, 0, 0.075); }.table-hover .table-active:hover > td, .table-hover .table-active:hover > th { background-color: rgba(0, 0, 0, 0.075); }.table .thead-dark th { color: rgb(255, 255, 255); background-color: rgb(33, 37, 41); border-color: rgb(50, 56, 62); }.table .thead-light th { color: rgb(73, 80, 87); background-color: rgb(233, 236, 239); border-color: rgb(222, 226, 230); }.table-dark { color: rgb(255, 255, 255); background-color: rgb(33, 37, 41); }.table-dark td, .table-dark th, .table-dark thead th { border-color: rgb(50, 56, 62); }.table-dark.table-bordered { border: 0px; }.table-dark.table-striped tbody tr:nth-of-type(2n+1) { background-color: rgba(255, 255, 255, 0.05); }.table-dark.table-hover tbody tr:hover { background-color: rgba(255, 255, 255, 0.075); }@media (max-width: 575.98px) {\n .table-responsive-sm { display: block; width: 100%; overflow-x: auto; }\n .table-responsive-sm > .table-bordered { border: 0px; }\n}@media (max-width: 767.98px) {\n .table-responsive-md { display: block; width: 100%; overflow-x: auto; }\n .table-responsive-md > .table-bordered { border: 0px; }\n}@media (max-width: 991.98px) {\n .table-responsive-lg { display: block; width: 100%; overflow-x: auto; }\n .table-responsive-lg > .table-bordered { border: 0px; }\n}@media (max-width: 1199.98px) {\n .table-responsive-xl { display: block; width: 100%; overflow-x: auto; }\n .table-responsive-xl > .table-bordered { border: 0px; }\n}.table-responsive { display: block; width: 100%; overflow-x: auto; }.table-responsive > .table-bordered { border: 0px; }.form-control { display: block; width: 100%; height: calc(2.25rem + 2px); padding: 0.375rem 0.75rem; font-size: 1rem; line-height: 1.5; color: rgb(73, 80, 87); background-color: rgb(255, 255, 255); background-clip: padding-box; border: 1px solid rgb(206, 212, 218); border-radius: 0.25rem; transition: border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; }@media not all {\n .form-control { transition: none 0s ease 0s; }\n}.form-control:focus { color: rgb(73, 80, 87); background-color: rgb(255, 255, 255); border-color: rgb(128, 189, 255); outline: 0px; box-shadow: rgba(0, 123, 255, 0.25) 0px 0px 0px 0.2rem; }.form-control::-webkit-input-placeholder { color: rgb(108, 117, 125); opacity: 1; }.form-control::placeholder { color: rgb(108, 117, 125); opacity: 1; }.form-control:disabled, .form-control[readonly] { background-color: rgb(233, 236, 239); opacity: 1; }.form-control-file, .form-control-range { display: block; width: 100%; }.col-form-label { padding-top: calc(0.375rem + 1px); padding-bottom: calc(0.375rem + 1px); margin-bottom: 0px; font-size: inherit; line-height: 1.5; }.col-form-label-lg { padding-top: calc(0.5rem + 1px); padding-bottom: calc(0.5rem + 1px); font-size: 1.25rem; line-height: 1.5; }.col-form-label-sm { padding-top: calc(0.25rem + 1px); padding-bottom: calc(0.25rem + 1px); font-size: 0.875rem; line-height: 1.5; }.form-control-plaintext { display: block; width: 100%; padding-top: 0.375rem; padding-bottom: 0.375rem; margin-bottom: 0px; line-height: 1.5; color: rgb(33, 37, 41); background-color: transparent; border-style: solid; border-color: transparent; border-image: initial; border-width: 1px 0px; }.form-control-plaintext.form-control-lg, .form-control-plaintext.form-control-sm { padding-right: 0px; padding-left: 0px; }.form-control-sm { height: calc(1.8125rem + 2px); padding: 0.25rem 0.5rem; font-size: 0.875rem; line-height: 1.5; border-radius: 0.2rem; }.form-control-lg { height: calc(2.875rem + 2px); padding: 0.5rem 1rem; font-size: 1.25rem; line-height: 1.5; border-radius: 0.3rem; }select.form-control[multiple], select.form-control[size] { height: auto; }textarea.form-control { height: auto; }.form-group { margin-bottom: 1rem; }.form-text { display: block; margin-top: 0.25rem; }.form-row { display: flex; flex-wrap: wrap; margin-right: -5px; margin-left: -5px; }.form-row > .col, .form-row > [class*=\"col-\"] { padding-right: 5px; padding-left: 5px; }.form-check { position: relative; display: block; padding-left: 1.25rem; }.form-check-input { position: absolute; margin-top: 0.3rem; margin-left: -1.25rem; }.form-check-input:disabled ~ .form-check-label { color: rgb(108, 117, 125); }.form-check-label { margin-bottom: 0px; }.form-check-inline { display: inline-flex; align-items: center; padding-left: 0px; margin-right: 0.75rem; }.form-check-inline .form-check-input { position: static; margin-top: 0px; margin-right: 0.3125rem; margin-left: 0px; }.valid-feedback { display: none; width: 100%; margin-top: 0.25rem; font-size: 80%; color: rgb(40, 167, 69); }.valid-tooltip { position: absolute; top: 100%; z-index: 5; display: none; max-width: 100%; padding: 0.25rem 0.5rem; margin-top: 0.1rem; font-size: 0.875rem; line-height: 1.5; color: rgb(255, 255, 255); background-color: rgba(40, 167, 69, 0.9); border-radius: 0.25rem; }.custom-select.is-valid, .form-control.is-valid, .was-validated .custom-select:valid, .was-validated .form-control:valid { border-color: rgb(40, 167, 69); }.custom-select.is-valid:focus, .form-control.is-valid:focus, .was-validated .custom-select:valid:focus, .was-validated .form-control:valid:focus { border-color: rgb(40, 167, 69); box-shadow: rgba(40, 167, 69, 0.25) 0px 0px 0px 0.2rem; }.custom-select.is-valid ~ .valid-feedback, .custom-select.is-valid ~ .valid-tooltip, .form-control.is-valid ~ .valid-feedback, .form-control.is-valid ~ .valid-tooltip, .was-validated .custom-select:valid ~ .valid-feedback, .was-validated .custom-select:valid ~ .valid-tooltip, .was-validated .form-control:valid ~ .valid-feedback, .was-validated .form-control:valid ~ .valid-tooltip { display: block; }.form-control-file.is-valid ~ .valid-feedback, .form-control-file.is-valid ~ .valid-tooltip, .was-validated .form-control-file:valid ~ .valid-feedback, .was-validated .form-control-file:valid ~ .valid-tooltip { display: block; }.form-check-input.is-valid ~ .form-check-label, .was-validated .form-check-input:valid ~ .form-check-label { color: rgb(40, 167, 69); }.form-check-input.is-valid ~ .valid-feedback, .form-check-input.is-valid ~ .valid-tooltip, .was-validated .form-check-input:valid ~ .valid-feedback, .was-validated .form-check-input:valid ~ .valid-tooltip { display: block; }.custom-control-input.is-valid ~ .custom-control-label, .was-validated .custom-control-input:valid ~ .custom-control-label { color: rgb(40, 167, 69); }.custom-control-input.is-valid ~ .custom-control-label::before, .was-validated .custom-control-input:valid ~ .custom-control-label::before { background-color: rgb(113, 221, 138); }.custom-control-input.is-valid ~ .valid-feedback, .custom-control-input.is-valid ~ .valid-tooltip, .was-validated .custom-control-input:valid ~ .valid-feedback, .was-validated .custom-control-input:valid ~ .valid-tooltip { display: block; }.custom-control-input.is-valid:checked ~ .custom-control-label::before, .was-validated .custom-control-input:valid:checked ~ .custom-control-label::before { background-color: rgb(52, 206, 87); }.custom-control-input.is-valid:focus ~ .custom-control-label::before, .was-validated .custom-control-input:valid:focus ~ .custom-control-label::before { box-shadow: rgb(255, 255, 255) 0px 0px 0px 1px, rgba(40, 167, 69, 0.25) 0px 0px 0px 0.2rem; }.custom-file-input.is-valid ~ .custom-file-label, .was-validated .custom-file-input:valid ~ .custom-file-label { border-color: rgb(40, 167, 69); }.custom-file-input.is-valid ~ .custom-file-label::after, .was-validated .custom-file-input:valid ~ .custom-file-label::after { border-color: inherit; }.custom-file-input.is-valid ~ .valid-feedback, .custom-file-input.is-valid ~ .valid-tooltip, .was-validated .custom-file-input:valid ~ .valid-feedback, .was-validated .custom-file-input:valid ~ .valid-tooltip { display: block; }.custom-file-input.is-valid:focus ~ .custom-file-label, .was-validated .custom-file-input:valid:focus ~ .custom-file-label { box-shadow: rgba(40, 167, 69, 0.25) 0px 0px 0px 0.2rem; }.invalid-feedback { display: none; width: 100%; margin-top: 0.25rem; font-size: 80%; color: rgb(220, 53, 69); }.invalid-tooltip { position: absolute; top: 100%; z-index: 5; display: none; max-width: 100%; padding: 0.25rem 0.5rem; margin-top: 0.1rem; font-size: 0.875rem; line-height: 1.5; color: rgb(255, 255, 255); background-color: rgba(220, 53, 69, 0.9); border-radius: 0.25rem; }.custom-select.is-invalid, .form-control.is-invalid, .was-validated .custom-select:invalid, .was-validated .form-control:invalid { border-color: rgb(220, 53, 69); }.custom-select.is-invalid:focus, .form-control.is-invalid:focus, .was-validated .custom-select:invalid:focus, .was-validated .form-control:invalid:focus { border-color: rgb(220, 53, 69); box-shadow: rgba(220, 53, 69, 0.25) 0px 0px 0px 0.2rem; }.custom-select.is-invalid ~ .invalid-feedback, .custom-select.is-invalid ~ .invalid-tooltip, .form-control.is-invalid ~ .invalid-feedback, .form-control.is-invalid ~ .invalid-tooltip, .was-validated .custom-select:invalid ~ .invalid-feedback, .was-validated .custom-select:invalid ~ .invalid-tooltip, .was-validated .form-control:invalid ~ .invalid-feedback, .was-validated .form-control:invalid ~ .invalid-tooltip { display: block; }.form-control-file.is-invalid ~ .invalid-feedback, .form-control-file.is-invalid ~ .invalid-tooltip, .was-validated .form-control-file:invalid ~ .invalid-feedback, .was-validated .form-control-file:invalid ~ .invalid-tooltip { display: block; }.form-check-input.is-invalid ~ .form-check-label, .was-validated .form-check-input:invalid ~ .form-check-label { color: rgb(220, 53, 69); }.form-check-input.is-invalid ~ .invalid-feedback, .form-check-input.is-invalid ~ .invalid-tooltip, .was-validated .form-check-input:invalid ~ .invalid-feedback, .was-validated .form-check-input:invalid ~ .invalid-tooltip { display: block; }.custom-control-input.is-invalid ~ .custom-control-label, .was-validated .custom-control-input:invalid ~ .custom-control-label { color: rgb(220, 53, 69); }.custom-control-input.is-invalid ~ .custom-control-label::before, .was-validated .custom-control-input:invalid ~ .custom-control-label::before { background-color: rgb(239, 162, 169); }.custom-control-input.is-invalid ~ .invalid-feedback, .custom-control-input.is-invalid ~ .invalid-tooltip, .was-validated .custom-control-input:invalid ~ .invalid-feedback, .was-validated .custom-control-input:invalid ~ .invalid-tooltip { display: block; }.custom-control-input.is-invalid:checked ~ .custom-control-label::before, .was-validated .custom-control-input:invalid:checked ~ .custom-control-label::before { background-color: rgb(228, 96, 109); }.custom-control-input.is-invalid:focus ~ .custom-control-label::before, .was-validated .custom-control-input:invalid:focus ~ .custom-control-label::before { box-shadow: rgb(255, 255, 255) 0px 0px 0px 1px, rgba(220, 53, 69, 0.25) 0px 0px 0px 0.2rem; }.custom-file-input.is-invalid ~ .custom-file-label, .was-validated .custom-file-input:invalid ~ .custom-file-label { border-color: rgb(220, 53, 69); }.custom-file-input.is-invalid ~ .custom-file-label::after, .was-validated .custom-file-input:invalid ~ .custom-file-label::after { border-color: inherit; }.custom-file-input.is-invalid ~ .invalid-feedback, .custom-file-input.is-invalid ~ .invalid-tooltip, .was-validated .custom-file-input:invalid ~ .invalid-feedback, .was-validated .custom-file-input:invalid ~ .invalid-tooltip { display: block; }.custom-file-input.is-invalid:focus ~ .custom-file-label, .was-validated .custom-file-input:invalid:focus ~ .custom-file-label { box-shadow: rgba(220, 53, 69, 0.25) 0px 0px 0px 0.2rem; }.form-inline { display: flex; flex-flow: row wrap; align-items: center; }.form-inline .form-check { width: 100%; }@media (min-width: 576px) {\n .form-inline label { display: flex; align-items: center; justify-content: center; margin-bottom: 0px; }\n .form-inline .form-group { display: flex; flex: 0 0 auto; flex-flow: row wrap; align-items: center; margin-bottom: 0px; }\n .form-inline .form-control { display: inline-block; width: auto; vertical-align: middle; }\n .form-inline .form-control-plaintext { display: inline-block; }\n .form-inline .custom-select, .form-inline .input-group { width: auto; }\n .form-inline .form-check { display: flex; align-items: center; justify-content: center; width: auto; padding-left: 0px; }\n .form-inline .form-check-input { position: relative; margin-top: 0px; margin-right: 0.25rem; margin-left: 0px; }\n .form-inline .custom-control { align-items: center; justify-content: center; }\n .form-inline .custom-control-label { margin-bottom: 0px; }\n}.btn { display: inline-block; font-weight: 400; text-align: center; white-space: nowrap; vertical-align: middle; user-select: none; border: 1px solid transparent; padding: 0.375rem 0.75rem; font-size: 1rem; line-height: 1.5; border-radius: 0.25rem; transition: color 0.15s ease-in-out 0s, background-color 0.15s ease-in-out 0s, border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; }@media not all {\n .btn { transition: none 0s ease 0s; }\n}.btn:focus, .btn:hover { text-decoration: none; }.btn.focus, .btn:focus { outline: 0px; box-shadow: rgba(0, 123, 255, 0.25) 0px 0px 0px 0.2rem; }.btn.disabled, .btn:disabled { opacity: 0.65; }.btn:not(:disabled):not(.disabled) { cursor: pointer; }a.btn.disabled, fieldset:disabled a.btn { pointer-events: none; }.btn-primary { color: rgb(255, 255, 255); background-color: rgb(0, 123, 255); border-color: rgb(0, 123, 255); }.btn-primary:hover { color: rgb(255, 255, 255); background-color: rgb(0, 105, 217); border-color: rgb(0, 98, 204); }.btn-primary.focus, .btn-primary:focus { box-shadow: rgba(0, 123, 255, 0.5) 0px 0px 0px 0.2rem; }.btn-primary.disabled, .btn-primary:disabled { color: rgb(255, 255, 255); background-color: rgb(0, 123, 255); border-color: rgb(0, 123, 255); }.btn-primary:not(:disabled):not(.disabled).active, .btn-primary:not(:disabled):not(.disabled):active, .show > .btn-primary.dropdown-toggle { color: rgb(255, 255, 255); background-color: rgb(0, 98, 204); border-color: rgb(0, 92, 191); }.btn-primary:not(:disabled):not(.disabled).active:focus, .btn-primary:not(:disabled):not(.disabled):active:focus, .show > .btn-primary.dropdown-toggle:focus { box-shadow: rgba(0, 123, 255, 0.5) 0px 0px 0px 0.2rem; }.btn-secondary { color: rgb(255, 255, 255); background-color: rgb(108, 117, 125); border-color: rgb(108, 117, 125); }.btn-secondary:hover { color: rgb(255, 255, 255); background-color: rgb(90, 98, 104); border-color: rgb(84, 91, 98); }.btn-secondary.focus, .btn-secondary:focus { box-shadow: rgba(108, 117, 125, 0.5) 0px 0px 0px 0.2rem; }.btn-secondary.disabled, .btn-secondary:disabled { color: rgb(255, 255, 255); background-color: rgb(108, 117, 125); border-color: rgb(108, 117, 125); }.btn-secondary:not(:disabled):not(.disabled).active, .btn-secondary:not(:disabled):not(.disabled):active, .show > .btn-secondary.dropdown-toggle { color: rgb(255, 255, 255); background-color: rgb(84, 91, 98); border-color: rgb(78, 85, 91); }.btn-secondary:not(:disabled):not(.disabled).active:focus, .btn-secondary:not(:disabled):not(.disabled):active:focus, .show > .btn-secondary.dropdown-toggle:focus { box-shadow: rgba(108, 117, 125, 0.5) 0px 0px 0px 0.2rem; }.btn-success { color: rgb(255, 255, 255); background-color: rgb(40, 167, 69); border-color: rgb(40, 167, 69); }.btn-success:hover { color: rgb(255, 255, 255); background-color: rgb(33, 136, 56); border-color: rgb(30, 126, 52); }.btn-success.focus, .btn-success:focus { box-shadow: rgba(40, 167, 69, 0.5) 0px 0px 0px 0.2rem; }.btn-success.disabled, .btn-success:disabled { color: rgb(255, 255, 255); background-color: rgb(40, 167, 69); border-color: rgb(40, 167, 69); }.btn-success:not(:disabled):not(.disabled).active, .btn-success:not(:disabled):not(.disabled):active, .show > .btn-success.dropdown-toggle { color: rgb(255, 255, 255); background-color: rgb(30, 126, 52); border-color: rgb(28, 116, 48); }.btn-success:not(:disabled):not(.disabled).active:focus, .btn-success:not(:disabled):not(.disabled):active:focus, .show > .btn-success.dropdown-toggle:focus { box-shadow: rgba(40, 167, 69, 0.5) 0px 0px 0px 0.2rem; }.btn-info { color: rgb(255, 255, 255); background-color: rgb(23, 162, 184); border-color: rgb(23, 162, 184); }.btn-info:hover { color: rgb(255, 255, 255); background-color: rgb(19, 132, 150); border-color: rgb(17, 122, 139); }.btn-info.focus, .btn-info:focus { box-shadow: rgba(23, 162, 184, 0.5) 0px 0px 0px 0.2rem; }.btn-info.disabled, .btn-info:disabled { color: rgb(255, 255, 255); background-color: rgb(23, 162, 184); border-color: rgb(23, 162, 184); }.btn-info:not(:disabled):not(.disabled).active, .btn-info:not(:disabled):not(.disabled):active, .show > .btn-info.dropdown-toggle { color: rgb(255, 255, 255); background-color: rgb(17, 122, 139); border-color: rgb(16, 112, 127); }.btn-info:not(:disabled):not(.disabled).active:focus, .btn-info:not(:disabled):not(.disabled):active:focus, .show > .btn-info.dropdown-toggle:focus { box-shadow: rgba(23, 162, 184, 0.5) 0px 0px 0px 0.2rem; }.btn-warning { color: rgb(33, 37, 41); background-color: rgb(255, 193, 7); border-color: rgb(255, 193, 7); }.btn-warning:hover { color: rgb(33, 37, 41); background-color: rgb(224, 168, 0); border-color: rgb(211, 158, 0); }.btn-warning.focus, .btn-warning:focus { box-shadow: rgba(255, 193, 7, 0.5) 0px 0px 0px 0.2rem; }.btn-warning.disabled, .btn-warning:disabled { color: rgb(33, 37, 41); background-color: rgb(255, 193, 7); border-color: rgb(255, 193, 7); }.btn-warning:not(:disabled):not(.disabled).active, .btn-warning:not(:disabled):not(.disabled):active, .show > .btn-warning.dropdown-toggle { color: rgb(33, 37, 41); background-color: rgb(211, 158, 0); border-color: rgb(198, 149, 0); }.btn-warning:not(:disabled):not(.disabled).active:focus, .btn-warning:not(:disabled):not(.disabled):active:focus, .show > .btn-warning.dropdown-toggle:focus { box-shadow: rgba(255, 193, 7, 0.5) 0px 0px 0px 0.2rem; }.btn-danger { color: rgb(255, 255, 255); background-color: rgb(220, 53, 69); border-color: rgb(220, 53, 69); }.btn-danger:hover { color: rgb(255, 255, 255); background-color: rgb(200, 35, 51); border-color: rgb(189, 33, 48); }.btn-danger.focus, .btn-danger:focus { box-shadow: rgba(220, 53, 69, 0.5) 0px 0px 0px 0.2rem; }.btn-danger.disabled, .btn-danger:disabled { color: rgb(255, 255, 255); background-color: rgb(220, 53, 69); border-color: rgb(220, 53, 69); }.btn-danger:not(:disabled):not(.disabled).active, .btn-danger:not(:disabled):not(.disabled):active, .show > .btn-danger.dropdown-toggle { color: rgb(255, 255, 255); background-color: rgb(189, 33, 48); border-color: rgb(178, 31, 45); }.btn-danger:not(:disabled):not(.disabled).active:focus, .btn-danger:not(:disabled):not(.disabled):active:focus, .show > .btn-danger.dropdown-toggle:focus { box-shadow: rgba(220, 53, 69, 0.5) 0px 0px 0px 0.2rem; }.btn-light { color: rgb(33, 37, 41); background-color: rgb(248, 249, 250); border-color: rgb(248, 249, 250); }.btn-light:hover { color: rgb(33, 37, 41); background-color: rgb(226, 230, 234); border-color: rgb(218, 224, 229); }.btn-light.focus, .btn-light:focus { box-shadow: rgba(248, 249, 250, 0.5) 0px 0px 0px 0.2rem; }.btn-light.disabled, .btn-light:disabled { color: rgb(33, 37, 41); background-color: rgb(248, 249, 250); border-color: rgb(248, 249, 250); }.btn-light:not(:disabled):not(.disabled).active, .btn-light:not(:disabled):not(.disabled):active, .show > .btn-light.dropdown-toggle { color: rgb(33, 37, 41); background-color: rgb(218, 224, 229); border-color: rgb(211, 217, 223); }.btn-light:not(:disabled):not(.disabled).active:focus, .btn-light:not(:disabled):not(.disabled):active:focus, .show > .btn-light.dropdown-toggle:focus { box-shadow: rgba(248, 249, 250, 0.5) 0px 0px 0px 0.2rem; }.btn-dark { color: rgb(255, 255, 255); background-color: rgb(52, 58, 64); border-color: rgb(52, 58, 64); }.btn-dark:hover { color: rgb(255, 255, 255); background-color: rgb(35, 39, 43); border-color: rgb(29, 33, 36); }.btn-dark.focus, .btn-dark:focus { box-shadow: rgba(52, 58, 64, 0.5) 0px 0px 0px 0.2rem; }.btn-dark.disabled, .btn-dark:disabled { color: rgb(255, 255, 255); background-color: rgb(52, 58, 64); border-color: rgb(52, 58, 64); }.btn-dark:not(:disabled):not(.disabled).active, .btn-dark:not(:disabled):not(.disabled):active, .show > .btn-dark.dropdown-toggle { color: rgb(255, 255, 255); background-color: rgb(29, 33, 36); border-color: rgb(23, 26, 29); }.btn-dark:not(:disabled):not(.disabled).active:focus, .btn-dark:not(:disabled):not(.disabled):active:focus, .show > .btn-dark.dropdown-toggle:focus { box-shadow: rgba(52, 58, 64, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-primary { color: rgb(0, 123, 255); background-color: transparent; background-image: none; border-color: rgb(0, 123, 255); }.btn-outline-primary:hover { color: rgb(255, 255, 255); background-color: rgb(0, 123, 255); border-color: rgb(0, 123, 255); }.btn-outline-primary.focus, .btn-outline-primary:focus { box-shadow: rgba(0, 123, 255, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-primary.disabled, .btn-outline-primary:disabled { color: rgb(0, 123, 255); background-color: transparent; }.btn-outline-primary:not(:disabled):not(.disabled).active, .btn-outline-primary:not(:disabled):not(.disabled):active, .show > .btn-outline-primary.dropdown-toggle { color: rgb(255, 255, 255); background-color: rgb(0, 123, 255); border-color: rgb(0, 123, 255); }.btn-outline-primary:not(:disabled):not(.disabled).active:focus, .btn-outline-primary:not(:disabled):not(.disabled):active:focus, .show > .btn-outline-primary.dropdown-toggle:focus { box-shadow: rgba(0, 123, 255, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-secondary { color: rgb(108, 117, 125); background-color: transparent; background-image: none; border-color: rgb(108, 117, 125); }.btn-outline-secondary:hover { color: rgb(255, 255, 255); background-color: rgb(108, 117, 125); border-color: rgb(108, 117, 125); }.btn-outline-secondary.focus, .btn-outline-secondary:focus { box-shadow: rgba(108, 117, 125, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-secondary.disabled, .btn-outline-secondary:disabled { color: rgb(108, 117, 125); background-color: transparent; }.btn-outline-secondary:not(:disabled):not(.disabled).active, .btn-outline-secondary:not(:disabled):not(.disabled):active, .show > .btn-outline-secondary.dropdown-toggle { color: rgb(255, 255, 255); background-color: rgb(108, 117, 125); border-color: rgb(108, 117, 125); }.btn-outline-secondary:not(:disabled):not(.disabled).active:focus, .btn-outline-secondary:not(:disabled):not(.disabled):active:focus, .show > .btn-outline-secondary.dropdown-toggle:focus { box-shadow: rgba(108, 117, 125, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-success { color: rgb(40, 167, 69); background-color: transparent; background-image: none; border-color: rgb(40, 167, 69); }.btn-outline-success:hover { color: rgb(255, 255, 255); background-color: rgb(40, 167, 69); border-color: rgb(40, 167, 69); }.btn-outline-success.focus, .btn-outline-success:focus { box-shadow: rgba(40, 167, 69, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-success.disabled, .btn-outline-success:disabled { color: rgb(40, 167, 69); background-color: transparent; }.btn-outline-success:not(:disabled):not(.disabled).active, .btn-outline-success:not(:disabled):not(.disabled):active, .show > .btn-outline-success.dropdown-toggle { color: rgb(255, 255, 255); background-color: rgb(40, 167, 69); border-color: rgb(40, 167, 69); }.btn-outline-success:not(:disabled):not(.disabled).active:focus, .btn-outline-success:not(:disabled):not(.disabled):active:focus, .show > .btn-outline-success.dropdown-toggle:focus { box-shadow: rgba(40, 167, 69, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-info { color: rgb(23, 162, 184); background-color: transparent; background-image: none; border-color: rgb(23, 162, 184); }.btn-outline-info:hover { color: rgb(255, 255, 255); background-color: rgb(23, 162, 184); border-color: rgb(23, 162, 184); }.btn-outline-info.focus, .btn-outline-info:focus { box-shadow: rgba(23, 162, 184, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-info.disabled, .btn-outline-info:disabled { color: rgb(23, 162, 184); background-color: transparent; }.btn-outline-info:not(:disabled):not(.disabled).active, .btn-outline-info:not(:disabled):not(.disabled):active, .show > .btn-outline-info.dropdown-toggle { color: rgb(255, 255, 255); background-color: rgb(23, 162, 184); border-color: rgb(23, 162, 184); }.btn-outline-info:not(:disabled):not(.disabled).active:focus, .btn-outline-info:not(:disabled):not(.disabled):active:focus, .show > .btn-outline-info.dropdown-toggle:focus { box-shadow: rgba(23, 162, 184, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-warning { color: rgb(255, 193, 7); background-color: transparent; background-image: none; border-color: rgb(255, 193, 7); }.btn-outline-warning:hover { color: rgb(33, 37, 41); background-color: rgb(255, 193, 7); border-color: rgb(255, 193, 7); }.btn-outline-warning.focus, .btn-outline-warning:focus { box-shadow: rgba(255, 193, 7, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-warning.disabled, .btn-outline-warning:disabled { color: rgb(255, 193, 7); background-color: transparent; }.btn-outline-warning:not(:disabled):not(.disabled).active, .btn-outline-warning:not(:disabled):not(.disabled):active, .show > .btn-outline-warning.dropdown-toggle { color: rgb(33, 37, 41); background-color: rgb(255, 193, 7); border-color: rgb(255, 193, 7); }.btn-outline-warning:not(:disabled):not(.disabled).active:focus, .btn-outline-warning:not(:disabled):not(.disabled):active:focus, .show > .btn-outline-warning.dropdown-toggle:focus { box-shadow: rgba(255, 193, 7, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-danger { color: rgb(220, 53, 69); background-color: transparent; background-image: none; border-color: rgb(220, 53, 69); }.btn-outline-danger:hover { color: rgb(255, 255, 255); background-color: rgb(220, 53, 69); border-color: rgb(220, 53, 69); }.btn-outline-danger.focus, .btn-outline-danger:focus { box-shadow: rgba(220, 53, 69, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-danger.disabled, .btn-outline-danger:disabled { color: rgb(220, 53, 69); background-color: transparent; }.btn-outline-danger:not(:disabled):not(.disabled).active, .btn-outline-danger:not(:disabled):not(.disabled):active, .show > .btn-outline-danger.dropdown-toggle { color: rgb(255, 255, 255); background-color: rgb(220, 53, 69); border-color: rgb(220, 53, 69); }.btn-outline-danger:not(:disabled):not(.disabled).active:focus, .btn-outline-danger:not(:disabled):not(.disabled):active:focus, .show > .btn-outline-danger.dropdown-toggle:focus { box-shadow: rgba(220, 53, 69, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-light { color: rgb(248, 249, 250); background-color: transparent; background-image: none; border-color: rgb(248, 249, 250); }.btn-outline-light:hover { color: rgb(33, 37, 41); background-color: rgb(248, 249, 250); border-color: rgb(248, 249, 250); }.btn-outline-light.focus, .btn-outline-light:focus { box-shadow: rgba(248, 249, 250, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-light.disabled, .btn-outline-light:disabled { color: rgb(248, 249, 250); background-color: transparent; }.btn-outline-light:not(:disabled):not(.disabled).active, .btn-outline-light:not(:disabled):not(.disabled):active, .show > .btn-outline-light.dropdown-toggle { color: rgb(33, 37, 41); background-color: rgb(248, 249, 250); border-color: rgb(248, 249, 250); }.btn-outline-light:not(:disabled):not(.disabled).active:focus, .btn-outline-light:not(:disabled):not(.disabled):active:focus, .show > .btn-outline-light.dropdown-toggle:focus { box-shadow: rgba(248, 249, 250, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-dark { color: rgb(52, 58, 64); background-color: transparent; background-image: none; border-color: rgb(52, 58, 64); }.btn-outline-dark:hover { color: rgb(255, 255, 255); background-color: rgb(52, 58, 64); border-color: rgb(52, 58, 64); }.btn-outline-dark.focus, .btn-outline-dark:focus { box-shadow: rgba(52, 58, 64, 0.5) 0px 0px 0px 0.2rem; }.btn-outline-dark.disabled, .btn-outline-dark:disabled { color: rgb(52, 58, 64); background-color: transparent; }.btn-outline-dark:not(:disabled):not(.disabled).active, .btn-outline-dark:not(:disabled):not(.disabled):active, .show > .btn-outline-dark.dropdown-toggle { color: rgb(255, 255, 255); background-color: rgb(52, 58, 64); border-color: rgb(52, 58, 64); }.btn-outline-dark:not(:disabled):not(.disabled).active:focus, .btn-outline-dark:not(:disabled):not(.disabled):active:focus, .show > .btn-outline-dark.dropdown-toggle:focus { box-shadow: rgba(52, 58, 64, 0.5) 0px 0px 0px 0.2rem; }.btn-link { font-weight: 400; color: rgb(0, 123, 255); background-color: transparent; }.btn-link:hover { color: rgb(0, 86, 179); text-decoration: underline; background-color: transparent; border-color: transparent; }.btn-link.focus, .btn-link:focus { text-decoration: underline; border-color: transparent; box-shadow: none; }.btn-link.disabled, .btn-link:disabled { color: rgb(108, 117, 125); pointer-events: none; }.btn-group-lg > .btn, .btn-lg { padding: 0.5rem 1rem; font-size: 1.25rem; line-height: 1.5; border-radius: 0.3rem; }.btn-group-sm > .btn, .btn-sm { padding: 0.25rem 0.5rem; font-size: 0.875rem; line-height: 1.5; border-radius: 0.2rem; }.btn-block { display: block; width: 100%; }.btn-block + .btn-block { margin-top: 0.5rem; }input[type=\"button\"].btn-block, input[type=\"reset\"].btn-block, input[type=\"submit\"].btn-block { width: 100%; }.fade { transition: opacity 0.15s linear 0s; }@media not all {\n .fade { transition: none 0s ease 0s; }\n}.fade:not(.show) { opacity: 0; }.collapse:not(.show) { display: none; }.collapsing { position: relative; height: 0px; overflow: hidden; transition: height 0.35s ease 0s; }@media not all {\n .collapsing { transition: none 0s ease 0s; }\n}.dropdown, .dropleft, .dropright, .dropup { position: relative; }.dropdown-toggle::after { display: inline-block; width: 0px; height: 0px; margin-left: 0.255em; vertical-align: 0.255em; content: \"\"; border-width: 0.3em 0.3em 0px; border-top-style: solid; border-top-color: initial; border-right-style: solid; border-right-color: transparent; border-bottom-style: initial; border-bottom-color: initial; border-left-style: solid; border-left-color: transparent; }.dropdown-toggle:empty::after { margin-left: 0px; }.dropdown-menu { position: absolute; top: 100%; left: 0px; z-index: 1000; display: none; float: left; min-width: 10rem; padding: 0.5rem 0px; margin: 0.125rem 0px 0px; font-size: 1rem; color: rgb(33, 37, 41); text-align: left; list-style: none; background-color: rgb(255, 255, 255); background-clip: padding-box; border: 1px solid rgba(0, 0, 0, 0.15); border-radius: 0.25rem; }.dropdown-menu-right { right: 0px; left: auto; }.dropup .dropdown-menu { top: auto; bottom: 100%; margin-top: 0px; margin-bottom: 0.125rem; }.dropup .dropdown-toggle::after { display: inline-block; width: 0px; height: 0px; margin-left: 0.255em; vertical-align: 0.255em; content: \"\"; border-width: 0px 0.3em 0.3em; border-top-style: initial; border-top-color: initial; border-right-style: solid; border-right-color: transparent; border-bottom-style: solid; border-bottom-color: initial; border-left-style: solid; border-left-color: transparent; }.dropup .dropdown-toggle:empty::after { margin-left: 0px; }.dropright .dropdown-menu { top: 0px; right: auto; left: 100%; margin-top: 0px; margin-left: 0.125rem; }.dropright .dropdown-toggle::after { display: inline-block; width: 0px; height: 0px; margin-left: 0.255em; vertical-align: 0.255em; content: \"\"; border-width: 0.3em 0px 0.3em 0.3em; border-top-style: solid; border-top-color: transparent; border-right-style: initial; border-right-color: initial; border-bottom-style: solid; border-bottom-color: transparent; border-left-style: solid; border-left-color: initial; }.dropright .dropdown-toggle:empty::after { margin-left: 0px; }.dropright .dropdown-toggle::after { vertical-align: 0px; }.dropleft .dropdown-menu { top: 0px; right: 100%; left: auto; margin-top: 0px; margin-right: 0.125rem; }.dropleft .dropdown-toggle::after { display: inline-block; width: 0px; height: 0px; margin-left: 0.255em; vertical-align: 0.255em; content: \"\"; }.dropleft .dropdown-toggle::after { display: none; }.dropleft .dropdown-toggle::before { display: inline-block; width: 0px; height: 0px; margin-right: 0.255em; vertical-align: 0.255em; content: \"\"; border-top: 0.3em solid transparent; border-right: 0.3em solid; border-bottom: 0.3em solid transparent; }.dropleft .dropdown-toggle:empty::after { margin-left: 0px; }.dropleft .dropdown-toggle::before { vertical-align: 0px; }.dropdown-menu[x-placement^=\"bottom\"], .dropdown-menu[x-placement^=\"left\"], .dropdown-menu[x-placement^=\"right\"], .dropdown-menu[x-placement^=\"top\"] { right: auto; bottom: auto; }.dropdown-divider { height: 0px; margin: 0.5rem 0px; overflow: hidden; border-top: 1px solid rgb(233, 236, 239); }.dropdown-item { display: block; width: 100%; padding: 0.25rem 1.5rem; clear: both; font-weight: 400; color: rgb(33, 37, 41); text-align: inherit; white-space: nowrap; background-color: transparent; border: 0px; }.dropdown-item:focus, .dropdown-item:hover { color: rgb(22, 24, 27); text-decoration: none; background-color: rgb(248, 249, 250); }.dropdown-item.active, .dropdown-item:active { color: rgb(255, 255, 255); text-decoration: none; background-color: rgb(0, 123, 255); }.dropdown-item.disabled, .dropdown-item:disabled { color: rgb(108, 117, 125); background-color: transparent; }.dropdown-menu.show { display: block; }.dropdown-header { display: block; padding: 0.5rem 1.5rem; margin-bottom: 0px; font-size: 0.875rem; color: rgb(108, 117, 125); white-space: nowrap; }.dropdown-item-text { display: block; padding: 0.25rem 1.5rem; color: rgb(33, 37, 41); }.btn-group, .btn-group-vertical { position: relative; display: inline-flex; vertical-align: middle; }.btn-group-vertical > .btn, .btn-group > .btn { position: relative; flex: 0 1 auto; }.btn-group-vertical > .btn:hover, .btn-group > .btn:hover { z-index: 1; }.btn-group-vertical > .btn.active, .btn-group-vertical > .btn:active, .btn-group-vertical > .btn:focus, .btn-group > .btn.active, .btn-group > .btn:active, .btn-group > .btn:focus { z-index: 1; }.btn-group .btn + .btn, .btn-group .btn + .btn-group, .btn-group .btn-group + .btn, .btn-group .btn-group + .btn-group, .btn-group-vertical .btn + .btn, .btn-group-vertical .btn + .btn-group, .btn-group-vertical .btn-group + .btn, .btn-group-vertical .btn-group + .btn-group { margin-left: -1px; }.btn-toolbar { display: flex; flex-wrap: wrap; justify-content: flex-start; }.btn-toolbar .input-group { width: auto; }.btn-group > .btn:first-child { margin-left: 0px; }.btn-group > .btn-group:not(:last-child) > .btn, .btn-group > .btn:not(:last-child):not(.dropdown-toggle) { border-top-right-radius: 0px; border-bottom-right-radius: 0px; }.btn-group > .btn-group:not(:first-child) > .btn, .btn-group > .btn:not(:first-child) { border-top-left-radius: 0px; border-bottom-left-radius: 0px; }.dropdown-toggle-split { padding-right: 0.5625rem; padding-left: 0.5625rem; }.dropdown-toggle-split::after, .dropright .dropdown-toggle-split::after, .dropup .dropdown-toggle-split::after { margin-left: 0px; }.dropleft .dropdown-toggle-split::before { margin-right: 0px; }.btn-group-sm > .btn + .dropdown-toggle-split, .btn-sm + .dropdown-toggle-split { padding-right: 0.375rem; padding-left: 0.375rem; }.btn-group-lg > .btn + .dropdown-toggle-split, .btn-lg + .dropdown-toggle-split { padding-right: 0.75rem; padding-left: 0.75rem; }.btn-group-vertical { flex-direction: column; align-items: flex-start; justify-content: center; }.btn-group-vertical .btn, .btn-group-vertical .btn-group { width: 100%; }.btn-group-vertical > .btn + .btn, .btn-group-vertical > .btn + .btn-group, .btn-group-vertical > .btn-group + .btn, .btn-group-vertical > .btn-group + .btn-group { margin-top: -1px; margin-left: 0px; }.btn-group-vertical > .btn-group:not(:last-child) > .btn, .btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle) { border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; }.btn-group-vertical > .btn-group:not(:first-child) > .btn, .btn-group-vertical > .btn:not(:first-child) { border-top-left-radius: 0px; border-top-right-radius: 0px; }.btn-group-toggle > .btn, .btn-group-toggle > .btn-group > .btn { margin-bottom: 0px; }.btn-group-toggle > .btn input[type=\"checkbox\"], .btn-group-toggle > .btn input[type=\"radio\"], .btn-group-toggle > .btn-group > .btn input[type=\"checkbox\"], .btn-group-toggle > .btn-group > .btn input[type=\"radio\"] { position: absolute; clip: rect(0px, 0px, 0px, 0px); pointer-events: none; }.input-group { position: relative; display: flex; flex-wrap: wrap; align-items: stretch; width: 100%; }.input-group > .custom-file, .input-group > .custom-select, .input-group > .form-control { position: relative; flex: 1 1 auto; width: 1%; margin-bottom: 0px; }.input-group > .custom-file + .custom-file, .input-group > .custom-file + .custom-select, .input-group > .custom-file + .form-control, .input-group > .custom-select + .custom-file, .input-group > .custom-select + .custom-select, .input-group > .custom-select + .form-control, .input-group > .form-control + .custom-file, .input-group > .form-control + .custom-select, .input-group > .form-control + .form-control { margin-left: -1px; }.input-group > .custom-file .custom-file-input:focus ~ .custom-file-label, .input-group > .custom-select:focus, .input-group > .form-control:focus { z-index: 3; }.input-group > .custom-file .custom-file-input:focus { z-index: 4; }.input-group > .custom-select:not(:last-child), .input-group > .form-control:not(:last-child) { border-top-right-radius: 0px; border-bottom-right-radius: 0px; }.input-group > .custom-select:not(:first-child), .input-group > .form-control:not(:first-child) { border-top-left-radius: 0px; border-bottom-left-radius: 0px; }.input-group > .custom-file { display: flex; align-items: center; }.input-group > .custom-file:not(:last-child) .custom-file-label, .input-group > .custom-file:not(:last-child) .custom-file-label::after { border-top-right-radius: 0px; border-bottom-right-radius: 0px; }.input-group > .custom-file:not(:first-child) .custom-file-label { border-top-left-radius: 0px; border-bottom-left-radius: 0px; }.input-group-append, .input-group-prepend { display: flex; }.input-group-append .btn, .input-group-prepend .btn { position: relative; z-index: 2; }.input-group-append .btn + .btn, .input-group-append .btn + .input-group-text, .input-group-append .input-group-text + .btn, .input-group-append .input-group-text + .input-group-text, .input-group-prepend .btn + .btn, .input-group-prepend .btn + .input-group-text, .input-group-prepend .input-group-text + .btn, .input-group-prepend .input-group-text + .input-group-text { margin-left: -1px; }.input-group-prepend { margin-right: -1px; }.input-group-append { margin-left: -1px; }.input-group-text { display: flex; align-items: center; padding: 0.375rem 0.75rem; margin-bottom: 0px; font-size: 1rem; font-weight: 400; line-height: 1.5; color: rgb(73, 80, 87); text-align: center; white-space: nowrap; background-color: rgb(233, 236, 239); border: 1px solid rgb(206, 212, 218); border-radius: 0.25rem; }.input-group-text input[type=\"checkbox\"], .input-group-text input[type=\"radio\"] { margin-top: 0px; }.input-group-lg > .form-control, .input-group-lg > .input-group-append > .btn, .input-group-lg > .input-group-append > .input-group-text, .input-group-lg > .input-group-prepend > .btn, .input-group-lg > .input-group-prepend > .input-group-text { height: calc(2.875rem + 2px); padding: 0.5rem 1rem; font-size: 1.25rem; line-height: 1.5; border-radius: 0.3rem; }.input-group-sm > .form-control, .input-group-sm > .input-group-append > .btn, .input-group-sm > .input-group-append > .input-group-text, .input-group-sm > .input-group-prepend > .btn, .input-group-sm > .input-group-prepend > .input-group-text { height: calc(1.8125rem + 2px); padding: 0.25rem 0.5rem; font-size: 0.875rem; line-height: 1.5; border-radius: 0.2rem; }.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle), .input-group > .input-group-append:last-child > .input-group-text:not(:last-child), .input-group > .input-group-append:not(:last-child) > .btn, .input-group > .input-group-append:not(:last-child) > .input-group-text, .input-group > .input-group-prepend > .btn, .input-group > .input-group-prepend > .input-group-text { border-top-right-radius: 0px; border-bottom-right-radius: 0px; }.input-group > .input-group-append > .btn, .input-group > .input-group-append > .input-group-text, .input-group > .input-group-prepend:first-child > .btn:not(:first-child), .input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child), .input-group > .input-group-prepend:not(:first-child) > .btn, .input-group > .input-group-prepend:not(:first-child) > .input-group-text { border-top-left-radius: 0px; border-bottom-left-radius: 0px; }.custom-control { position: relative; display: block; min-height: 1.5rem; padding-left: 1.5rem; }.custom-control-inline { display: inline-flex; margin-right: 1rem; }.custom-control-input { position: absolute; z-index: -1; opacity: 0; }.custom-control-input:checked ~ .custom-control-label::before { color: rgb(255, 255, 255); background-color: rgb(0, 123, 255); }.custom-control-input:focus ~ .custom-control-label::before { box-shadow: rgb(255, 255, 255) 0px 0px 0px 1px, rgba(0, 123, 255, 0.25) 0px 0px 0px 0.2rem; }.custom-control-input:active ~ .custom-control-label::before { color: rgb(255, 255, 255); background-color: rgb(179, 215, 255); }.custom-control-input:disabled ~ .custom-control-label { color: rgb(108, 117, 125); }.custom-control-input:disabled ~ .custom-control-label::before { background-color: rgb(233, 236, 239); }.custom-control-label { position: relative; margin-bottom: 0px; }.custom-control-label::before { position: absolute; top: 0.25rem; left: -1.5rem; display: block; width: 1rem; height: 1rem; pointer-events: none; content: \"\"; user-select: none; background-color: rgb(222, 226, 230); }.custom-control-label::after { position: absolute; top: 0.25rem; left: -1.5rem; display: block; width: 1rem; height: 1rem; content: \"\"; background-repeat: no-repeat; background-position: center center; background-size: 50% 50%; }.custom-checkbox .custom-control-label::before { border-radius: 0.25rem; }.custom-checkbox .custom-control-input:checked ~ .custom-control-label::before { background-color: rgb(0, 123, 255); }.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after { background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E\"); }.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::before { background-color: rgb(0, 123, 255); }.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::after { background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E\"); }.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::before { background-color: rgba(0, 123, 255, 0.5); }.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::before { background-color: rgba(0, 123, 255, 0.5); }.custom-radio .custom-control-label::before { border-radius: 50%; }.custom-radio .custom-control-input:checked ~ .custom-control-label::before { background-color: rgb(0, 123, 255); }.custom-radio .custom-control-input:checked ~ .custom-control-label::after { background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E\"); }.custom-radio .custom-control-input:disabled:checked ~ .custom-control-label::before { background-color: rgba(0, 123, 255, 0.5); }.custom-select { display: inline-block; width: 100%; height: calc(2.25rem + 2px); padding: 0.375rem 1.75rem 0.375rem 0.75rem; line-height: 1.5; color: rgb(73, 80, 87); vertical-align: middle; background: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E\") right 0.75rem center / 8px 10px no-repeat rgb(255, 255, 255); border: 1px solid rgb(206, 212, 218); border-radius: 0.25rem; -webkit-appearance: none; }.custom-select:focus { border-color: rgb(128, 189, 255); outline: 0px; box-shadow: rgba(128, 189, 255, 0.5) 0px 0px 0px 0.2rem; }.custom-select[multiple], .custom-select[size]:not([size=\"1\"]) { height: auto; padding-right: 0.75rem; background-image: none; }.custom-select:disabled { color: rgb(108, 117, 125); background-color: rgb(233, 236, 239); }.custom-select-sm { height: calc(1.8125rem + 2px); padding-top: 0.375rem; padding-bottom: 0.375rem; font-size: 75%; }.custom-select-lg { height: calc(2.875rem + 2px); padding-top: 0.375rem; padding-bottom: 0.375rem; font-size: 125%; }.custom-file { position: relative; display: inline-block; width: 100%; height: calc(2.25rem + 2px); margin-bottom: 0px; }.custom-file-input { position: relative; z-index: 2; width: 100%; height: calc(2.25rem + 2px); margin: 0px; opacity: 0; }.custom-file-input:focus ~ .custom-file-label { border-color: rgb(128, 189, 255); box-shadow: rgba(0, 123, 255, 0.25) 0px 0px 0px 0.2rem; }.custom-file-input:focus ~ .custom-file-label::after { border-color: rgb(128, 189, 255); }.custom-file-input:disabled ~ .custom-file-label { background-color: rgb(233, 236, 239); }.custom-file-input:lang(en) ~ .custom-file-label::after { content: \"Browse\"; }.custom-file-label { position: absolute; top: 0px; right: 0px; left: 0px; z-index: 1; height: calc(2.25rem + 2px); padding: 0.375rem 0.75rem; line-height: 1.5; color: rgb(73, 80, 87); background-color: rgb(255, 255, 255); border: 1px solid rgb(206, 212, 218); border-radius: 0.25rem; }.custom-file-label::after { position: absolute; top: 0px; right: 0px; bottom: 0px; z-index: 3; display: block; height: 2.25rem; padding: 0.375rem 0.75rem; line-height: 1.5; color: rgb(73, 80, 87); content: \"Browse\"; background-color: rgb(233, 236, 239); border-left: 1px solid rgb(206, 212, 218); border-radius: 0px 0.25rem 0.25rem 0px; }.custom-range { width: 100%; padding-left: 0px; background-color: transparent; -webkit-appearance: none; }.custom-range:focus { outline: 0px; }.custom-range:focus::-webkit-slider-thumb { box-shadow: rgb(255, 255, 255) 0px 0px 0px 1px, rgba(0, 123, 255, 0.25) 0px 0px 0px 0.2rem; }.custom-range::-webkit-slider-thumb { width: 1rem; height: 1rem; margin-top: -0.25rem; background-color: rgb(0, 123, 255); border: 0px; border-radius: 1rem; transition: background-color 0.15s ease-in-out 0s, border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; -webkit-appearance: none; }@media not all {\n .custom-range::-webkit-slider-thumb { transition: none 0s ease 0s; }\n}.custom-range::-webkit-slider-thumb:active { background-color: rgb(179, 215, 255); }.custom-range::-webkit-slider-runnable-track { width: 100%; height: 0.5rem; color: transparent; cursor: pointer; background-color: rgb(222, 226, 230); border-color: transparent; border-radius: 1rem; }@media not all {\n}@media not all {\n}.custom-control-label::before, .custom-file-label, .custom-select { transition: background-color 0.15s ease-in-out 0s, border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; }@media not all {\n .custom-control-label::before, .custom-file-label, .custom-select { transition: none 0s ease 0s; }\n}.nav { display: flex; flex-wrap: wrap; padding-left: 0px; margin-bottom: 0px; list-style: none; }.nav-link { display: block; padding: 0.5rem 1rem; }.nav-link:focus, .nav-link:hover { text-decoration: none; }.nav-link.disabled { color: rgb(108, 117, 125); }.nav-tabs { border-bottom: 1px solid rgb(222, 226, 230); }.nav-tabs .nav-item { margin-bottom: -1px; }.nav-tabs .nav-link { border: 1px solid transparent; border-top-left-radius: 0.25rem; border-top-right-radius: 0.25rem; }.nav-tabs .nav-link:focus, .nav-tabs .nav-link:hover { border-color: rgb(233, 236, 239) rgb(233, 236, 239) rgb(222, 226, 230); }.nav-tabs .nav-link.disabled { color: rgb(108, 117, 125); background-color: transparent; border-color: transparent; }.nav-tabs .nav-item.show .nav-link, .nav-tabs .nav-link.active { color: rgb(73, 80, 87); background-color: rgb(255, 255, 255); border-color: rgb(222, 226, 230) rgb(222, 226, 230) rgb(255, 255, 255); }.nav-tabs .dropdown-menu { margin-top: -1px; border-top-left-radius: 0px; border-top-right-radius: 0px; }.nav-pills .nav-link { border-radius: 0.25rem; }.nav-pills .nav-link.active, .nav-pills .show > .nav-link { color: rgb(255, 255, 255); background-color: rgb(0, 123, 255); }.nav-fill .nav-item { flex: 1 1 auto; text-align: center; }.nav-justified .nav-item { flex-basis: 0px; flex-grow: 1; text-align: center; }.tab-content > .tab-pane { display: none; }.tab-content > .active { display: block; }.navbar { position: relative; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; padding: 0.5rem 1rem; }.navbar > .container, .navbar > .container-fluid { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; }.navbar-brand { display: inline-block; padding-top: 0.3125rem; padding-bottom: 0.3125rem; margin-right: 1rem; font-size: 1.25rem; line-height: inherit; white-space: nowrap; }.navbar-brand:focus, .navbar-brand:hover { text-decoration: none; }.navbar-nav { display: flex; flex-direction: column; padding-left: 0px; margin-bottom: 0px; list-style: none; }.navbar-nav .nav-link { padding-right: 0px; padding-left: 0px; }.navbar-nav .dropdown-menu { position: static; float: none; }.navbar-text { display: inline-block; padding-top: 0.5rem; padding-bottom: 0.5rem; }.navbar-collapse { flex-basis: 100%; flex-grow: 1; align-items: center; }.navbar-toggler { padding: 0.25rem 0.75rem; font-size: 1.25rem; line-height: 1; background-color: transparent; border: 1px solid transparent; border-radius: 0.25rem; }.navbar-toggler:focus, .navbar-toggler:hover { text-decoration: none; }.navbar-toggler:not(:disabled):not(.disabled) { cursor: pointer; }.navbar-toggler-icon { display: inline-block; width: 1.5em; height: 1.5em; vertical-align: middle; content: \"\"; background: center center / 100% 100% no-repeat; }@media (max-width: 575.98px) {\n .navbar-expand-sm > .container, .navbar-expand-sm > .container-fluid { padding-right: 0px; padding-left: 0px; }\n}@media (min-width: 576px) {\n .navbar-expand-sm { flex-flow: row nowrap; justify-content: flex-start; }\n .navbar-expand-sm .navbar-nav { flex-direction: row; }\n .navbar-expand-sm .navbar-nav .dropdown-menu { position: absolute; }\n .navbar-expand-sm .navbar-nav .nav-link { padding-right: 0.5rem; padding-left: 0.5rem; }\n .navbar-expand-sm > .container, .navbar-expand-sm > .container-fluid { flex-wrap: nowrap; }\n .navbar-expand-sm .navbar-collapse { flex-basis: auto; display: flex !important; }\n .navbar-expand-sm .navbar-toggler { display: none; }\n}@media (max-width: 767.98px) {\n .navbar-expand-md > .container, .navbar-expand-md > .container-fluid { padding-right: 0px; padding-left: 0px; }\n}@media (min-width: 768px) {\n .navbar-expand-md { flex-flow: row nowrap; justify-content: flex-start; }\n .navbar-expand-md .navbar-nav { flex-direction: row; }\n .navbar-expand-md .navbar-nav .dropdown-menu { position: absolute; }\n .navbar-expand-md .navbar-nav .nav-link { padding-right: 0.5rem; padding-left: 0.5rem; }\n .navbar-expand-md > .container, .navbar-expand-md > .container-fluid { flex-wrap: nowrap; }\n .navbar-expand-md .navbar-collapse { flex-basis: auto; display: flex !important; }\n .navbar-expand-md .navbar-toggler { display: none; }\n}@media (max-width: 991.98px) {\n .navbar-expand-lg > .container, .navbar-expand-lg > .container-fluid { padding-right: 0px; padding-left: 0px; }\n}@media (min-width: 992px) {\n .navbar-expand-lg { flex-flow: row nowrap; justify-content: flex-start; }\n .navbar-expand-lg .navbar-nav { flex-direction: row; }\n .navbar-expand-lg .navbar-nav .dropdown-menu { position: absolute; }\n .navbar-expand-lg .navbar-nav .nav-link { padding-right: 0.5rem; padding-left: 0.5rem; }\n .navbar-expand-lg > .container, .navbar-expand-lg > .container-fluid { flex-wrap: nowrap; }\n .navbar-expand-lg .navbar-collapse { flex-basis: auto; display: flex !important; }\n .navbar-expand-lg .navbar-toggler { display: none; }\n}@media (max-width: 1199.98px) {\n .navbar-expand-xl > .container, .navbar-expand-xl > .container-fluid { padding-right: 0px; padding-left: 0px; }\n}@media (min-width: 1200px) {\n .navbar-expand-xl { flex-flow: row nowrap; justify-content: flex-start; }\n .navbar-expand-xl .navbar-nav { flex-direction: row; }\n .navbar-expand-xl .navbar-nav .dropdown-menu { position: absolute; }\n .navbar-expand-xl .navbar-nav .nav-link { padding-right: 0.5rem; padding-left: 0.5rem; }\n .navbar-expand-xl > .container, .navbar-expand-xl > .container-fluid { flex-wrap: nowrap; }\n .navbar-expand-xl .navbar-collapse { flex-basis: auto; display: flex !important; }\n .navbar-expand-xl .navbar-toggler { display: none; }\n}.navbar-expand { flex-flow: row nowrap; justify-content: flex-start; }.navbar-expand > .container, .navbar-expand > .container-fluid { padding-right: 0px; padding-left: 0px; }.navbar-expand .navbar-nav { flex-direction: row; }.navbar-expand .navbar-nav .dropdown-menu { position: absolute; }.navbar-expand .navbar-nav .nav-link { padding-right: 0.5rem; padding-left: 0.5rem; }.navbar-expand > .container, .navbar-expand > .container-fluid { flex-wrap: nowrap; }.navbar-expand .navbar-collapse { flex-basis: auto; display: flex !important; }.navbar-expand .navbar-toggler { display: none; }.navbar-light .navbar-brand { color: rgba(0, 0, 0, 0.9); }.navbar-light .navbar-brand:focus, .navbar-light .navbar-brand:hover { color: rgba(0, 0, 0, 0.9); }.navbar-light .navbar-nav .nav-link { color: rgba(0, 0, 0, 0.5); }.navbar-light .navbar-nav .nav-link:focus, .navbar-light .navbar-nav .nav-link:hover { color: rgba(0, 0, 0, 0.7); }.navbar-light .navbar-nav .nav-link.disabled { color: rgba(0, 0, 0, 0.3); }.navbar-light .navbar-nav .active > .nav-link, .navbar-light .navbar-nav .nav-link.active, .navbar-light .navbar-nav .nav-link.show, .navbar-light .navbar-nav .show > .nav-link { color: rgba(0, 0, 0, 0.9); }.navbar-light .navbar-toggler { color: rgba(0, 0, 0, 0.5); border-color: rgba(0, 0, 0, 0.1); }.navbar-light .navbar-toggler-icon { background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E\"); }.navbar-light .navbar-text { color: rgba(0, 0, 0, 0.5); }.navbar-light .navbar-text a { color: rgba(0, 0, 0, 0.9); }.navbar-light .navbar-text a:focus, .navbar-light .navbar-text a:hover { color: rgba(0, 0, 0, 0.9); }.navbar-dark .navbar-brand { color: rgb(255, 255, 255); }.navbar-dark .navbar-brand:focus, .navbar-dark .navbar-brand:hover { color: rgb(255, 255, 255); }.navbar-dark .navbar-nav .nav-link { color: rgba(255, 255, 255, 0.5); }.navbar-dark .navbar-nav .nav-link:focus, .navbar-dark .navbar-nav .nav-link:hover { color: rgba(255, 255, 255, 0.75); }.navbar-dark .navbar-nav .nav-link.disabled { color: rgba(255, 255, 255, 0.25); }.navbar-dark .navbar-nav .active > .nav-link, .navbar-dark .navbar-nav .nav-link.active, .navbar-dark .navbar-nav .nav-link.show, .navbar-dark .navbar-nav .show > .nav-link { color: rgb(255, 255, 255); }.navbar-dark .navbar-toggler { color: rgba(255, 255, 255, 0.5); border-color: rgba(255, 255, 255, 0.1); }.navbar-dark .navbar-toggler-icon { background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E\"); }.navbar-dark .navbar-text { color: rgba(255, 255, 255, 0.5); }.navbar-dark .navbar-text a { color: rgb(255, 255, 255); }.navbar-dark .navbar-text a:focus, .navbar-dark .navbar-text a:hover { color: rgb(255, 255, 255); }.card { position: relative; display: flex; flex-direction: column; min-width: 0px; word-wrap: break-word; background-color: rgb(255, 255, 255); background-clip: border-box; border: 1px solid rgba(0, 0, 0, 0.125); border-radius: 0.25rem; }.card > hr { margin-right: 0px; margin-left: 0px; }.card > .list-group:first-child .list-group-item:first-child { border-top-left-radius: 0.25rem; border-top-right-radius: 0.25rem; }.card > .list-group:last-child .list-group-item:last-child { border-bottom-right-radius: 0.25rem; border-bottom-left-radius: 0.25rem; }.card-body { flex: 1 1 auto; padding: 1.25rem; }.card-title { margin-bottom: 0.75rem; }.card-subtitle { margin-top: -0.375rem; margin-bottom: 0px; }.card-text:last-child { margin-bottom: 0px; }.card-link:hover { text-decoration: none; }.card-link + .card-link { margin-left: 1.25rem; }.card-header { padding: 0.75rem 1.25rem; margin-bottom: 0px; background-color: rgba(0, 0, 0, 0.03); border-bottom: 1px solid rgba(0, 0, 0, 0.125); }.card-header:first-child { border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0px 0px; }.card-header + .list-group .list-group-item:first-child { border-top: 0px; }.card-footer { padding: 0.75rem 1.25rem; background-color: rgba(0, 0, 0, 0.03); border-top: 1px solid rgba(0, 0, 0, 0.125); }.card-footer:last-child { border-radius: 0px 0px calc(0.25rem - 1px) calc(0.25rem - 1px); }.card-header-tabs { margin-right: -0.625rem; margin-bottom: -0.75rem; margin-left: -0.625rem; border-bottom: 0px; }.card-header-pills { margin-right: -0.625rem; margin-left: -0.625rem; }.card-img-overlay { position: absolute; top: 0px; right: 0px; bottom: 0px; left: 0px; padding: 1.25rem; }.card-img { width: 100%; border-radius: calc(0.25rem - 1px); }.card-img-top { width: 100%; border-top-left-radius: calc(0.25rem - 1px); border-top-right-radius: calc(0.25rem - 1px); }.card-img-bottom { width: 100%; border-bottom-right-radius: calc(0.25rem - 1px); border-bottom-left-radius: calc(0.25rem - 1px); }.card-deck { display: flex; flex-direction: column; }.card-deck .card { margin-bottom: 15px; }@media (min-width: 576px) {\n .card-deck { flex-flow: row wrap; margin-right: -15px; margin-left: -15px; }\n .card-deck .card { display: flex; flex: 1 0 0%; flex-direction: column; margin-right: 15px; margin-bottom: 0px; margin-left: 15px; }\n}.card-group { display: flex; flex-direction: column; }.card-group > .card { margin-bottom: 15px; }@media (min-width: 576px) {\n .card-group { flex-flow: row wrap; }\n .card-group > .card { flex: 1 0 0%; margin-bottom: 0px; }\n .card-group > .card + .card { margin-left: 0px; border-left: 0px; }\n .card-group > .card:first-child { border-top-right-radius: 0px; border-bottom-right-radius: 0px; }\n .card-group > .card:first-child .card-header, .card-group > .card:first-child .card-img-top { border-top-right-radius: 0px; }\n .card-group > .card:first-child .card-footer, .card-group > .card:first-child .card-img-bottom { border-bottom-right-radius: 0px; }\n .card-group > .card:last-child { border-top-left-radius: 0px; border-bottom-left-radius: 0px; }\n .card-group > .card:last-child .card-header, .card-group > .card:last-child .card-img-top { border-top-left-radius: 0px; }\n .card-group > .card:last-child .card-footer, .card-group > .card:last-child .card-img-bottom { border-bottom-left-radius: 0px; }\n .card-group > .card:only-child { border-radius: 0.25rem; }\n .card-group > .card:only-child .card-header, .card-group > .card:only-child .card-img-top { border-top-left-radius: 0.25rem; border-top-right-radius: 0.25rem; }\n .card-group > .card:only-child .card-footer, .card-group > .card:only-child .card-img-bottom { border-bottom-right-radius: 0.25rem; border-bottom-left-radius: 0.25rem; }\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) { border-radius: 0px; }\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-footer, .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-header, .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom, .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-img-top { border-radius: 0px; }\n}.card-columns .card { margin-bottom: 0.75rem; }@media (min-width: 576px) {\n .card-columns { column-count: 3; column-gap: 1.25rem; orphans: 1; widows: 1; }\n .card-columns .card { display: inline-block; width: 100%; }\n}.accordion .card:not(:first-of-type):not(:last-of-type) { border-bottom: 0px; border-radius: 0px; }.accordion .card:not(:first-of-type) .card-header:first-child { border-radius: 0px; }.accordion .card:first-of-type { border-bottom: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; }.accordion .card:last-of-type { border-top-left-radius: 0px; border-top-right-radius: 0px; }.breadcrumb { display: flex; flex-wrap: wrap; padding: 0.75rem 1rem; margin-bottom: 1rem; list-style: none; background-color: rgb(233, 236, 239); border-radius: 0.25rem; }.breadcrumb-item + .breadcrumb-item { padding-left: 0.5rem; }.breadcrumb-item + .breadcrumb-item::before { display: inline-block; padding-right: 0.5rem; color: rgb(108, 117, 125); content: \"/\"; }.breadcrumb-item + .breadcrumb-item:hover::before { text-decoration: underline; }.breadcrumb-item + .breadcrumb-item:hover::before { text-decoration: none; }.breadcrumb-item.active { color: rgb(108, 117, 125); }.pagination { display: flex; padding-left: 0px; list-style: none; border-radius: 0.25rem; }.page-link { position: relative; display: block; padding: 0.5rem 0.75rem; margin-left: -1px; line-height: 1.25; color: rgb(0, 123, 255); background-color: rgb(255, 255, 255); border: 1px solid rgb(222, 226, 230); }.page-link:hover { z-index: 2; color: rgb(0, 86, 179); text-decoration: none; background-color: rgb(233, 236, 239); border-color: rgb(222, 226, 230); }.page-link:focus { z-index: 2; outline: 0px; box-shadow: rgba(0, 123, 255, 0.25) 0px 0px 0px 0.2rem; }.page-link:not(:disabled):not(.disabled) { cursor: pointer; }.page-item:first-child .page-link { margin-left: 0px; border-top-left-radius: 0.25rem; border-bottom-left-radius: 0.25rem; }.page-item:last-child .page-link { border-top-right-radius: 0.25rem; border-bottom-right-radius: 0.25rem; }.page-item.active .page-link { z-index: 1; color: rgb(255, 255, 255); background-color: rgb(0, 123, 255); border-color: rgb(0, 123, 255); }.page-item.disabled .page-link { color: rgb(108, 117, 125); pointer-events: none; cursor: auto; background-color: rgb(255, 255, 255); border-color: rgb(222, 226, 230); }.pagination-lg .page-link { padding: 0.75rem 1.5rem; font-size: 1.25rem; line-height: 1.5; }.pagination-lg .page-item:first-child .page-link { border-top-left-radius: 0.3rem; border-bottom-left-radius: 0.3rem; }.pagination-lg .page-item:last-child .page-link { border-top-right-radius: 0.3rem; border-bottom-right-radius: 0.3rem; }.pagination-sm .page-link { padding: 0.25rem 0.5rem; font-size: 0.875rem; line-height: 1.5; }.pagination-sm .page-item:first-child .page-link { border-top-left-radius: 0.2rem; border-bottom-left-radius: 0.2rem; }.pagination-sm .page-item:last-child .page-link { border-top-right-radius: 0.2rem; border-bottom-right-radius: 0.2rem; }.badge { display: inline-block; padding: 0.25em 0.4em; font-size: 75%; font-weight: 700; line-height: 1; text-align: center; white-space: nowrap; vertical-align: baseline; border-radius: 0.25rem; }.badge:empty { display: none; }.btn .badge { position: relative; top: -1px; }.badge-pill { padding-right: 0.6em; padding-left: 0.6em; border-radius: 10rem; }.badge-primary { color: rgb(255, 255, 255); background-color: rgb(0, 123, 255); }.badge-primary[href]:focus, .badge-primary[href]:hover { color: rgb(255, 255, 255); text-decoration: none; background-color: rgb(0, 98, 204); }.badge-secondary { color: rgb(255, 255, 255); background-color: rgb(108, 117, 125); }.badge-secondary[href]:focus, .badge-secondary[href]:hover { color: rgb(255, 255, 255); text-decoration: none; background-color: rgb(84, 91, 98); }.badge-success { color: rgb(255, 255, 255); background-color: rgb(40, 167, 69); }.badge-success[href]:focus, .badge-success[href]:hover { color: rgb(255, 255, 255); text-decoration: none; background-color: rgb(30, 126, 52); }.badge-info { color: rgb(255, 255, 255); background-color: rgb(23, 162, 184); }.badge-info[href]:focus, .badge-info[href]:hover { color: rgb(255, 255, 255); text-decoration: none; background-color: rgb(17, 122, 139); }.badge-warning { color: rgb(33, 37, 41); background-color: rgb(255, 193, 7); }.badge-warning[href]:focus, .badge-warning[href]:hover { color: rgb(33, 37, 41); text-decoration: none; background-color: rgb(211, 158, 0); }.badge-danger { color: rgb(255, 255, 255); background-color: rgb(220, 53, 69); }.badge-danger[href]:focus, .badge-danger[href]:hover { color: rgb(255, 255, 255); text-decoration: none; background-color: rgb(189, 33, 48); }.badge-light { color: rgb(33, 37, 41); background-color: rgb(248, 249, 250); }.badge-light[href]:focus, .badge-light[href]:hover { color: rgb(33, 37, 41); text-decoration: none; background-color: rgb(218, 224, 229); }.badge-dark { color: rgb(255, 255, 255); background-color: rgb(52, 58, 64); }.badge-dark[href]:focus, .badge-dark[href]:hover { color: rgb(255, 255, 255); text-decoration: none; background-color: rgb(29, 33, 36); }.jumbotron { padding: 2rem 1rem; margin-bottom: 2rem; background-color: rgb(233, 236, 239); border-radius: 0.3rem; }@media (min-width: 576px) {\n .jumbotron { padding: 4rem 2rem; }\n}.jumbotron-fluid { padding-right: 0px; padding-left: 0px; border-radius: 0px; }.alert { position: relative; padding: 0.75rem 1.25rem; margin-bottom: 1rem; border: 1px solid transparent; border-radius: 0.25rem; }.alert-heading { color: inherit; }.alert-link { font-weight: 700; }.alert-dismissible { padding-right: 4rem; }.alert-dismissible .close { position: absolute; top: 0px; right: 0px; padding: 0.75rem 1.25rem; color: inherit; }.alert-primary { color: rgb(0, 64, 133); background-color: rgb(204, 229, 255); border-color: rgb(184, 218, 255); }.alert-primary hr { border-top-color: rgb(159, 205, 255); }.alert-primary .alert-link { color: rgb(0, 39, 82); }.alert-secondary { color: rgb(56, 61, 65); background-color: rgb(226, 227, 229); border-color: rgb(214, 216, 219); }.alert-secondary hr { border-top-color: rgb(200, 203, 207); }.alert-secondary .alert-link { color: rgb(32, 35, 38); }.alert-success { color: rgb(21, 87, 36); background-color: rgb(212, 237, 218); border-color: rgb(195, 230, 203); }.alert-success hr { border-top-color: rgb(177, 223, 187); }.alert-success .alert-link { color: rgb(11, 46, 19); }.alert-info { color: rgb(12, 84, 96); background-color: rgb(209, 236, 241); border-color: rgb(190, 229, 235); }.alert-info hr { border-top-color: rgb(171, 221, 229); }.alert-info .alert-link { color: rgb(6, 44, 51); }.alert-warning { color: rgb(133, 100, 4); background-color: rgb(255, 243, 205); border-color: rgb(255, 238, 186); }.alert-warning hr { border-top-color: rgb(255, 232, 161); }.alert-warning .alert-link { color: rgb(83, 63, 3); }.alert-danger { color: rgb(114, 28, 36); background-color: rgb(248, 215, 218); border-color: rgb(245, 198, 203); }.alert-danger hr { border-top-color: rgb(241, 176, 183); }.alert-danger .alert-link { color: rgb(73, 18, 23); }.alert-light { color: rgb(129, 129, 130); background-color: rgb(254, 254, 254); border-color: rgb(253, 253, 254); }.alert-light hr { border-top-color: rgb(236, 236, 246); }.alert-light .alert-link { color: rgb(104, 104, 104); }.alert-dark { color: rgb(27, 30, 33); background-color: rgb(214, 216, 217); border-color: rgb(198, 200, 202); }.alert-dark hr { border-top-color: rgb(185, 187, 190); }.alert-dark .alert-link { color: rgb(4, 5, 5); }@-webkit-keyframes progress-bar-stripes { \n 0% { background-position: 1rem 0px; }\n 100% { background-position: 0px 0px; }\n}@keyframes progress-bar-stripes { \n 0% { background-position: 1rem 0px; }\n 100% { background-position: 0px 0px; }\n}.progress { display: flex; height: 1rem; overflow: hidden; font-size: 0.75rem; background-color: rgb(233, 236, 239); border-radius: 0.25rem; }.progress-bar { display: flex; flex-direction: column; justify-content: center; color: rgb(255, 255, 255); text-align: center; white-space: nowrap; background-color: rgb(0, 123, 255); transition: width 0.6s ease 0s; }@media not all {\n .progress-bar { transition: none 0s ease 0s; }\n}.progress-bar-striped { background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-size: 1rem 1rem; }.progress-bar-animated { animation: progress-bar-stripes 1s linear 0s infinite normal none running; }.media { display: flex; align-items: flex-start; }.media-body { flex: 1 1 0%; }.list-group { display: flex; flex-direction: column; padding-left: 0px; margin-bottom: 0px; }.list-group-item-action { width: 100%; color: rgb(73, 80, 87); text-align: inherit; }.list-group-item-action:focus, .list-group-item-action:hover { color: rgb(73, 80, 87); text-decoration: none; background-color: rgb(248, 249, 250); }.list-group-item-action:active { color: rgb(33, 37, 41); background-color: rgb(233, 236, 239); }.list-group-item { position: relative; display: block; padding: 0.75rem 1.25rem; margin-bottom: -1px; background-color: rgb(255, 255, 255); border: 1px solid rgba(0, 0, 0, 0.125); }.list-group-item:first-child { border-top-left-radius: 0.25rem; border-top-right-radius: 0.25rem; }.list-group-item:last-child { margin-bottom: 0px; border-bottom-right-radius: 0.25rem; border-bottom-left-radius: 0.25rem; }.list-group-item:focus, .list-group-item:hover { z-index: 1; text-decoration: none; }.list-group-item.disabled, .list-group-item:disabled { color: rgb(108, 117, 125); background-color: rgb(255, 255, 255); }.list-group-item.active { z-index: 2; color: rgb(255, 255, 255); background-color: rgb(0, 123, 255); border-color: rgb(0, 123, 255); }.list-group-flush .list-group-item { border-right: 0px; border-left: 0px; border-radius: 0px; }.list-group-flush:first-child .list-group-item:first-child { border-top: 0px; }.list-group-flush:last-child .list-group-item:last-child { border-bottom: 0px; }.list-group-item-primary { color: rgb(0, 64, 133); background-color: rgb(184, 218, 255); }.list-group-item-primary.list-group-item-action:focus, .list-group-item-primary.list-group-item-action:hover { color: rgb(0, 64, 133); background-color: rgb(159, 205, 255); }.list-group-item-primary.list-group-item-action.active { color: rgb(255, 255, 255); background-color: rgb(0, 64, 133); border-color: rgb(0, 64, 133); }.list-group-item-secondary { color: rgb(56, 61, 65); background-color: rgb(214, 216, 219); }.list-group-item-secondary.list-group-item-action:focus, .list-group-item-secondary.list-group-item-action:hover { color: rgb(56, 61, 65); background-color: rgb(200, 203, 207); }.list-group-item-secondary.list-group-item-action.active { color: rgb(255, 255, 255); background-color: rgb(56, 61, 65); border-color: rgb(56, 61, 65); }.list-group-item-success { color: rgb(21, 87, 36); background-color: rgb(195, 230, 203); }.list-group-item-success.list-group-item-action:focus, .list-group-item-success.list-group-item-action:hover { color: rgb(21, 87, 36); background-color: rgb(177, 223, 187); }.list-group-item-success.list-group-item-action.active { color: rgb(255, 255, 255); background-color: rgb(21, 87, 36); border-color: rgb(21, 87, 36); }.list-group-item-info { color: rgb(12, 84, 96); background-color: rgb(190, 229, 235); }.list-group-item-info.list-group-item-action:focus, .list-group-item-info.list-group-item-action:hover { color: rgb(12, 84, 96); background-color: rgb(171, 221, 229); }.list-group-item-info.list-group-item-action.active { color: rgb(255, 255, 255); background-color: rgb(12, 84, 96); border-color: rgb(12, 84, 96); }.list-group-item-warning { color: rgb(133, 100, 4); background-color: rgb(255, 238, 186); }.list-group-item-warning.list-group-item-action:focus, .list-group-item-warning.list-group-item-action:hover { color: rgb(133, 100, 4); background-color: rgb(255, 232, 161); }.list-group-item-warning.list-group-item-action.active { color: rgb(255, 255, 255); background-color: rgb(133, 100, 4); border-color: rgb(133, 100, 4); }.list-group-item-danger { color: rgb(114, 28, 36); background-color: rgb(245, 198, 203); }.list-group-item-danger.list-group-item-action:focus, .list-group-item-danger.list-group-item-action:hover { color: rgb(114, 28, 36); background-color: rgb(241, 176, 183); }.list-group-item-danger.list-group-item-action.active { color: rgb(255, 255, 255); background-color: rgb(114, 28, 36); border-color: rgb(114, 28, 36); }.list-group-item-light { color: rgb(129, 129, 130); background-color: rgb(253, 253, 254); }.list-group-item-light.list-group-item-action:focus, .list-group-item-light.list-group-item-action:hover { color: rgb(129, 129, 130); background-color: rgb(236, 236, 246); }.list-group-item-light.list-group-item-action.active { color: rgb(255, 255, 255); background-color: rgb(129, 129, 130); border-color: rgb(129, 129, 130); }.list-group-item-dark { color: rgb(27, 30, 33); background-color: rgb(198, 200, 202); }.list-group-item-dark.list-group-item-action:focus, .list-group-item-dark.list-group-item-action:hover { color: rgb(27, 30, 33); background-color: rgb(185, 187, 190); }.list-group-item-dark.list-group-item-action.active { color: rgb(255, 255, 255); background-color: rgb(27, 30, 33); border-color: rgb(27, 30, 33); }.close { float: right; font-size: 1.5rem; font-weight: 700; line-height: 1; color: rgb(0, 0, 0); text-shadow: rgb(255, 255, 255) 0px 1px 0px; opacity: 0.5; }.close:not(:disabled):not(.disabled) { cursor: pointer; }.close:not(:disabled):not(.disabled):focus, .close:not(:disabled):not(.disabled):hover { color: rgb(0, 0, 0); text-decoration: none; opacity: 0.75; }button.close { padding: 0px; background-color: transparent; border: 0px; -webkit-appearance: none; }.modal-open { overflow: hidden; }.modal-open .modal { overflow: hidden auto; }.modal { position: fixed; top: 0px; right: 0px; bottom: 0px; left: 0px; z-index: 1050; display: none; overflow: hidden; outline: 0px; }.modal-dialog { position: relative; width: auto; margin: 0.5rem; pointer-events: none; }.modal.fade .modal-dialog { transition: transform 0.3s ease-out 0s, -webkit-transform 0.3s ease-out 0s; transform: translate(0px, -25%); }@media not all {\n .modal.fade .modal-dialog { transition: none 0s ease 0s; }\n}.modal.show .modal-dialog { transform: translate(0px, 0px); }.modal-dialog-centered { display: flex; align-items: center; min-height: calc(100% - 1rem); }.modal-dialog-centered::before { display: block; height: calc(100vh - 1rem); content: \"\"; }.modal-content { position: relative; display: flex; flex-direction: column; width: 100%; pointer-events: auto; background-color: rgb(255, 255, 255); background-clip: padding-box; border: 1px solid rgba(0, 0, 0, 0.2); border-radius: 0.3rem; outline: 0px; }.modal-backdrop { position: fixed; top: 0px; right: 0px; bottom: 0px; left: 0px; z-index: 1040; background-color: rgb(0, 0, 0); }.modal-backdrop.fade { opacity: 0; }.modal-backdrop.show { opacity: 0.5; }.modal-header { display: flex; align-items: flex-start; justify-content: space-between; padding: 1rem; border-bottom: 1px solid rgb(233, 236, 239); border-top-left-radius: 0.3rem; border-top-right-radius: 0.3rem; }.modal-header .close { padding: 1rem; margin: -1rem -1rem -1rem auto; }.modal-title { margin-bottom: 0px; line-height: 1.5; }.modal-body { position: relative; flex: 1 1 auto; padding: 1rem; }.modal-footer { display: flex; align-items: center; justify-content: flex-end; padding: 1rem; border-top: 1px solid rgb(233, 236, 239); }.modal-footer > :not(:first-child) { margin-left: 0.25rem; }.modal-footer > :not(:last-child) { margin-right: 0.25rem; }.modal-scrollbar-measure { position: absolute; top: -9999px; width: 50px; height: 50px; overflow: scroll; }@media (min-width: 576px) {\n .modal-dialog { max-width: 500px; margin: 1.75rem auto; }\n .modal-dialog-centered { min-height: calc(100% - 3.5rem); }\n .modal-dialog-centered::before { height: calc(100vh - 3.5rem); }\n .modal-sm { max-width: 300px; }\n}@media (min-width: 992px) {\n .modal-lg { max-width: 800px; }\n}.tooltip { position: absolute; z-index: 1070; display: block; margin: 0px; font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\"; font-style: normal; font-weight: 400; line-height: 1.5; text-align: start; text-decoration: none; text-shadow: none; text-transform: none; letter-spacing: normal; word-break: normal; word-spacing: normal; white-space: normal; line-break: auto; font-size: 0.875rem; word-wrap: break-word; opacity: 0; }.tooltip.show { opacity: 0.9; }.tooltip .arrow { position: absolute; display: block; width: 0.8rem; height: 0.4rem; }.tooltip .arrow::before { position: absolute; content: \"\"; border-color: transparent; border-style: solid; }.bs-tooltip-auto[x-placement^=\"top\"], .bs-tooltip-top { padding: 0.4rem 0px; }.bs-tooltip-auto[x-placement^=\"top\"] .arrow, .bs-tooltip-top .arrow { bottom: 0px; }.bs-tooltip-auto[x-placement^=\"top\"] .arrow::before, .bs-tooltip-top .arrow::before { top: 0px; border-width: 0.4rem 0.4rem 0px; border-top-color: rgb(0, 0, 0); }.bs-tooltip-auto[x-placement^=\"right\"], .bs-tooltip-right { padding: 0px 0.4rem; }.bs-tooltip-auto[x-placement^=\"right\"] .arrow, .bs-tooltip-right .arrow { left: 0px; width: 0.4rem; height: 0.8rem; }.bs-tooltip-auto[x-placement^=\"right\"] .arrow::before, .bs-tooltip-right .arrow::before { right: 0px; border-width: 0.4rem 0.4rem 0.4rem 0px; border-right-color: rgb(0, 0, 0); }.bs-tooltip-auto[x-placement^=\"bottom\"], .bs-tooltip-bottom { padding: 0.4rem 0px; }.bs-tooltip-auto[x-placement^=\"bottom\"] .arrow, .bs-tooltip-bottom .arrow { top: 0px; }.bs-tooltip-auto[x-placement^=\"bottom\"] .arrow::before, .bs-tooltip-bottom .arrow::before { bottom: 0px; border-width: 0px 0.4rem 0.4rem; border-bottom-color: rgb(0, 0, 0); }.bs-tooltip-auto[x-placement^=\"left\"], .bs-tooltip-left { padding: 0px 0.4rem; }.bs-tooltip-auto[x-placement^=\"left\"] .arrow, .bs-tooltip-left .arrow { right: 0px; width: 0.4rem; height: 0.8rem; }.bs-tooltip-auto[x-placement^=\"left\"] .arrow::before, .bs-tooltip-left .arrow::before { left: 0px; border-width: 0.4rem 0px 0.4rem 0.4rem; border-left-color: rgb(0, 0, 0); }.tooltip-inner { max-width: 200px; padding: 0.25rem 0.5rem; color: rgb(255, 255, 255); text-align: center; background-color: rgb(0, 0, 0); border-radius: 0.25rem; }.popover { position: absolute; top: 0px; left: 0px; z-index: 1060; display: block; max-width: 276px; font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\"; font-style: normal; font-weight: 400; line-height: 1.5; text-align: start; text-decoration: none; text-shadow: none; text-transform: none; letter-spacing: normal; word-break: normal; word-spacing: normal; white-space: normal; line-break: auto; font-size: 0.875rem; word-wrap: break-word; background-color: rgb(255, 255, 255); background-clip: padding-box; border: 1px solid rgba(0, 0, 0, 0.2); border-radius: 0.3rem; }.popover .arrow { position: absolute; display: block; width: 1rem; height: 0.5rem; margin: 0px 0.3rem; }.popover .arrow::after, .popover .arrow::before { position: absolute; display: block; content: \"\"; border-color: transparent; border-style: solid; }.bs-popover-auto[x-placement^=\"top\"], .bs-popover-top { margin-bottom: 0.5rem; }.bs-popover-auto[x-placement^=\"top\"] .arrow, .bs-popover-top .arrow { bottom: calc((0.5rem + 1px) * -1); }.bs-popover-auto[x-placement^=\"top\"] .arrow::after, .bs-popover-auto[x-placement^=\"top\"] .arrow::before, .bs-popover-top .arrow::after, .bs-popover-top .arrow::before { border-width: 0.5rem 0.5rem 0px; }.bs-popover-auto[x-placement^=\"top\"] .arrow::before, .bs-popover-top .arrow::before { bottom: 0px; border-top-color: rgba(0, 0, 0, 0.25); }.bs-popover-auto[x-placement^=\"top\"] .arrow::after, .bs-popover-top .arrow::after { bottom: 1px; border-top-color: rgb(255, 255, 255); }.bs-popover-auto[x-placement^=\"right\"], .bs-popover-right { margin-left: 0.5rem; }.bs-popover-auto[x-placement^=\"right\"] .arrow, .bs-popover-right .arrow { left: calc((0.5rem + 1px) * -1); width: 0.5rem; height: 1rem; margin: 0.3rem 0px; }.bs-popover-auto[x-placement^=\"right\"] .arrow::after, .bs-popover-auto[x-placement^=\"right\"] .arrow::before, .bs-popover-right .arrow::after, .bs-popover-right .arrow::before { border-width: 0.5rem 0.5rem 0.5rem 0px; }.bs-popover-auto[x-placement^=\"right\"] .arrow::before, .bs-popover-right .arrow::before { left: 0px; border-right-color: rgba(0, 0, 0, 0.25); }.bs-popover-auto[x-placement^=\"right\"] .arrow::after, .bs-popover-right .arrow::after { left: 1px; border-right-color: rgb(255, 255, 255); }.bs-popover-auto[x-placement^=\"bottom\"], .bs-popover-bottom { margin-top: 0.5rem; }.bs-popover-auto[x-placement^=\"bottom\"] .arrow, .bs-popover-bottom .arrow { top: calc((0.5rem + 1px) * -1); }.bs-popover-auto[x-placement^=\"bottom\"] .arrow::after, .bs-popover-auto[x-placement^=\"bottom\"] .arrow::before, .bs-popover-bottom .arrow::after, .bs-popover-bottom .arrow::before { border-width: 0px 0.5rem 0.5rem; }.bs-popover-auto[x-placement^=\"bottom\"] .arrow::before, .bs-popover-bottom .arrow::before { top: 0px; border-bottom-color: rgba(0, 0, 0, 0.25); }.bs-popover-auto[x-placement^=\"bottom\"] .arrow::after, .bs-popover-bottom .arrow::after { top: 1px; border-bottom-color: rgb(255, 255, 255); }.bs-popover-auto[x-placement^=\"bottom\"] .popover-header::before, .bs-popover-bottom .popover-header::before { position: absolute; top: 0px; left: 50%; display: block; width: 1rem; margin-left: -0.5rem; content: \"\"; border-bottom: 1px solid rgb(247, 247, 247); }.bs-popover-auto[x-placement^=\"left\"], .bs-popover-left { margin-right: 0.5rem; }.bs-popover-auto[x-placement^=\"left\"] .arrow, .bs-popover-left .arrow { right: calc((0.5rem + 1px) * -1); width: 0.5rem; height: 1rem; margin: 0.3rem 0px; }.bs-popover-auto[x-placement^=\"left\"] .arrow::after, .bs-popover-auto[x-placement^=\"left\"] .arrow::before, .bs-popover-left .arrow::after, .bs-popover-left .arrow::before { border-width: 0.5rem 0px 0.5rem 0.5rem; }.bs-popover-auto[x-placement^=\"left\"] .arrow::before, .bs-popover-left .arrow::before { right: 0px; border-left-color: rgba(0, 0, 0, 0.25); }.bs-popover-auto[x-placement^=\"left\"] .arrow::after, .bs-popover-left .arrow::after { right: 1px; border-left-color: rgb(255, 255, 255); }.popover-header { padding: 0.5rem 0.75rem; margin-bottom: 0px; font-size: 1rem; color: inherit; background-color: rgb(247, 247, 247); border-bottom: 1px solid rgb(235, 235, 235); border-top-left-radius: calc(0.3rem - 1px); border-top-right-radius: calc(0.3rem - 1px); }.popover-header:empty { display: none; }.popover-body { padding: 0.5rem 0.75rem; color: rgb(33, 37, 41); }.carousel { position: relative; }.carousel-inner { position: relative; width: 100%; overflow: hidden; }.carousel-item { position: relative; display: none; align-items: center; width: 100%; backface-visibility: hidden; perspective: 1000px; }.carousel-item-next, .carousel-item-prev, .carousel-item.active { display: block; transition: transform 0.6s ease 0s, -webkit-transform 0.6s ease 0s; }@media not all {\n .carousel-item-next, .carousel-item-prev, .carousel-item.active { transition: none 0s ease 0s; }\n}.carousel-item-next, .carousel-item-prev { position: absolute; top: 0px; }.carousel-item-next.carousel-item-left, .carousel-item-prev.carousel-item-right { transform: translateX(0px); }@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)) {\n .carousel-item-next.carousel-item-left, .carousel-item-prev.carousel-item-right { transform: translate3d(0px, 0px, 0px); }\n}.active.carousel-item-right, .carousel-item-next { transform: translateX(100%); }@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)) {\n .active.carousel-item-right, .carousel-item-next { transform: translate3d(100%, 0px, 0px); }\n}.active.carousel-item-left, .carousel-item-prev { transform: translateX(-100%); }@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)) {\n .active.carousel-item-left, .carousel-item-prev { transform: translate3d(-100%, 0px, 0px); }\n}.carousel-fade .carousel-item { opacity: 0; transition-duration: 0.6s; transition-property: opacity; }.carousel-fade .carousel-item-next.carousel-item-left, .carousel-fade .carousel-item-prev.carousel-item-right, .carousel-fade .carousel-item.active { opacity: 1; }.carousel-fade .active.carousel-item-left, .carousel-fade .active.carousel-item-right { opacity: 0; }.carousel-fade .active.carousel-item-left, .carousel-fade .active.carousel-item-prev, .carousel-fade .carousel-item-next, .carousel-fade .carousel-item-prev, .carousel-fade .carousel-item.active { transform: translateX(0px); }@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)) {\n .carousel-fade .active.carousel-item-left, .carousel-fade .active.carousel-item-prev, .carousel-fade .carousel-item-next, .carousel-fade .carousel-item-prev, .carousel-fade .carousel-item.active { transform: translate3d(0px, 0px, 0px); }\n}.carousel-control-next, .carousel-control-prev { position: absolute; top: 0px; bottom: 0px; display: flex; align-items: center; justify-content: center; width: 15%; color: rgb(255, 255, 255); text-align: center; opacity: 0.5; }.carousel-control-next:focus, .carousel-control-next:hover, .carousel-control-prev:focus, .carousel-control-prev:hover { color: rgb(255, 255, 255); text-decoration: none; outline: 0px; opacity: 0.9; }.carousel-control-prev { left: 0px; }.carousel-control-next { right: 0px; }.carousel-control-next-icon, .carousel-control-prev-icon { display: inline-block; width: 20px; height: 20px; background: center center / 100% 100% no-repeat transparent; }.carousel-control-prev-icon { background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E\"); }.carousel-control-next-icon { background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E\"); }.carousel-indicators { position: absolute; right: 0px; bottom: 10px; left: 0px; z-index: 15; display: flex; justify-content: center; padding-left: 0px; margin-right: 15%; margin-left: 15%; list-style: none; }.carousel-indicators li { position: relative; flex: 0 1 auto; width: 30px; height: 3px; margin-right: 3px; margin-left: 3px; text-indent: -999px; cursor: pointer; background-color: rgba(255, 255, 255, 0.5); }.carousel-indicators li::before { position: absolute; top: -10px; left: 0px; display: inline-block; width: 100%; height: 10px; content: \"\"; }.carousel-indicators li::after { position: absolute; bottom: -10px; left: 0px; display: inline-block; width: 100%; height: 10px; content: \"\"; }.carousel-indicators .active { background-color: rgb(255, 255, 255); }.carousel-caption { position: absolute; right: 15%; bottom: 20px; left: 15%; z-index: 10; padding-top: 20px; padding-bottom: 20px; color: rgb(255, 255, 255); text-align: center; }.align-baseline { vertical-align: baseline !important; }.align-top { vertical-align: top !important; }.align-middle { vertical-align: middle !important; }.align-bottom { vertical-align: bottom !important; }.align-text-bottom { vertical-align: text-bottom !important; }.align-text-top { vertical-align: text-top !important; }.bg-primary { background-color: rgb(0, 123, 255) !important; }a.bg-primary:focus, a.bg-primary:hover, button.bg-primary:focus, button.bg-primary:hover { background-color: rgb(0, 98, 204) !important; }.bg-secondary { background-color: rgb(108, 117, 125) !important; }a.bg-secondary:focus, a.bg-secondary:hover, button.bg-secondary:focus, button.bg-secondary:hover { background-color: rgb(84, 91, 98) !important; }.bg-success { background-color: rgb(40, 167, 69) !important; }a.bg-success:focus, a.bg-success:hover, button.bg-success:focus, button.bg-success:hover { background-color: rgb(30, 126, 52) !important; }.bg-info { background-color: rgb(23, 162, 184) !important; }a.bg-info:focus, a.bg-info:hover, button.bg-info:focus, button.bg-info:hover { background-color: rgb(17, 122, 139) !important; }.bg-warning { background-color: rgb(255, 193, 7) !important; }a.bg-warning:focus, a.bg-warning:hover, button.bg-warning:focus, button.bg-warning:hover { background-color: rgb(211, 158, 0) !important; }.bg-danger { background-color: rgb(220, 53, 69) !important; }a.bg-danger:focus, a.bg-danger:hover, button.bg-danger:focus, button.bg-danger:hover { background-color: rgb(189, 33, 48) !important; }.bg-light { background-color: rgb(248, 249, 250) !important; }a.bg-light:focus, a.bg-light:hover, button.bg-light:focus, button.bg-light:hover { background-color: rgb(218, 224, 229) !important; }.bg-dark { background-color: rgb(52, 58, 64) !important; }a.bg-dark:focus, a.bg-dark:hover, button.bg-dark:focus, button.bg-dark:hover { background-color: rgb(29, 33, 36) !important; }.bg-white { background-color: rgb(255, 255, 255) !important; }.bg-transparent { background-color: transparent !important; }.border { border: 1px solid rgb(222, 226, 230) !important; }.border-top { border-top: 1px solid rgb(222, 226, 230) !important; }.border-right { border-right: 1px solid rgb(222, 226, 230) !important; }.border-bottom { border-bottom: 1px solid rgb(222, 226, 230) !important; }.border-left { border-left: 1px solid rgb(222, 226, 230) !important; }.border-0 { border: 0px !important; }.border-top-0 { border-top: 0px !important; }.border-right-0 { border-right: 0px !important; }.border-bottom-0 { border-bottom: 0px !important; }.border-left-0 { border-left: 0px !important; }.border-primary { border-color: rgb(0, 123, 255) !important; }.border-secondary { border-color: rgb(108, 117, 125) !important; }.border-success { border-color: rgb(40, 167, 69) !important; }.border-info { border-color: rgb(23, 162, 184) !important; }.border-warning { border-color: rgb(255, 193, 7) !important; }.border-danger { border-color: rgb(220, 53, 69) !important; }.border-light { border-color: rgb(248, 249, 250) !important; }.border-dark { border-color: rgb(52, 58, 64) !important; }.border-white { border-color: rgb(255, 255, 255) !important; }.rounded { border-radius: 0.25rem !important; }.rounded-top { border-top-left-radius: 0.25rem !important; border-top-right-radius: 0.25rem !important; }.rounded-right { border-top-right-radius: 0.25rem !important; border-bottom-right-radius: 0.25rem !important; }.rounded-bottom { border-bottom-right-radius: 0.25rem !important; border-bottom-left-radius: 0.25rem !important; }.rounded-left { border-top-left-radius: 0.25rem !important; border-bottom-left-radius: 0.25rem !important; }.rounded-circle { border-radius: 50% !important; }.rounded-0 { border-radius: 0px !important; }.clearfix::after { display: block; clear: both; content: \"\"; }.d-none { display: none !important; }.d-inline { display: inline !important; }.d-inline-block { display: inline-block !important; }.d-block { display: block !important; }.d-table { display: table !important; }.d-table-row { display: table-row !important; }.d-table-cell { display: table-cell !important; }.d-flex { display: flex !important; }.d-inline-flex { display: inline-flex !important; }@media (min-width: 576px) {\n .d-sm-none { display: none !important; }\n .d-sm-inline { display: inline !important; }\n .d-sm-inline-block { display: inline-block !important; }\n .d-sm-block { display: block !important; }\n .d-sm-table { display: table !important; }\n .d-sm-table-row { display: table-row !important; }\n .d-sm-table-cell { display: table-cell !important; }\n .d-sm-flex { display: flex !important; }\n .d-sm-inline-flex { display: inline-flex !important; }\n}@media (min-width: 768px) {\n .d-md-none { display: none !important; }\n .d-md-inline { display: inline !important; }\n .d-md-inline-block { display: inline-block !important; }\n .d-md-block { display: block !important; }\n .d-md-table { display: table !important; }\n .d-md-table-row { display: table-row !important; }\n .d-md-table-cell { display: table-cell !important; }\n .d-md-flex { display: flex !important; }\n .d-md-inline-flex { display: inline-flex !important; }\n}@media (min-width: 992px) {\n .d-lg-none { display: none !important; }\n .d-lg-inline { display: inline !important; }\n .d-lg-inline-block { display: inline-block !important; }\n .d-lg-block { display: block !important; }\n .d-lg-table { display: table !important; }\n .d-lg-table-row { display: table-row !important; }\n .d-lg-table-cell { display: table-cell !important; }\n .d-lg-flex { display: flex !important; }\n .d-lg-inline-flex { display: inline-flex !important; }\n}@media (min-width: 1200px) {\n .d-xl-none { display: none !important; }\n .d-xl-inline { display: inline !important; }\n .d-xl-inline-block { display: inline-block !important; }\n .d-xl-block { display: block !important; }\n .d-xl-table { display: table !important; }\n .d-xl-table-row { display: table-row !important; }\n .d-xl-table-cell { display: table-cell !important; }\n .d-xl-flex { display: flex !important; }\n .d-xl-inline-flex { display: inline-flex !important; }\n}@media print {\n .d-print-none { display: none !important; }\n .d-print-inline { display: inline !important; }\n .d-print-inline-block { display: inline-block !important; }\n .d-print-block { display: block !important; }\n .d-print-table { display: table !important; }\n .d-print-table-row { display: table-row !important; }\n .d-print-table-cell { display: table-cell !important; }\n .d-print-flex { display: flex !important; }\n .d-print-inline-flex { display: inline-flex !important; }\n}.embed-responsive { position: relative; display: block; width: 100%; padding: 0px; overflow: hidden; }.embed-responsive::before { display: block; content: \"\"; }.embed-responsive .embed-responsive-item, .embed-responsive embed, .embed-responsive iframe, .embed-responsive object, .embed-responsive video { position: absolute; top: 0px; bottom: 0px; left: 0px; width: 100%; height: 100%; border: 0px; }.embed-responsive-21by9::before { padding-top: 42.8571%; }.embed-responsive-16by9::before { padding-top: 56.25%; }.embed-responsive-4by3::before { padding-top: 75%; }.embed-responsive-1by1::before { padding-top: 100%; }.flex-row { flex-direction: row !important; }.flex-column { flex-direction: column !important; }.flex-row-reverse { flex-direction: row-reverse !important; }.flex-column-reverse { flex-direction: column-reverse !important; }.flex-wrap { flex-wrap: wrap !important; }.flex-nowrap { flex-wrap: nowrap !important; }.flex-wrap-reverse { flex-wrap: wrap-reverse !important; }.flex-fill { flex: 1 1 auto !important; }.flex-grow-0 { flex-grow: 0 !important; }.flex-grow-1 { flex-grow: 1 !important; }.flex-shrink-0 { flex-shrink: 0 !important; }.flex-shrink-1 { flex-shrink: 1 !important; }.justify-content-start { justify-content: flex-start !important; }.justify-content-end { justify-content: flex-end !important; }.justify-content-center { justify-content: center !important; }.justify-content-between { justify-content: space-between !important; }.justify-content-around { justify-content: space-around !important; }.align-items-start { align-items: flex-start !important; }.align-items-end { align-items: flex-end !important; }.align-items-center { align-items: center !important; }.align-items-baseline { align-items: baseline !important; }.align-items-stretch { align-items: stretch !important; }.align-content-start { align-content: flex-start !important; }.align-content-end { align-content: flex-end !important; }.align-content-center { align-content: center !important; }.align-content-between { align-content: space-between !important; }.align-content-around { align-content: space-around !important; }.align-content-stretch { align-content: stretch !important; }.align-self-auto { align-self: auto !important; }.align-self-start { align-self: flex-start !important; }.align-self-end { align-self: flex-end !important; }.align-self-center { align-self: center !important; }.align-self-baseline { align-self: baseline !important; }.align-self-stretch { align-self: stretch !important; }@media (min-width: 576px) {\n .flex-sm-row { flex-direction: row !important; }\n .flex-sm-column { flex-direction: column !important; }\n .flex-sm-row-reverse { flex-direction: row-reverse !important; }\n .flex-sm-column-reverse { flex-direction: column-reverse !important; }\n .flex-sm-wrap { flex-wrap: wrap !important; }\n .flex-sm-nowrap { flex-wrap: nowrap !important; }\n .flex-sm-wrap-reverse { flex-wrap: wrap-reverse !important; }\n .flex-sm-fill { flex: 1 1 auto !important; }\n .flex-sm-grow-0 { flex-grow: 0 !important; }\n .flex-sm-grow-1 { flex-grow: 1 !important; }\n .flex-sm-shrink-0 { flex-shrink: 0 !important; }\n .flex-sm-shrink-1 { flex-shrink: 1 !important; }\n .justify-content-sm-start { justify-content: flex-start !important; }\n .justify-content-sm-end { justify-content: flex-end !important; }\n .justify-content-sm-center { justify-content: center !important; }\n .justify-content-sm-between { justify-content: space-between !important; }\n .justify-content-sm-around { justify-content: space-around !important; }\n .align-items-sm-start { align-items: flex-start !important; }\n .align-items-sm-end { align-items: flex-end !important; }\n .align-items-sm-center { align-items: center !important; }\n .align-items-sm-baseline { align-items: baseline !important; }\n .align-items-sm-stretch { align-items: stretch !important; }\n .align-content-sm-start { align-content: flex-start !important; }\n .align-content-sm-end { align-content: flex-end !important; }\n .align-content-sm-center { align-content: center !important; }\n .align-content-sm-between { align-content: space-between !important; }\n .align-content-sm-around { align-content: space-around !important; }\n .align-content-sm-stretch { align-content: stretch !important; }\n .align-self-sm-auto { align-self: auto !important; }\n .align-self-sm-start { align-self: flex-start !important; }\n .align-self-sm-end { align-self: flex-end !important; }\n .align-self-sm-center { align-self: center !important; }\n .align-self-sm-baseline { align-self: baseline !important; }\n .align-self-sm-stretch { align-self: stretch !important; }\n}@media (min-width: 768px) {\n .flex-md-row { flex-direction: row !important; }\n .flex-md-column { flex-direction: column !important; }\n .flex-md-row-reverse { flex-direction: row-reverse !important; }\n .flex-md-column-reverse { flex-direction: column-reverse !important; }\n .flex-md-wrap { flex-wrap: wrap !important; }\n .flex-md-nowrap { flex-wrap: nowrap !important; }\n .flex-md-wrap-reverse { flex-wrap: wrap-reverse !important; }\n .flex-md-fill { flex: 1 1 auto !important; }\n .flex-md-grow-0 { flex-grow: 0 !important; }\n .flex-md-grow-1 { flex-grow: 1 !important; }\n .flex-md-shrink-0 { flex-shrink: 0 !important; }\n .flex-md-shrink-1 { flex-shrink: 1 !important; }\n .justify-content-md-start { justify-content: flex-start !important; }\n .justify-content-md-end { justify-content: flex-end !important; }\n .justify-content-md-center { justify-content: center !important; }\n .justify-content-md-between { justify-content: space-between !important; }\n .justify-content-md-around { justify-content: space-around !important; }\n .align-items-md-start { align-items: flex-start !important; }\n .align-items-md-end { align-items: flex-end !important; }\n .align-items-md-center { align-items: center !important; }\n .align-items-md-baseline { align-items: baseline !important; }\n .align-items-md-stretch { align-items: stretch !important; }\n .align-content-md-start { align-content: flex-start !important; }\n .align-content-md-end { align-content: flex-end !important; }\n .align-content-md-center { align-content: center !important; }\n .align-content-md-between { align-content: space-between !important; }\n .align-content-md-around { align-content: space-around !important; }\n .align-content-md-stretch { align-content: stretch !important; }\n .align-self-md-auto { align-self: auto !important; }\n .align-self-md-start { align-self: flex-start !important; }\n .align-self-md-end { align-self: flex-end !important; }\n .align-self-md-center { align-self: center !important; }\n .align-self-md-baseline { align-self: baseline !important; }\n .align-self-md-stretch { align-self: stretch !important; }\n}@media (min-width: 992px) {\n .flex-lg-row { flex-direction: row !important; }\n .flex-lg-column { flex-direction: column !important; }\n .flex-lg-row-reverse { flex-direction: row-reverse !important; }\n .flex-lg-column-reverse { flex-direction: column-reverse !important; }\n .flex-lg-wrap { flex-wrap: wrap !important; }\n .flex-lg-nowrap { flex-wrap: nowrap !important; }\n .flex-lg-wrap-reverse { flex-wrap: wrap-reverse !important; }\n .flex-lg-fill { flex: 1 1 auto !important; }\n .flex-lg-grow-0 { flex-grow: 0 !important; }\n .flex-lg-grow-1 { flex-grow: 1 !important; }\n .flex-lg-shrink-0 { flex-shrink: 0 !important; }\n .flex-lg-shrink-1 { flex-shrink: 1 !important; }\n .justify-content-lg-start { justify-content: flex-start !important; }\n .justify-content-lg-end { justify-content: flex-end !important; }\n .justify-content-lg-center { justify-content: center !important; }\n .justify-content-lg-between { justify-content: space-between !important; }\n .justify-content-lg-around { justify-content: space-around !important; }\n .align-items-lg-start { align-items: flex-start !important; }\n .align-items-lg-end { align-items: flex-end !important; }\n .align-items-lg-center { align-items: center !important; }\n .align-items-lg-baseline { align-items: baseline !important; }\n .align-items-lg-stretch { align-items: stretch !important; }\n .align-content-lg-start { align-content: flex-start !important; }\n .align-content-lg-end { align-content: flex-end !important; }\n .align-content-lg-center { align-content: center !important; }\n .align-content-lg-between { align-content: space-between !important; }\n .align-content-lg-around { align-content: space-around !important; }\n .align-content-lg-stretch { align-content: stretch !important; }\n .align-self-lg-auto { align-self: auto !important; }\n .align-self-lg-start { align-self: flex-start !important; }\n .align-self-lg-end { align-self: flex-end !important; }\n .align-self-lg-center { align-self: center !important; }\n .align-self-lg-baseline { align-self: baseline !important; }\n .align-self-lg-stretch { align-self: stretch !important; }\n}@media (min-width: 1200px) {\n .flex-xl-row { flex-direction: row !important; }\n .flex-xl-column { flex-direction: column !important; }\n .flex-xl-row-reverse { flex-direction: row-reverse !important; }\n .flex-xl-column-reverse { flex-direction: column-reverse !important; }\n .flex-xl-wrap { flex-wrap: wrap !important; }\n .flex-xl-nowrap { flex-wrap: nowrap !important; }\n .flex-xl-wrap-reverse { flex-wrap: wrap-reverse !important; }\n .flex-xl-fill { flex: 1 1 auto !important; }\n .flex-xl-grow-0 { flex-grow: 0 !important; }\n .flex-xl-grow-1 { flex-grow: 1 !important; }\n .flex-xl-shrink-0 { flex-shrink: 0 !important; }\n .flex-xl-shrink-1 { flex-shrink: 1 !important; }\n .justify-content-xl-start { justify-content: flex-start !important; }\n .justify-content-xl-end { justify-content: flex-end !important; }\n .justify-content-xl-center { justify-content: center !important; }\n .justify-content-xl-between { justify-content: space-between !important; }\n .justify-content-xl-around { justify-content: space-around !important; }\n .align-items-xl-start { align-items: flex-start !important; }\n .align-items-xl-end { align-items: flex-end !important; }\n .align-items-xl-center { align-items: center !important; }\n .align-items-xl-baseline { align-items: baseline !important; }\n .align-items-xl-stretch { align-items: stretch !important; }\n .align-content-xl-start { align-content: flex-start !important; }\n .align-content-xl-end { align-content: flex-end !important; }\n .align-content-xl-center { align-content: center !important; }\n .align-content-xl-between { align-content: space-between !important; }\n .align-content-xl-around { align-content: space-around !important; }\n .align-content-xl-stretch { align-content: stretch !important; }\n .align-self-xl-auto { align-self: auto !important; }\n .align-self-xl-start { align-self: flex-start !important; }\n .align-self-xl-end { align-self: flex-end !important; }\n .align-self-xl-center { align-self: center !important; }\n .align-self-xl-baseline { align-self: baseline !important; }\n .align-self-xl-stretch { align-self: stretch !important; }\n}.float-left { float: left !important; }.float-right { float: right !important; }.float-none { float: none !important; }@media (min-width: 576px) {\n .float-sm-left { float: left !important; }\n .float-sm-right { float: right !important; }\n .float-sm-none { float: none !important; }\n}@media (min-width: 768px) {\n .float-md-left { float: left !important; }\n .float-md-right { float: right !important; }\n .float-md-none { float: none !important; }\n}@media (min-width: 992px) {\n .float-lg-left { float: left !important; }\n .float-lg-right { float: right !important; }\n .float-lg-none { float: none !important; }\n}@media (min-width: 1200px) {\n .float-xl-left { float: left !important; }\n .float-xl-right { float: right !important; }\n .float-xl-none { float: none !important; }\n}.position-static { position: static !important; }.position-relative { position: relative !important; }.position-absolute { position: absolute !important; }.position-fixed { position: fixed !important; }.position-sticky { position: sticky !important; }.fixed-top { position: fixed; top: 0px; right: 0px; left: 0px; z-index: 1030; }.fixed-bottom { position: fixed; right: 0px; bottom: 0px; left: 0px; z-index: 1030; }@supports ((position:-webkit-sticky) or (position:sticky)) {\n .sticky-top { position: sticky; top: 0px; z-index: 1020; }\n}.sr-only { position: absolute; width: 1px; height: 1px; padding: 0px; overflow: hidden; clip: rect(0px, 0px, 0px, 0px); white-space: nowrap; border: 0px; }.sr-only-focusable:active, .sr-only-focusable:focus { position: static; width: auto; height: auto; overflow: visible; clip: auto; white-space: normal; }.shadow-sm { box-shadow: rgba(0, 0, 0, 0.075) 0px 0.125rem 0.25rem !important; }.shadow { box-shadow: rgba(0, 0, 0, 0.15) 0px 0.5rem 1rem !important; }.shadow-lg { box-shadow: rgba(0, 0, 0, 0.176) 0px 1rem 3rem !important; }.shadow-none { box-shadow: none !important; }.w-25 { width: 25% !important; }.w-50 { width: 50% !important; }.w-75 { width: 75% !important; }.w-100 { width: 100% !important; }.w-auto { width: auto !important; }.h-25 { height: 25% !important; }.h-50 { height: 50% !important; }.h-75 { height: 75% !important; }.h-100 { height: 100% !important; }.h-auto { height: auto !important; }.mw-100 { max-width: 100% !important; }.mh-100 { max-height: 100% !important; }.m-0 { margin: 0px !important; }.mt-0, .my-0 { margin-top: 0px !important; }.mr-0, .mx-0 { margin-right: 0px !important; }.mb-0, .my-0 { margin-bottom: 0px !important; }.ml-0, .mx-0 { margin-left: 0px !important; }.m-1 { margin: 0.25rem !important; }.mt-1, .my-1 { margin-top: 0.25rem !important; }.mr-1, .mx-1 { margin-right: 0.25rem !important; }.mb-1, .my-1 { margin-bottom: 0.25rem !important; }.ml-1, .mx-1 { margin-left: 0.25rem !important; }.m-2 { margin: 0.5rem !important; }.mt-2, .my-2 { margin-top: 0.5rem !important; }.mr-2, .mx-2 { margin-right: 0.5rem !important; }.mb-2, .my-2 { margin-bottom: 0.5rem !important; }.ml-2, .mx-2 { margin-left: 0.5rem !important; }.m-3 { margin: 1rem !important; }.mt-3, .my-3 { margin-top: 1rem !important; }.mr-3, .mx-3 { margin-right: 1rem !important; }.mb-3, .my-3 { margin-bottom: 1rem !important; }.ml-3, .mx-3 { margin-left: 1rem !important; }.m-4 { margin: 1.5rem !important; }.mt-4, .my-4 { margin-top: 1.5rem !important; }.mr-4, .mx-4 { margin-right: 1.5rem !important; }.mb-4, .my-4 { margin-bottom: 1.5rem !important; }.ml-4, .mx-4 { margin-left: 1.5rem !important; }.m-5 { margin: 3rem !important; }.mt-5, .my-5 { margin-top: 3rem !important; }.mr-5, .mx-5 { margin-right: 3rem !important; }.mb-5, .my-5 { margin-bottom: 3rem !important; }.ml-5, .mx-5 { margin-left: 3rem !important; }.p-0 { padding: 0px !important; }.pt-0, .py-0 { padding-top: 0px !important; }.pr-0, .px-0 { padding-right: 0px !important; }.pb-0, .py-0 { padding-bottom: 0px !important; }.pl-0, .px-0 { padding-left: 0px !important; }.p-1 { padding: 0.25rem !important; }.pt-1, .py-1 { padding-top: 0.25rem !important; }.pr-1, .px-1 { padding-right: 0.25rem !important; }.pb-1, .py-1 { padding-bottom: 0.25rem !important; }.pl-1, .px-1 { padding-left: 0.25rem !important; }.p-2 { padding: 0.5rem !important; }.pt-2, .py-2 { padding-top: 0.5rem !important; }.pr-2, .px-2 { padding-right: 0.5rem !important; }.pb-2, .py-2 { padding-bottom: 0.5rem !important; }.pl-2, .px-2 { padding-left: 0.5rem !important; }.p-3 { padding: 1rem !important; }.pt-3, .py-3 { padding-top: 1rem !important; }.pr-3, .px-3 { padding-right: 1rem !important; }.pb-3, .py-3 { padding-bottom: 1rem !important; }.pl-3, .px-3 { padding-left: 1rem !important; }.p-4 { padding: 1.5rem !important; }.pt-4, .py-4 { padding-top: 1.5rem !important; }.pr-4, .px-4 { padding-right: 1.5rem !important; }.pb-4, .py-4 { padding-bottom: 1.5rem !important; }.pl-4, .px-4 { padding-left: 1.5rem !important; }.p-5 { padding: 3rem !important; }.pt-5, .py-5 { padding-top: 3rem !important; }.pr-5, .px-5 { padding-right: 3rem !important; }.pb-5, .py-5 { padding-bottom: 3rem !important; }.pl-5, .px-5 { padding-left: 3rem !important; }.m-auto { margin: auto !important; }.mt-auto, .my-auto { margin-top: auto !important; }.mr-auto, .mx-auto { margin-right: auto !important; }.mb-auto, .my-auto { margin-bottom: auto !important; }.ml-auto, .mx-auto { margin-left: auto !important; }@media (min-width: 576px) {\n .m-sm-0 { margin: 0px !important; }\n .mt-sm-0, .my-sm-0 { margin-top: 0px !important; }\n .mr-sm-0, .mx-sm-0 { margin-right: 0px !important; }\n .mb-sm-0, .my-sm-0 { margin-bottom: 0px !important; }\n .ml-sm-0, .mx-sm-0 { margin-left: 0px !important; }\n .m-sm-1 { margin: 0.25rem !important; }\n .mt-sm-1, .my-sm-1 { margin-top: 0.25rem !important; }\n .mr-sm-1, .mx-sm-1 { margin-right: 0.25rem !important; }\n .mb-sm-1, .my-sm-1 { margin-bottom: 0.25rem !important; }\n .ml-sm-1, .mx-sm-1 { margin-left: 0.25rem !important; }\n .m-sm-2 { margin: 0.5rem !important; }\n .mt-sm-2, .my-sm-2 { margin-top: 0.5rem !important; }\n .mr-sm-2, .mx-sm-2 { margin-right: 0.5rem !important; }\n .mb-sm-2, .my-sm-2 { margin-bottom: 0.5rem !important; }\n .ml-sm-2, .mx-sm-2 { margin-left: 0.5rem !important; }\n .m-sm-3 { margin: 1rem !important; }\n .mt-sm-3, .my-sm-3 { margin-top: 1rem !important; }\n .mr-sm-3, .mx-sm-3 { margin-right: 1rem !important; }\n .mb-sm-3, .my-sm-3 { margin-bottom: 1rem !important; }\n .ml-sm-3, .mx-sm-3 { margin-left: 1rem !important; }\n .m-sm-4 { margin: 1.5rem !important; }\n .mt-sm-4, .my-sm-4 { margin-top: 1.5rem !important; }\n .mr-sm-4, .mx-sm-4 { margin-right: 1.5rem !important; }\n .mb-sm-4, .my-sm-4 { margin-bottom: 1.5rem !important; }\n .ml-sm-4, .mx-sm-4 { margin-left: 1.5rem !important; }\n .m-sm-5 { margin: 3rem !important; }\n .mt-sm-5, .my-sm-5 { margin-top: 3rem !important; }\n .mr-sm-5, .mx-sm-5 { margin-right: 3rem !important; }\n .mb-sm-5, .my-sm-5 { margin-bottom: 3rem !important; }\n .ml-sm-5, .mx-sm-5 { margin-left: 3rem !important; }\n .p-sm-0 { padding: 0px !important; }\n .pt-sm-0, .py-sm-0 { padding-top: 0px !important; }\n .pr-sm-0, .px-sm-0 { padding-right: 0px !important; }\n .pb-sm-0, .py-sm-0 { padding-bottom: 0px !important; }\n .pl-sm-0, .px-sm-0 { padding-left: 0px !important; }\n .p-sm-1 { padding: 0.25rem !important; }\n .pt-sm-1, .py-sm-1 { padding-top: 0.25rem !important; }\n .pr-sm-1, .px-sm-1 { padding-right: 0.25rem !important; }\n .pb-sm-1, .py-sm-1 { padding-bottom: 0.25rem !important; }\n .pl-sm-1, .px-sm-1 { padding-left: 0.25rem !important; }\n .p-sm-2 { padding: 0.5rem !important; }\n .pt-sm-2, .py-sm-2 { padding-top: 0.5rem !important; }\n .pr-sm-2, .px-sm-2 { padding-right: 0.5rem !important; }\n .pb-sm-2, .py-sm-2 { padding-bottom: 0.5rem !important; }\n .pl-sm-2, .px-sm-2 { padding-left: 0.5rem !important; }\n .p-sm-3 { padding: 1rem !important; }\n .pt-sm-3, .py-sm-3 { padding-top: 1rem !important; }\n .pr-sm-3, .px-sm-3 { padding-right: 1rem !important; }\n .pb-sm-3, .py-sm-3 { padding-bottom: 1rem !important; }\n .pl-sm-3, .px-sm-3 { padding-left: 1rem !important; }\n .p-sm-4 { padding: 1.5rem !important; }\n .pt-sm-4, .py-sm-4 { padding-top: 1.5rem !important; }\n .pr-sm-4, .px-sm-4 { padding-right: 1.5rem !important; }\n .pb-sm-4, .py-sm-4 { padding-bottom: 1.5rem !important; }\n .pl-sm-4, .px-sm-4 { padding-left: 1.5rem !important; }\n .p-sm-5 { padding: 3rem !important; }\n .pt-sm-5, .py-sm-5 { padding-top: 3rem !important; }\n .pr-sm-5, .px-sm-5 { padding-right: 3rem !important; }\n .pb-sm-5, .py-sm-5 { padding-bottom: 3rem !important; }\n .pl-sm-5, .px-sm-5 { padding-left: 3rem !important; }\n .m-sm-auto { margin: auto !important; }\n .mt-sm-auto, .my-sm-auto { margin-top: auto !important; }\n .mr-sm-auto, .mx-sm-auto { margin-right: auto !important; }\n .mb-sm-auto, .my-sm-auto { margin-bottom: auto !important; }\n .ml-sm-auto, .mx-sm-auto { margin-left: auto !important; }\n}@media (min-width: 768px) {\n .m-md-0 { margin: 0px !important; }\n .mt-md-0, .my-md-0 { margin-top: 0px !important; }\n .mr-md-0, .mx-md-0 { margin-right: 0px !important; }\n .mb-md-0, .my-md-0 { margin-bottom: 0px !important; }\n .ml-md-0, .mx-md-0 { margin-left: 0px !important; }\n .m-md-1 { margin: 0.25rem !important; }\n .mt-md-1, .my-md-1 { margin-top: 0.25rem !important; }\n .mr-md-1, .mx-md-1 { margin-right: 0.25rem !important; }\n .mb-md-1, .my-md-1 { margin-bottom: 0.25rem !important; }\n .ml-md-1, .mx-md-1 { margin-left: 0.25rem !important; }\n .m-md-2 { margin: 0.5rem !important; }\n .mt-md-2, .my-md-2 { margin-top: 0.5rem !important; }\n .mr-md-2, .mx-md-2 { margin-right: 0.5rem !important; }\n .mb-md-2, .my-md-2 { margin-bottom: 0.5rem !important; }\n .ml-md-2, .mx-md-2 { margin-left: 0.5rem !important; }\n .m-md-3 { margin: 1rem !important; }\n .mt-md-3, .my-md-3 { margin-top: 1rem !important; }\n .mr-md-3, .mx-md-3 { margin-right: 1rem !important; }\n .mb-md-3, .my-md-3 { margin-bottom: 1rem !important; }\n .ml-md-3, .mx-md-3 { margin-left: 1rem !important; }\n .m-md-4 { margin: 1.5rem !important; }\n .mt-md-4, .my-md-4 { margin-top: 1.5rem !important; }\n .mr-md-4, .mx-md-4 { margin-right: 1.5rem !important; }\n .mb-md-4, .my-md-4 { margin-bottom: 1.5rem !important; }\n .ml-md-4, .mx-md-4 { margin-left: 1.5rem !important; }\n .m-md-5 { margin: 3rem !important; }\n .mt-md-5, .my-md-5 { margin-top: 3rem !important; }\n .mr-md-5, .mx-md-5 { margin-right: 3rem !important; }\n .mb-md-5, .my-md-5 { margin-bottom: 3rem !important; }\n .ml-md-5, .mx-md-5 { margin-left: 3rem !important; }\n .p-md-0 { padding: 0px !important; }\n .pt-md-0, .py-md-0 { padding-top: 0px !important; }\n .pr-md-0, .px-md-0 { padding-right: 0px !important; }\n .pb-md-0, .py-md-0 { padding-bottom: 0px !important; }\n .pl-md-0, .px-md-0 { padding-left: 0px !important; }\n .p-md-1 { padding: 0.25rem !important; }\n .pt-md-1, .py-md-1 { padding-top: 0.25rem !important; }\n .pr-md-1, .px-md-1 { padding-right: 0.25rem !important; }\n .pb-md-1, .py-md-1 { padding-bottom: 0.25rem !important; }\n .pl-md-1, .px-md-1 { padding-left: 0.25rem !important; }\n .p-md-2 { padding: 0.5rem !important; }\n .pt-md-2, .py-md-2 { padding-top: 0.5rem !important; }\n .pr-md-2, .px-md-2 { padding-right: 0.5rem !important; }\n .pb-md-2, .py-md-2 { padding-bottom: 0.5rem !important; }\n .pl-md-2, .px-md-2 { padding-left: 0.5rem !important; }\n .p-md-3 { padding: 1rem !important; }\n .pt-md-3, .py-md-3 { padding-top: 1rem !important; }\n .pr-md-3, .px-md-3 { padding-right: 1rem !important; }\n .pb-md-3, .py-md-3 { padding-bottom: 1rem !important; }\n .pl-md-3, .px-md-3 { padding-left: 1rem !important; }\n .p-md-4 { padding: 1.5rem !important; }\n .pt-md-4, .py-md-4 { padding-top: 1.5rem !important; }\n .pr-md-4, .px-md-4 { padding-right: 1.5rem !important; }\n .pb-md-4, .py-md-4 { padding-bottom: 1.5rem !important; }\n .pl-md-4, .px-md-4 { padding-left: 1.5rem !important; }\n .p-md-5 { padding: 3rem !important; }\n .pt-md-5, .py-md-5 { padding-top: 3rem !important; }\n .pr-md-5, .px-md-5 { padding-right: 3rem !important; }\n .pb-md-5, .py-md-5 { padding-bottom: 3rem !important; }\n .pl-md-5, .px-md-5 { padding-left: 3rem !important; }\n .m-md-auto { margin: auto !important; }\n .mt-md-auto, .my-md-auto { margin-top: auto !important; }\n .mr-md-auto, .mx-md-auto { margin-right: auto !important; }\n .mb-md-auto, .my-md-auto { margin-bottom: auto !important; }\n .ml-md-auto, .mx-md-auto { margin-left: auto !important; }\n}@media (min-width: 992px) {\n .m-lg-0 { margin: 0px !important; }\n .mt-lg-0, .my-lg-0 { margin-top: 0px !important; }\n .mr-lg-0, .mx-lg-0 { margin-right: 0px !important; }\n .mb-lg-0, .my-lg-0 { margin-bottom: 0px !important; }\n .ml-lg-0, .mx-lg-0 { margin-left: 0px !important; }\n .m-lg-1 { margin: 0.25rem !important; }\n .mt-lg-1, .my-lg-1 { margin-top: 0.25rem !important; }\n .mr-lg-1, .mx-lg-1 { margin-right: 0.25rem !important; }\n .mb-lg-1, .my-lg-1 { margin-bottom: 0.25rem !important; }\n .ml-lg-1, .mx-lg-1 { margin-left: 0.25rem !important; }\n .m-lg-2 { margin: 0.5rem !important; }\n .mt-lg-2, .my-lg-2 { margin-top: 0.5rem !important; }\n .mr-lg-2, .mx-lg-2 { margin-right: 0.5rem !important; }\n .mb-lg-2, .my-lg-2 { margin-bottom: 0.5rem !important; }\n .ml-lg-2, .mx-lg-2 { margin-left: 0.5rem !important; }\n .m-lg-3 { margin: 1rem !important; }\n .mt-lg-3, .my-lg-3 { margin-top: 1rem !important; }\n .mr-lg-3, .mx-lg-3 { margin-right: 1rem !important; }\n .mb-lg-3, .my-lg-3 { margin-bottom: 1rem !important; }\n .ml-lg-3, .mx-lg-3 { margin-left: 1rem !important; }\n .m-lg-4 { margin: 1.5rem !important; }\n .mt-lg-4, .my-lg-4 { margin-top: 1.5rem !important; }\n .mr-lg-4, .mx-lg-4 { margin-right: 1.5rem !important; }\n .mb-lg-4, .my-lg-4 { margin-bottom: 1.5rem !important; }\n .ml-lg-4, .mx-lg-4 { margin-left: 1.5rem !important; }\n .m-lg-5 { margin: 3rem !important; }\n .mt-lg-5, .my-lg-5 { margin-top: 3rem !important; }\n .mr-lg-5, .mx-lg-5 { margin-right: 3rem !important; }\n .mb-lg-5, .my-lg-5 { margin-bottom: 3rem !important; }\n .ml-lg-5, .mx-lg-5 { margin-left: 3rem !important; }\n .p-lg-0 { padding: 0px !important; }\n .pt-lg-0, .py-lg-0 { padding-top: 0px !important; }\n .pr-lg-0, .px-lg-0 { padding-right: 0px !important; }\n .pb-lg-0, .py-lg-0 { padding-bottom: 0px !important; }\n .pl-lg-0, .px-lg-0 { padding-left: 0px !important; }\n .p-lg-1 { padding: 0.25rem !important; }\n .pt-lg-1, .py-lg-1 { padding-top: 0.25rem !important; }\n .pr-lg-1, .px-lg-1 { padding-right: 0.25rem !important; }\n .pb-lg-1, .py-lg-1 { padding-bottom: 0.25rem !important; }\n .pl-lg-1, .px-lg-1 { padding-left: 0.25rem !important; }\n .p-lg-2 { padding: 0.5rem !important; }\n .pt-lg-2, .py-lg-2 { padding-top: 0.5rem !important; }\n .pr-lg-2, .px-lg-2 { padding-right: 0.5rem !important; }\n .pb-lg-2, .py-lg-2 { padding-bottom: 0.5rem !important; }\n .pl-lg-2, .px-lg-2 { padding-left: 0.5rem !important; }\n .p-lg-3 { padding: 1rem !important; }\n .pt-lg-3, .py-lg-3 { padding-top: 1rem !important; }\n .pr-lg-3, .px-lg-3 { padding-right: 1rem !important; }\n .pb-lg-3, .py-lg-3 { padding-bottom: 1rem !important; }\n .pl-lg-3, .px-lg-3 { padding-left: 1rem !important; }\n .p-lg-4 { padding: 1.5rem !important; }\n .pt-lg-4, .py-lg-4 { padding-top: 1.5rem !important; }\n .pr-lg-4, .px-lg-4 { padding-right: 1.5rem !important; }\n .pb-lg-4, .py-lg-4 { padding-bottom: 1.5rem !important; }\n .pl-lg-4, .px-lg-4 { padding-left: 1.5rem !important; }\n .p-lg-5 { padding: 3rem !important; }\n .pt-lg-5, .py-lg-5 { padding-top: 3rem !important; }\n .pr-lg-5, .px-lg-5 { padding-right: 3rem !important; }\n .pb-lg-5, .py-lg-5 { padding-bottom: 3rem !important; }\n .pl-lg-5, .px-lg-5 { padding-left: 3rem !important; }\n .m-lg-auto { margin: auto !important; }\n .mt-lg-auto, .my-lg-auto { margin-top: auto !important; }\n .mr-lg-auto, .mx-lg-auto { margin-right: auto !important; }\n .mb-lg-auto, .my-lg-auto { margin-bottom: auto !important; }\n .ml-lg-auto, .mx-lg-auto { margin-left: auto !important; }\n}@media (min-width: 1200px) {\n .m-xl-0 { margin: 0px !important; }\n .mt-xl-0, .my-xl-0 { margin-top: 0px !important; }\n .mr-xl-0, .mx-xl-0 { margin-right: 0px !important; }\n .mb-xl-0, .my-xl-0 { margin-bottom: 0px !important; }\n .ml-xl-0, .mx-xl-0 { margin-left: 0px !important; }\n .m-xl-1 { margin: 0.25rem !important; }\n .mt-xl-1, .my-xl-1 { margin-top: 0.25rem !important; }\n .mr-xl-1, .mx-xl-1 { margin-right: 0.25rem !important; }\n .mb-xl-1, .my-xl-1 { margin-bottom: 0.25rem !important; }\n .ml-xl-1, .mx-xl-1 { margin-left: 0.25rem !important; }\n .m-xl-2 { margin: 0.5rem !important; }\n .mt-xl-2, .my-xl-2 { margin-top: 0.5rem !important; }\n .mr-xl-2, .mx-xl-2 { margin-right: 0.5rem !important; }\n .mb-xl-2, .my-xl-2 { margin-bottom: 0.5rem !important; }\n .ml-xl-2, .mx-xl-2 { margin-left: 0.5rem !important; }\n .m-xl-3 { margin: 1rem !important; }\n .mt-xl-3, .my-xl-3 { margin-top: 1rem !important; }\n .mr-xl-3, .mx-xl-3 { margin-right: 1rem !important; }\n .mb-xl-3, .my-xl-3 { margin-bottom: 1rem !important; }\n .ml-xl-3, .mx-xl-3 { margin-left: 1rem !important; }\n .m-xl-4 { margin: 1.5rem !important; }\n .mt-xl-4, .my-xl-4 { margin-top: 1.5rem !important; }\n .mr-xl-4, .mx-xl-4 { margin-right: 1.5rem !important; }\n .mb-xl-4, .my-xl-4 { margin-bottom: 1.5rem !important; }\n .ml-xl-4, .mx-xl-4 { margin-left: 1.5rem !important; }\n .m-xl-5 { margin: 3rem !important; }\n .mt-xl-5, .my-xl-5 { margin-top: 3rem !important; }\n .mr-xl-5, .mx-xl-5 { margin-right: 3rem !important; }\n .mb-xl-5, .my-xl-5 { margin-bottom: 3rem !important; }\n .ml-xl-5, .mx-xl-5 { margin-left: 3rem !important; }\n .p-xl-0 { padding: 0px !important; }\n .pt-xl-0, .py-xl-0 { padding-top: 0px !important; }\n .pr-xl-0, .px-xl-0 { padding-right: 0px !important; }\n .pb-xl-0, .py-xl-0 { padding-bottom: 0px !important; }\n .pl-xl-0, .px-xl-0 { padding-left: 0px !important; }\n .p-xl-1 { padding: 0.25rem !important; }\n .pt-xl-1, .py-xl-1 { padding-top: 0.25rem !important; }\n .pr-xl-1, .px-xl-1 { padding-right: 0.25rem !important; }\n .pb-xl-1, .py-xl-1 { padding-bottom: 0.25rem !important; }\n .pl-xl-1, .px-xl-1 { padding-left: 0.25rem !important; }\n .p-xl-2 { padding: 0.5rem !important; }\n .pt-xl-2, .py-xl-2 { padding-top: 0.5rem !important; }\n .pr-xl-2, .px-xl-2 { padding-right: 0.5rem !important; }\n .pb-xl-2, .py-xl-2 { padding-bottom: 0.5rem !important; }\n .pl-xl-2, .px-xl-2 { padding-left: 0.5rem !important; }\n .p-xl-3 { padding: 1rem !important; }\n .pt-xl-3, .py-xl-3 { padding-top: 1rem !important; }\n .pr-xl-3, .px-xl-3 { padding-right: 1rem !important; }\n .pb-xl-3, .py-xl-3 { padding-bottom: 1rem !important; }\n .pl-xl-3, .px-xl-3 { padding-left: 1rem !important; }\n .p-xl-4 { padding: 1.5rem !important; }\n .pt-xl-4, .py-xl-4 { padding-top: 1.5rem !important; }\n .pr-xl-4, .px-xl-4 { padding-right: 1.5rem !important; }\n .pb-xl-4, .py-xl-4 { padding-bottom: 1.5rem !important; }\n .pl-xl-4, .px-xl-4 { padding-left: 1.5rem !important; }\n .p-xl-5 { padding: 3rem !important; }\n .pt-xl-5, .py-xl-5 { padding-top: 3rem !important; }\n .pr-xl-5, .px-xl-5 { padding-right: 3rem !important; }\n .pb-xl-5, .py-xl-5 { padding-bottom: 3rem !important; }\n .pl-xl-5, .px-xl-5 { padding-left: 3rem !important; }\n .m-xl-auto { margin: auto !important; }\n .mt-xl-auto, .my-xl-auto { margin-top: auto !important; }\n .mr-xl-auto, .mx-xl-auto { margin-right: auto !important; }\n .mb-xl-auto, .my-xl-auto { margin-bottom: auto !important; }\n .ml-xl-auto, .mx-xl-auto { margin-left: auto !important; }\n}.text-monospace { font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; }.text-justify { text-align: justify !important; }.text-nowrap { white-space: nowrap !important; }.text-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }.text-left { text-align: left !important; }.text-right { text-align: right !important; }.text-center { text-align: center !important; }@media (min-width: 576px) {\n .text-sm-left { text-align: left !important; }\n .text-sm-right { text-align: right !important; }\n .text-sm-center { text-align: center !important; }\n}@media (min-width: 768px) {\n .text-md-left { text-align: left !important; }\n .text-md-right { text-align: right !important; }\n .text-md-center { text-align: center !important; }\n}@media (min-width: 992px) {\n .text-lg-left { text-align: left !important; }\n .text-lg-right { text-align: right !important; }\n .text-lg-center { text-align: center !important; }\n}@media (min-width: 1200px) {\n .text-xl-left { text-align: left !important; }\n .text-xl-right { text-align: right !important; }\n .text-xl-center { text-align: center !important; }\n}.text-lowercase { text-transform: lowercase !important; }.text-uppercase { text-transform: uppercase !important; }.text-capitalize { text-transform: capitalize !important; }.font-weight-light { font-weight: 300 !important; }.font-weight-normal { font-weight: 400 !important; }.font-weight-bold { font-weight: 700 !important; }.font-italic { font-style: italic !important; }.text-white { color: rgb(255, 255, 255) !important; }.text-primary { color: rgb(0, 123, 255) !important; }a.text-primary:focus, a.text-primary:hover { color: rgb(0, 98, 204) !important; }.text-secondary { color: rgb(108, 117, 125) !important; }a.text-secondary:focus, a.text-secondary:hover { color: rgb(84, 91, 98) !important; }.text-success { color: rgb(40, 167, 69) !important; }a.text-success:focus, a.text-success:hover { color: rgb(30, 126, 52) !important; }.text-info { color: rgb(23, 162, 184) !important; }a.text-info:focus, a.text-info:hover { color: rgb(17, 122, 139) !important; }.text-warning { color: rgb(255, 193, 7) !important; }a.text-warning:focus, a.text-warning:hover { color: rgb(211, 158, 0) !important; }.text-danger { color: rgb(220, 53, 69) !important; }a.text-danger:focus, a.text-danger:hover { color: rgb(189, 33, 48) !important; }.text-light { color: rgb(248, 249, 250) !important; }a.text-light:focus, a.text-light:hover { color: rgb(218, 224, 229) !important; }.text-dark { color: rgb(52, 58, 64) !important; }a.text-dark:focus, a.text-dark:hover { color: rgb(29, 33, 36) !important; }.text-body { color: rgb(33, 37, 41) !important; }.text-muted { color: rgb(108, 117, 125) !important; }.text-black-50 { color: rgba(0, 0, 0, 0.5) !important; }.text-white-50 { color: rgba(255, 255, 255, 0.5) !important; }.text-hide { font: 0px/0 a; color: transparent; text-shadow: none; background-color: transparent; border: 0px; }.visible { visibility: visible !important; }.invisible { visibility: hidden !important; }@media print {\n *, ::after, ::before { text-shadow: none !important; box-shadow: none !important; }\n a:not(.btn) { text-decoration: underline; }\n abbr[title]::after { content: \" (\" attr(title) \")\"; }\n pre { white-space: pre-wrap !important; }\n blockquote, pre { border: 1px solid rgb(173, 181, 189); break-inside: avoid; }\n thead { display: table-header-group; }\n img, tr { break-inside: avoid; }\n h2, h3, p { orphans: 3; widows: 3; }\n h2, h3 { break-after: avoid; }\n @page { size: a3; }\n body { min-width: 992px !important; }\n .container { min-width: 992px !important; }\n .navbar { display: none; }\n .badge { border: 1px solid rgb(0, 0, 0); }\n .table { border-collapse: collapse !important; }\n .table td, .table th { background-color: rgb(255, 255, 255) !important; }\n .table-bordered td, .table-bordered th { border: 1px solid rgb(222, 226, 230) !important; }\n .table-dark { color: inherit; }\n .table-dark tbody + tbody, .table-dark td, .table-dark th, .table-dark thead th { border-color: rgb(222, 226, 230); }\n .table .thead-dark th { color: inherit; border-color: rgb(222, 226, 230); }\n}"},"childNodes":[],"id":22},{"type":3,"textContent":"\n\n ","id":23},{"type":5,"textContent":" Custom styles for this template ","id":24},{"type":3,"textContent":"\n ","id":25},{"type":2,"tagName":"link","attributes":{"_cssText":".container { max-width: 960px; }.lh-condensed { line-height: 1.25; }"},"childNodes":[],"id":26},{"type":3,"textContent":"\n","id":27}],"id":5},{"type":3,"textContent":"\n\n","id":28},{"type":2,"tagName":"body","attributes":{"class":"bg-light"},"childNodes":[{"type":3,"textContent":"\n\n ","id":30},{"type":2,"tagName":"div","attributes":{"class":"container"},"childNodes":[{"type":3,"textContent":"\n ","id":32},{"type":2,"tagName":"div","attributes":{"class":"py-5 text-center"},"childNodes":[{"type":3,"textContent":"\n ","id":34},{"type":2,"tagName":"img","attributes":{"class":"d-block mx-auto mb-4","src":"http://localhost:5500/checkout-demo/index_files/bootstrap-solid.svg","alt":"","width":"72","height":"72"},"childNodes":[],"id":35},{"type":3,"textContent":"\n ","id":36},{"type":2,"tagName":"h2","attributes":{},"childNodes":[{"type":3,"textContent":"Checkout form","id":38}],"id":37},{"type":3,"textContent":"\n ","id":39},{"type":2,"tagName":"p","attributes":{"class":"lead"},"childNodes":[{"type":3,"textContent":"Below is an example form built entirely with Bootstrap's form controls. Each required form group\n has\n a validation state that can be triggered by attempting to submit the form without completing it.","id":41}],"id":40},{"type":3,"textContent":"\n ","id":42}],"id":33},{"type":3,"textContent":"\n\n ","id":43},{"type":2,"tagName":"div","attributes":{"class":"row"},"childNodes":[{"type":3,"textContent":"\n ","id":45},{"type":2,"tagName":"div","attributes":{"class":"col-md-4 order-md-2 mb-4"},"childNodes":[{"type":3,"textContent":"\n ","id":47},{"type":2,"tagName":"h4","attributes":{"class":"d-flex justify-content-between align-items-center mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":49},{"type":2,"tagName":"span","attributes":{"class":"text-muted"},"childNodes":[{"type":3,"textContent":"Your cart","id":51}],"id":50},{"type":3,"textContent":"\n ","id":52},{"type":2,"tagName":"span","attributes":{"class":"badge badge-secondary badge-pill"},"childNodes":[{"type":3,"textContent":"3","id":54}],"id":53},{"type":3,"textContent":"\n ","id":55}],"id":48},{"type":3,"textContent":"\n ","id":56},{"type":2,"tagName":"ul","attributes":{"class":"list-group mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":58},{"type":2,"tagName":"li","attributes":{"class":"list-group-item d-flex justify-content-between lh-condensed"},"childNodes":[{"type":3,"textContent":"\n ","id":60},{"type":2,"tagName":"div","attributes":{},"childNodes":[{"type":3,"textContent":"\n ","id":62},{"type":2,"tagName":"h6","attributes":{"class":"my-0"},"childNodes":[{"type":3,"textContent":"Product name","id":64}],"id":63},{"type":3,"textContent":"\n ","id":65},{"type":2,"tagName":"small","attributes":{"class":"text-muted"},"childNodes":[{"type":3,"textContent":"Brief description","id":67}],"id":66},{"type":3,"textContent":"\n ","id":68}],"id":61},{"type":3,"textContent":"\n ","id":69},{"type":2,"tagName":"span","attributes":{"class":"text-muted"},"childNodes":[{"type":3,"textContent":"$12","id":71}],"id":70},{"type":3,"textContent":"\n ","id":72}],"id":59},{"type":3,"textContent":"\n ","id":73},{"type":2,"tagName":"li","attributes":{"class":"list-group-item d-flex justify-content-between lh-condensed"},"childNodes":[{"type":3,"textContent":"\n ","id":75},{"type":2,"tagName":"div","attributes":{},"childNodes":[{"type":3,"textContent":"\n ","id":77},{"type":2,"tagName":"h6","attributes":{"class":"my-0"},"childNodes":[{"type":3,"textContent":"Second product","id":79}],"id":78},{"type":3,"textContent":"\n ","id":80},{"type":2,"tagName":"small","attributes":{"class":"text-muted"},"childNodes":[{"type":3,"textContent":"Brief description","id":82}],"id":81},{"type":3,"textContent":"\n ","id":83}],"id":76},{"type":3,"textContent":"\n ","id":84},{"type":2,"tagName":"span","attributes":{"class":"text-muted"},"childNodes":[{"type":3,"textContent":"$8","id":86}],"id":85},{"type":3,"textContent":"\n ","id":87}],"id":74},{"type":3,"textContent":"\n ","id":88},{"type":2,"tagName":"li","attributes":{"class":"list-group-item d-flex justify-content-between lh-condensed"},"childNodes":[{"type":3,"textContent":"\n ","id":90},{"type":2,"tagName":"div","attributes":{},"childNodes":[{"type":3,"textContent":"\n ","id":92},{"type":2,"tagName":"h6","attributes":{"class":"my-0"},"childNodes":[{"type":3,"textContent":"Third item","id":94}],"id":93},{"type":3,"textContent":"\n ","id":95},{"type":2,"tagName":"small","attributes":{"class":"text-muted"},"childNodes":[{"type":3,"textContent":"Brief description","id":97}],"id":96},{"type":3,"textContent":"\n ","id":98}],"id":91},{"type":3,"textContent":"\n ","id":99},{"type":2,"tagName":"span","attributes":{"class":"text-muted"},"childNodes":[{"type":3,"textContent":"$5","id":101}],"id":100},{"type":3,"textContent":"\n ","id":102}],"id":89},{"type":3,"textContent":"\n ","id":103},{"type":2,"tagName":"li","attributes":{"class":"list-group-item d-flex justify-content-between bg-light"},"childNodes":[{"type":3,"textContent":"\n ","id":105},{"type":2,"tagName":"div","attributes":{"class":"text-success"},"childNodes":[{"type":3,"textContent":"\n ","id":107},{"type":2,"tagName":"h6","attributes":{"class":"my-0"},"childNodes":[{"type":3,"textContent":"Promo code","id":109}],"id":108},{"type":3,"textContent":"\n ","id":110},{"type":2,"tagName":"small","attributes":{},"childNodes":[{"type":3,"textContent":"EXAMPLECODE","id":112}],"id":111},{"type":3,"textContent":"\n ","id":113}],"id":106},{"type":3,"textContent":"\n ","id":114},{"type":2,"tagName":"span","attributes":{"class":"text-success"},"childNodes":[{"type":3,"textContent":"-$5","id":116}],"id":115},{"type":3,"textContent":"\n ","id":117}],"id":104},{"type":3,"textContent":"\n ","id":118},{"type":2,"tagName":"li","attributes":{"class":"list-group-item d-flex justify-content-between"},"childNodes":[{"type":3,"textContent":"\n ","id":120},{"type":2,"tagName":"span","attributes":{},"childNodes":[{"type":3,"textContent":"Total (USD)","id":122}],"id":121},{"type":3,"textContent":"\n ","id":123},{"type":2,"tagName":"strong","attributes":{},"childNodes":[{"type":3,"textContent":"$20","id":125}],"id":124},{"type":3,"textContent":"\n ","id":126}],"id":119},{"type":3,"textContent":"\n ","id":127}],"id":57},{"type":3,"textContent":"\n\n ","id":128},{"type":2,"tagName":"form","attributes":{"class":"card p-2"},"childNodes":[{"type":3,"textContent":"\n ","id":130},{"type":2,"tagName":"div","attributes":{"class":"input-group"},"childNodes":[{"type":3,"textContent":"\n ","id":132},{"type":2,"tagName":"input","attributes":{"type":"text","class":"form-control","placeholder":"Promo code"},"childNodes":[],"id":133},{"type":3,"textContent":"\n ","id":134},{"type":2,"tagName":"div","attributes":{"class":"input-group-append"},"childNodes":[{"type":3,"textContent":"\n ","id":136},{"type":2,"tagName":"button","attributes":{"type":"submit","class":"btn btn-secondary"},"childNodes":[{"type":3,"textContent":"Redeem","id":138}],"id":137},{"type":3,"textContent":"\n ","id":139}],"id":135},{"type":3,"textContent":"\n ","id":140}],"id":131},{"type":3,"textContent":"\n ","id":141}],"id":129},{"type":3,"textContent":"\n ","id":142}],"id":46},{"type":3,"textContent":"\n ","id":143},{"type":2,"tagName":"div","attributes":{"class":"col-md-8 order-md-1"},"childNodes":[{"type":3,"textContent":"\n ","id":145},{"type":2,"tagName":"h4","attributes":{"class":"mb-3"},"childNodes":[{"type":3,"textContent":"Billing address","id":147}],"id":146},{"type":3,"textContent":"\n ","id":148},{"type":2,"tagName":"form","attributes":{"class":"needs-validation","novalidate":""},"childNodes":[{"type":3,"textContent":"\n ","id":150},{"type":2,"tagName":"div","attributes":{"class":"row"},"childNodes":[{"type":3,"textContent":"\n ","id":152},{"type":2,"tagName":"div","attributes":{"class":"col-md-6 mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":154},{"type":2,"tagName":"label","attributes":{"for":"firstName"},"childNodes":[{"type":3,"textContent":"First name","id":156}],"id":155},{"type":3,"textContent":"\n ","id":157},{"type":2,"tagName":"input","attributes":{"type":"text","class":"form-control","id":"firstName","placeholder":"","value":"","required":""},"childNodes":[],"id":158},{"type":3,"textContent":"\n ","id":159},{"type":2,"tagName":"div","attributes":{"class":"invalid-feedback"},"childNodes":[{"type":3,"textContent":"\n Valid first name is required.\n ","id":161}],"id":160},{"type":3,"textContent":"\n ","id":162}],"id":153},{"type":3,"textContent":"\n ","id":163},{"type":2,"tagName":"div","attributes":{"class":"col-md-6 mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":165},{"type":2,"tagName":"label","attributes":{"for":"lastName"},"childNodes":[{"type":3,"textContent":"Last name","id":167}],"id":166},{"type":3,"textContent":"\n ","id":168},{"type":2,"tagName":"input","attributes":{"type":"text","class":"form-control","id":"lastName","placeholder":"","value":"","required":""},"childNodes":[],"id":169},{"type":3,"textContent":"\n ","id":170},{"type":2,"tagName":"div","attributes":{"class":"invalid-feedback"},"childNodes":[{"type":3,"textContent":"\n Valid last name is required.\n ","id":172}],"id":171},{"type":3,"textContent":"\n ","id":173}],"id":164},{"type":3,"textContent":"\n ","id":174}],"id":151},{"type":3,"textContent":"\n\n ","id":175},{"type":2,"tagName":"div","attributes":{"class":"mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":177},{"type":2,"tagName":"label","attributes":{"for":"username"},"childNodes":[{"type":3,"textContent":"Username","id":179}],"id":178},{"type":3,"textContent":"\n ","id":180},{"type":2,"tagName":"div","attributes":{"class":"input-group"},"childNodes":[{"type":3,"textContent":"\n ","id":182},{"type":2,"tagName":"div","attributes":{"class":"input-group-prepend"},"childNodes":[{"type":3,"textContent":"\n ","id":184},{"type":2,"tagName":"span","attributes":{"class":"input-group-text"},"childNodes":[{"type":3,"textContent":"@","id":186}],"id":185},{"type":3,"textContent":"\n ","id":187}],"id":183},{"type":3,"textContent":"\n ","id":188},{"type":2,"tagName":"input","attributes":{"type":"text","class":"form-control","id":"username","placeholder":"Username","required":""},"childNodes":[],"id":189},{"type":3,"textContent":"\n ","id":190},{"type":2,"tagName":"div","attributes":{"class":"invalid-feedback","style":"width: 100%;"},"childNodes":[{"type":3,"textContent":"\n Your username is required.\n ","id":192}],"id":191},{"type":3,"textContent":"\n ","id":193}],"id":181},{"type":3,"textContent":"\n ","id":194}],"id":176},{"type":3,"textContent":"\n\n ","id":195},{"type":2,"tagName":"div","attributes":{"class":"mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":197},{"type":2,"tagName":"label","attributes":{"for":"email"},"childNodes":[{"type":3,"textContent":"Email ","id":199},{"type":2,"tagName":"span","attributes":{"class":"text-muted"},"childNodes":[{"type":3,"textContent":"(Optional)","id":201}],"id":200}],"id":198},{"type":3,"textContent":"\n ","id":202},{"type":2,"tagName":"input","attributes":{"type":"email","class":"form-control","id":"email","placeholder":"you@example.com"},"childNodes":[],"id":203},{"type":3,"textContent":"\n ","id":204},{"type":2,"tagName":"div","attributes":{"class":"invalid-feedback"},"childNodes":[{"type":3,"textContent":"\n Please enter a valid email address for shipping updates.\n ","id":206}],"id":205},{"type":3,"textContent":"\n ","id":207}],"id":196},{"type":3,"textContent":"\n\n ","id":208},{"type":2,"tagName":"div","attributes":{"class":"mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":210},{"type":2,"tagName":"label","attributes":{"for":"address"},"childNodes":[{"type":3,"textContent":"Address","id":212}],"id":211},{"type":3,"textContent":"\n ","id":213},{"type":2,"tagName":"input","attributes":{"type":"text","class":"form-control","id":"address","placeholder":"1234 Main St","required":""},"childNodes":[],"id":214},{"type":3,"textContent":"\n ","id":215},{"type":2,"tagName":"div","attributes":{"class":"invalid-feedback"},"childNodes":[{"type":3,"textContent":"\n Please enter your shipping address.\n ","id":217}],"id":216},{"type":3,"textContent":"\n ","id":218}],"id":209},{"type":3,"textContent":"\n\n ","id":219},{"type":2,"tagName":"div","attributes":{"class":"mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":221},{"type":2,"tagName":"label","attributes":{"for":"address2"},"childNodes":[{"type":3,"textContent":"Address 2 ","id":223},{"type":2,"tagName":"span","attributes":{"class":"text-muted"},"childNodes":[{"type":3,"textContent":"(Optional)","id":225}],"id":224}],"id":222},{"type":3,"textContent":"\n ","id":226},{"type":2,"tagName":"input","attributes":{"type":"text","class":"form-control","id":"address2","placeholder":"Apartment or suite"},"childNodes":[],"id":227},{"type":3,"textContent":"\n ","id":228}],"id":220},{"type":3,"textContent":"\n\n ","id":229},{"type":2,"tagName":"div","attributes":{"class":"row"},"childNodes":[{"type":3,"textContent":"\n ","id":231},{"type":2,"tagName":"div","attributes":{"class":"col-md-5 mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":233},{"type":2,"tagName":"label","attributes":{"for":"country"},"childNodes":[{"type":3,"textContent":"Country","id":235}],"id":234},{"type":3,"textContent":"\n ","id":236},{"type":2,"tagName":"select","attributes":{"class":"custom-select d-block w-100","id":"country","required":""},"childNodes":[{"type":3,"textContent":"\n ","id":238},{"type":2,"tagName":"option","attributes":{"value":"","selected":true},"childNodes":[{"type":3,"textContent":"Choose...","id":240}],"id":239},{"type":3,"textContent":"\n ","id":241},{"type":2,"tagName":"option","attributes":{},"childNodes":[{"type":3,"textContent":"United States","id":243}],"id":242},{"type":3,"textContent":"\n ","id":244}],"id":237},{"type":3,"textContent":"\n ","id":245},{"type":2,"tagName":"div","attributes":{"class":"invalid-feedback"},"childNodes":[{"type":3,"textContent":"\n Please select a valid country.\n ","id":247}],"id":246},{"type":3,"textContent":"\n ","id":248}],"id":232},{"type":3,"textContent":"\n ","id":249},{"type":2,"tagName":"div","attributes":{"class":"col-md-4 mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":251},{"type":2,"tagName":"label","attributes":{"for":"state"},"childNodes":[{"type":3,"textContent":"State","id":253}],"id":252},{"type":3,"textContent":"\n ","id":254},{"type":2,"tagName":"select","attributes":{"class":"custom-select d-block w-100","id":"state","required":""},"childNodes":[{"type":3,"textContent":"\n ","id":256},{"type":2,"tagName":"option","attributes":{"value":"","selected":true},"childNodes":[{"type":3,"textContent":"Choose...","id":258}],"id":257},{"type":3,"textContent":"\n ","id":259},{"type":2,"tagName":"option","attributes":{},"childNodes":[{"type":3,"textContent":"California","id":261}],"id":260},{"type":3,"textContent":"\n ","id":262}],"id":255},{"type":3,"textContent":"\n ","id":263},{"type":2,"tagName":"div","attributes":{"class":"invalid-feedback"},"childNodes":[{"type":3,"textContent":"\n Please provide a valid state.\n ","id":265}],"id":264},{"type":3,"textContent":"\n ","id":266}],"id":250},{"type":3,"textContent":"\n ","id":267},{"type":2,"tagName":"div","attributes":{"class":"col-md-3 mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":269},{"type":2,"tagName":"label","attributes":{"for":"zip"},"childNodes":[{"type":3,"textContent":"Zip","id":271}],"id":270},{"type":3,"textContent":"\n ","id":272},{"type":2,"tagName":"input","attributes":{"type":"text","class":"form-control","id":"zip","placeholder":"","required":""},"childNodes":[],"id":273},{"type":3,"textContent":"\n ","id":274},{"type":2,"tagName":"div","attributes":{"class":"invalid-feedback"},"childNodes":[{"type":3,"textContent":"\n Zip code required.\n ","id":276}],"id":275},{"type":3,"textContent":"\n ","id":277}],"id":268},{"type":3,"textContent":"\n ","id":278}],"id":230},{"type":3,"textContent":"\n ","id":279},{"type":2,"tagName":"hr","attributes":{"class":"mb-4"},"childNodes":[],"id":280},{"type":3,"textContent":"\n ","id":281},{"type":2,"tagName":"div","attributes":{"class":"custom-control custom-checkbox"},"childNodes":[{"type":3,"textContent":"\n ","id":283},{"type":2,"tagName":"input","attributes":{"type":"checkbox","class":"custom-control-input","id":"same-address"},"childNodes":[],"id":284},{"type":3,"textContent":"\n ","id":285},{"type":2,"tagName":"label","attributes":{"class":"custom-control-label","for":"same-address"},"childNodes":[{"type":3,"textContent":"Shipping address is the same as my billing address","id":287}],"id":286},{"type":3,"textContent":"\n ","id":288}],"id":282},{"type":3,"textContent":"\n ","id":289},{"type":2,"tagName":"div","attributes":{"class":"custom-control custom-checkbox"},"childNodes":[{"type":3,"textContent":"\n ","id":291},{"type":2,"tagName":"input","attributes":{"type":"checkbox","class":"custom-control-input","id":"save-info"},"childNodes":[],"id":292},{"type":3,"textContent":"\n ","id":293},{"type":2,"tagName":"label","attributes":{"class":"custom-control-label","for":"save-info"},"childNodes":[{"type":3,"textContent":"Save this information for next time","id":295}],"id":294},{"type":3,"textContent":"\n ","id":296}],"id":290},{"type":3,"textContent":"\n ","id":297},{"type":2,"tagName":"hr","attributes":{"class":"mb-4"},"childNodes":[],"id":298},{"type":3,"textContent":"\n\n ","id":299},{"type":2,"tagName":"h4","attributes":{"class":"mb-3"},"childNodes":[{"type":3,"textContent":"Payment","id":301}],"id":300},{"type":3,"textContent":"\n\n ","id":302},{"type":2,"tagName":"div","attributes":{"class":"d-block my-3"},"childNodes":[{"type":3,"textContent":"\n ","id":304},{"type":2,"tagName":"div","attributes":{"class":"custom-control custom-radio"},"childNodes":[{"type":3,"textContent":"\n ","id":306},{"type":2,"tagName":"input","attributes":{"id":"credit","name":"paymentMethod","type":"radio","class":"custom-control-input","checked":true,"required":""},"childNodes":[],"id":307},{"type":3,"textContent":"\n ","id":308},{"type":2,"tagName":"label","attributes":{"class":"custom-control-label","for":"credit"},"childNodes":[{"type":3,"textContent":"Credit card","id":310}],"id":309},{"type":3,"textContent":"\n ","id":311}],"id":305},{"type":3,"textContent":"\n ","id":312},{"type":2,"tagName":"div","attributes":{"class":"custom-control custom-radio"},"childNodes":[{"type":3,"textContent":"\n ","id":314},{"type":2,"tagName":"input","attributes":{"id":"debit","name":"paymentMethod","type":"radio","class":"custom-control-input","required":""},"childNodes":[],"id":315},{"type":3,"textContent":"\n ","id":316},{"type":2,"tagName":"label","attributes":{"class":"custom-control-label","for":"debit"},"childNodes":[{"type":3,"textContent":"Debit card","id":318}],"id":317},{"type":3,"textContent":"\n ","id":319}],"id":313},{"type":3,"textContent":"\n ","id":320},{"type":2,"tagName":"div","attributes":{"class":"custom-control custom-radio"},"childNodes":[{"type":3,"textContent":"\n ","id":322},{"type":2,"tagName":"input","attributes":{"id":"paypal","name":"paymentMethod","type":"radio","class":"custom-control-input","required":""},"childNodes":[],"id":323},{"type":3,"textContent":"\n ","id":324},{"type":2,"tagName":"label","attributes":{"class":"custom-control-label","for":"paypal"},"childNodes":[{"type":3,"textContent":"PayPal","id":326}],"id":325},{"type":3,"textContent":"\n ","id":327}],"id":321},{"type":3,"textContent":"\n ","id":328}],"id":303},{"type":3,"textContent":"\n ","id":329},{"type":2,"tagName":"div","attributes":{"class":"row"},"childNodes":[{"type":3,"textContent":"\n ","id":331},{"type":2,"tagName":"div","attributes":{"class":"col-md-6 mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":333},{"type":2,"tagName":"label","attributes":{"for":"cc-name"},"childNodes":[{"type":3,"textContent":"Name on card","id":335}],"id":334},{"type":3,"textContent":"\n ","id":336},{"type":2,"tagName":"input","attributes":{"type":"text","class":"form-control","id":"cc-name","placeholder":"","required":""},"childNodes":[],"id":337},{"type":3,"textContent":"\n ","id":338},{"type":2,"tagName":"small","attributes":{"class":"text-muted"},"childNodes":[{"type":3,"textContent":"Full name as displayed on card","id":340}],"id":339},{"type":3,"textContent":"\n ","id":341},{"type":2,"tagName":"div","attributes":{"class":"invalid-feedback"},"childNodes":[{"type":3,"textContent":"\n Name on card is required\n ","id":343}],"id":342},{"type":3,"textContent":"\n ","id":344}],"id":332},{"type":3,"textContent":"\n ","id":345},{"type":2,"tagName":"div","attributes":{"class":"col-md-6 mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":347},{"type":2,"tagName":"label","attributes":{"for":"cc-number"},"childNodes":[{"type":3,"textContent":"Credit card number","id":349}],"id":348},{"type":3,"textContent":"\n ","id":350},{"type":2,"tagName":"input","attributes":{"type":"text","class":"form-control","id":"cc-number","placeholder":"","required":""},"childNodes":[],"id":351},{"type":3,"textContent":"\n ","id":352},{"type":2,"tagName":"div","attributes":{"class":"invalid-feedback"},"childNodes":[{"type":3,"textContent":"\n Credit card number is required\n ","id":354}],"id":353},{"type":3,"textContent":"\n ","id":355}],"id":346},{"type":3,"textContent":"\n ","id":356}],"id":330},{"type":3,"textContent":"\n ","id":357},{"type":2,"tagName":"div","attributes":{"class":"row"},"childNodes":[{"type":3,"textContent":"\n ","id":359},{"type":2,"tagName":"div","attributes":{"class":"col-md-3 mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":361},{"type":2,"tagName":"label","attributes":{"for":"cc-expiration"},"childNodes":[{"type":3,"textContent":"Expiration","id":363}],"id":362},{"type":3,"textContent":"\n ","id":364},{"type":2,"tagName":"input","attributes":{"type":"text","class":"form-control","id":"cc-expiration","placeholder":"","required":""},"childNodes":[],"id":365},{"type":3,"textContent":"\n ","id":366},{"type":2,"tagName":"div","attributes":{"class":"invalid-feedback"},"childNodes":[{"type":3,"textContent":"\n Expiration date required\n ","id":368}],"id":367},{"type":3,"textContent":"\n ","id":369}],"id":360},{"type":3,"textContent":"\n ","id":370},{"type":2,"tagName":"div","attributes":{"class":"col-md-3 mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":372},{"type":2,"tagName":"label","attributes":{"for":"cc-cvv"},"childNodes":[{"type":3,"textContent":"CVV","id":374}],"id":373},{"type":3,"textContent":"\n ","id":375},{"type":2,"tagName":"input","attributes":{"type":"text","class":"form-control","id":"cc-cvv","placeholder":"","required":""},"childNodes":[],"id":376},{"type":3,"textContent":"\n ","id":377},{"type":2,"tagName":"div","attributes":{"class":"invalid-feedback"},"childNodes":[{"type":3,"textContent":"\n Security code required\n ","id":379}],"id":378},{"type":3,"textContent":"\n ","id":380}],"id":371},{"type":3,"textContent":"\n ","id":381}],"id":358},{"type":3,"textContent":"\n ","id":382},{"type":2,"tagName":"div","attributes":{"class":"mb-3"},"childNodes":[{"type":3,"textContent":"\n ","id":384},{"type":2,"tagName":"label","attributes":{"for":"email"},"childNodes":[{"type":3,"textContent":"textarea ","id":386},{"type":2,"tagName":"span","attributes":{"class":"text-muted"},"childNodes":[{"type":3,"textContent":"(Optional)","id":388}],"id":387}],"id":385},{"type":3,"textContent":"\n ","id":389},{"type":2,"tagName":"textarea","attributes":{"name":"","id":"","cols":"30","rows":"10"},"childNodes":[],"id":390},{"type":3,"textContent":"\n ","id":391}],"id":383},{"type":3,"textContent":"\n ","id":392},{"type":2,"tagName":"hr","attributes":{"class":"mb-4"},"childNodes":[],"id":393},{"type":3,"textContent":"\n ","id":394},{"type":2,"tagName":"button","attributes":{"class":"btn btn-primary btn-lg btn-block","type":"submit"},"childNodes":[{"type":3,"textContent":"Continue to checkout","id":396}],"id":395},{"type":3,"textContent":"\n ","id":397}],"id":149},{"type":3,"textContent":"\n ","id":398}],"id":144},{"type":3,"textContent":"\n ","id":399}],"id":44},{"type":3,"textContent":"\n\n ","id":400},{"type":2,"tagName":"footer","attributes":{"class":"my-5 pt-5 text-muted text-center text-small"},"childNodes":[{"type":3,"textContent":"\n ","id":402},{"type":2,"tagName":"p","attributes":{"class":"mb-1"},"childNodes":[{"type":3,"textContent":"© 2017-2018 Company Name","id":404}],"id":403},{"type":3,"textContent":"\n ","id":405},{"type":2,"tagName":"ul","attributes":{"class":"list-inline"},"childNodes":[{"type":3,"textContent":"\n ","id":407},{"type":2,"tagName":"li","attributes":{"class":"list-inline-item"},"childNodes":[{"type":2,"tagName":"a","attributes":{"href":"https://getbootstrap.com/docs/4.1/examples/checkout/#"},"childNodes":[{"type":3,"textContent":"Privacy","id":410}],"id":409}],"id":408},{"type":3,"textContent":"\n ","id":411},{"type":2,"tagName":"li","attributes":{"class":"list-inline-item"},"childNodes":[{"type":2,"tagName":"a","attributes":{"href":"https://getbootstrap.com/docs/4.1/examples/checkout/#"},"childNodes":[{"type":3,"textContent":"Terms","id":414}],"id":413}],"id":412},{"type":3,"textContent":"\n ","id":415},{"type":2,"tagName":"li","attributes":{"class":"list-inline-item"},"childNodes":[{"type":2,"tagName":"a","attributes":{"href":"https://getbootstrap.com/docs/4.1/examples/checkout/#"},"childNodes":[{"type":3,"textContent":"Support","id":418}],"id":417}],"id":416},{"type":3,"textContent":"\n ","id":419}],"id":406},{"type":3,"textContent":"\n ","id":420}],"id":401},{"type":3,"textContent":"\n ","id":421}],"id":31},{"type":3,"textContent":"\n\n ","id":422},{"type":5,"textContent":" Bootstrap core JavaScript\n ================================================== ","id":423},{"type":3,"textContent":"\n ","id":424},{"type":5,"textContent":" Placed at the end of the document so the pages load faster ","id":425},{"type":3,"textContent":"\n ","id":426},{"type":2,"tagName":"script","attributes":{"src":"http://localhost:5500/checkout-demo/index_files/jquery-3.3.1.slim.min.js","integrity":"sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo","crossorigin":"anonymous"},"childNodes":[],"id":427},{"type":3,"textContent":"\n ","id":428},{"type":2,"tagName":"script","attributes":{},"childNodes":[{"type":3,"textContent":"SCRIPT_PLACEHOLDER","id":430}],"id":429},{"type":3,"textContent":"\n ","id":431},{"type":2,"tagName":"script","attributes":{"src":"http://localhost:5500/checkout-demo/index_files/popper.min.js"},"childNodes":[],"id":432},{"type":3,"textContent":"\n ","id":433},{"type":2,"tagName":"script","attributes":{"src":"http://localhost:5500/checkout-demo/index_files/bootstrap.min.js"},"childNodes":[],"id":434},{"type":3,"textContent":"\n ","id":435},{"type":2,"tagName":"script","attributes":{"src":"http://localhost:5500/checkout-demo/index_files/holder.min.js"},"childNodes":[],"id":436},{"type":3,"textContent":"\n ","id":437},{"type":2,"tagName":"script","attributes":{},"childNodes":[{"type":3,"textContent":"SCRIPT_PLACEHOLDER","id":439}],"id":438},{"type":3,"textContent":"\n\n ","id":440},{"type":5,"textContent":" logrocket ","id":441},{"type":3,"textContent":"\n\n ","id":442},{"type":5,"textContent":" \n ","id":443},{"type":3,"textContent":"\n\n ","id":444},{"type":5,"textContent":" fundebug ","id":445},{"type":3,"textContent":"\n\n ","id":446},{"type":5,"textContent":" \n ","id":447},{"type":3,"textContent":"\n\n ","id":448},{"type":5,"textContent":" fullstory ","id":449},{"type":3,"textContent":"\n\n ","id":450},{"type":5,"textContent":" ","id":451},{"type":3,"textContent":"\n\n ","id":452},{"type":2,"tagName":"script","attributes":{"src":"http://localhost:5500/src/record.js"},"childNodes":[],"id":453},{"type":3,"textContent":"\n ","id":454},{"type":2,"tagName":"script","attributes":{},"childNodes":[{"type":3,"textContent":"SCRIPT_PLACEHOLDER","id":456}],"id":455},{"type":3,"textContent":"\n\n","id":457},{"type":5,"textContent":" Code injected by live-server ","id":458},{"type":3,"textContent":"\n","id":459},{"type":2,"tagName":"script","attributes":{"type":"text/javascript"},"childNodes":[{"type":3,"textContent":"SCRIPT_PLACEHOLDER","id":461}],"id":460},{"type":3,"textContent":"\n\n","id":462}],"id":29}],"id":4}],"id":1},"initialOffset":{"left":0,"top":0}},"timestamp":1539774745304},{"type":3,"data":{"source":1,"positions":[{"x":301,"y":156,"timeOffset":-1}]},"timestamp":1539774745307},{"type":3,"data":{"source":1,"positions":[{"x":297,"y":159,"timeOffset":-477},{"x":294,"y":160,"timeOffset":-427},{"x":291,"y":162,"timeOffset":-393},{"x":286,"y":166,"timeOffset":-359},{"x":281,"y":169,"timeOffset":-327},{"x":278,"y":172,"timeOffset":-294},{"x":278,"y":175,"timeOffset":-260},{"x":278,"y":179,"timeOffset":-227},{"x":277,"y":185,"timeOffset":-193},{"x":277,"y":192,"timeOffset":-160},{"x":277,"y":197,"timeOffset":-126},{"x":277,"y":199,"timeOffset":-93},{"x":277,"y":202,"timeOffset":-60}]},"timestamp":1539774745807},{"type":3,"data":{"source":1,"positions":[{"x":278,"y":204,"timeOffset":-361},{"x":278,"y":204,"timeOffset":-311},{"x":277,"y":206,"timeOffset":-228}]},"timestamp":1539774746308},{"type":3,"data":{"source":1,"positions":[{"x":277,"y":207,"timeOffset":0}]},"timestamp":1539774747114},{"type":3,"data":{"source":2,"type":1,"id":29,"x":279,"y":280},"timestamp":1539774747448},{"type":3,"data":{"source":2,"type":0,"id":29,"x":279,"y":280},"timestamp":1539774747576},{"type":3,"data":{"source":2,"type":2,"id":29,"x":279,"y":280},"timestamp":1539774747576},{"type":3,"data":{"source":1,"positions":[{"x":274,"y":212,"timeOffset":-466},{"x":273,"y":221,"timeOffset":-433},{"x":272,"y":233,"timeOffset":-400},{"x":272,"y":245,"timeOffset":-367},{"x":272,"y":255,"timeOffset":-334},{"x":276,"y":263,"timeOffset":-300},{"x":277,"y":270,"timeOffset":-266},{"x":279,"y":274,"timeOffset":-233},{"x":279,"y":278,"timeOffset":-184}]},"timestamp":1539774747614},{"type":3,"data":{"source":1,"positions":[{"x":279,"y":280,"timeOffset":0}]},"timestamp":1539774748546},{"type":3,"data":{"source":4,"width":1147,"height":711},"timestamp":1539774748563},{"type":3,"data":{"source":1,"positions":[{"x":279,"y":285,"timeOffset":0}]},"timestamp":1539774749479},{"type":3,"data":{"source":1,"positions":[{"x":270,"y":304,"timeOffset":-468},{"x":265,"y":326,"timeOffset":-435},{"x":264,"y":336,"timeOffset":-401},{"x":262,"y":348,"timeOffset":-368},{"x":263,"y":356,"timeOffset":-334},{"x":263,"y":367,"timeOffset":-301},{"x":263,"y":373,"timeOffset":-267},{"x":263,"y":379,"timeOffset":-234},{"x":263,"y":384,"timeOffset":-201},{"x":262,"y":388,"timeOffset":-167},{"x":262,"y":393,"timeOffset":-133},{"x":261,"y":402,"timeOffset":-101},{"x":261,"y":405,"timeOffset":-68},{"x":261,"y":408,"timeOffset":-18}]},"timestamp":1539774749980},{"type":3,"data":{"source":2,"type":1,"id":158,"x":261,"y":410},"timestamp":1539774750089},{"type":3,"data":{"source":2,"type":5,"id":158},"timestamp":1539774750094},{"type":3,"data":{"source":2,"type":0,"id":158,"x":261,"y":410},"timestamp":1539774750208},{"type":3,"data":{"source":2,"type":2,"id":158,"x":261,"y":410},"timestamp":1539774750208},{"type":3,"data":{"source":1,"positions":[{"x":261,"y":410,"timeOffset":-486}]},"timestamp":1539774750481},{"type":3,"data":{"source":5,"text":"y","isChecked":false,"id":158},"timestamp":1539774750928},{"type":3,"data":{"source":5,"text":"ya","isChecked":false,"id":158},"timestamp":1539774751039},{"type":3,"data":{"source":5,"text":"yan","isChecked":false,"id":158},"timestamp":1539774751151},{"type":3,"data":{"source":5,"text":"yanz","isChecked":false,"id":158},"timestamp":1539774751264},{"type":3,"data":{"source":5,"text":"yanzh","isChecked":false,"id":158},"timestamp":1539774751342},{"type":3,"data":{"source":5,"text":"yanzhe","isChecked":false,"id":158},"timestamp":1539774751449},{"type":3,"data":{"source":5,"text":"yanzhen","isChecked":false,"id":158},"timestamp":1539774751551},{"type":3,"data":{"source":1,"positions":[{"x":265,"y":411,"timeOffset":0}]},"timestamp":1539774752128},{"type":3,"data":{"source":1,"positions":[{"x":317,"y":392,"timeOffset":-466},{"x":337,"y":357,"timeOffset":-433},{"x":342,"y":336,"timeOffset":-399},{"x":367,"y":319,"timeOffset":-366},{"x":406,"y":323,"timeOffset":-333},{"x":409,"y":336,"timeOffset":-300},{"x":409,"y":352,"timeOffset":-266},{"x":411,"y":363,"timeOffset":-233},{"x":419,"y":367,"timeOffset":-200},{"x":424,"y":373,"timeOffset":-166},{"x":430,"y":381,"timeOffset":-133},{"x":438,"y":384,"timeOffset":-100},{"x":443,"y":385,"timeOffset":-67},{"x":449,"y":388,"timeOffset":-33},{"x":451,"y":389,"timeOffset":0}]},"timestamp":1539774752629},{"type":3,"data":{"source":2,"type":1,"id":169,"x":453,"y":393},"timestamp":1539774752826},{"type":3,"data":{"source":2,"type":6,"id":158},"timestamp":1539774752829},{"type":3,"data":{"source":2,"type":5,"id":169},"timestamp":1539774752830},{"type":3,"data":{"source":2,"type":0,"id":169,"x":454,"y":396},"timestamp":1539774752896},{"type":3,"data":{"source":2,"type":2,"id":169,"x":454,"y":396},"timestamp":1539774752896},{"type":3,"data":{"source":1,"positions":[{"x":453,"y":391,"timeOffset":-466},{"x":453,"y":393,"timeOffset":-400},{"x":453,"y":393,"timeOffset":-367},{"x":453,"y":394,"timeOffset":-249},{"x":458,"y":397,"timeOffset":-215},{"x":468,"y":401,"timeOffset":-183}]},"timestamp":1539774753128},{"type":3,"data":{"source":5,"text":"y","isChecked":false,"id":169},"timestamp":1539774753790},{"type":3,"data":{"source":5,"text":"yu","isChecked":false,"id":169},"timestamp":1539774753836},{"type":3,"data":{"source":1,"positions":[{"x":465,"y":400,"timeOffset":0}]},"timestamp":1539774754611},{"type":3,"data":{"source":1,"positions":[{"x":447,"y":397,"timeOffset":-466},{"x":433,"y":394,"timeOffset":-433},{"x":373,"y":421,"timeOffset":-400},{"x":334,"y":442,"timeOffset":-367},{"x":322,"y":446,"timeOffset":-317},{"x":319,"y":450,"timeOffset":-266},{"x":308,"y":470,"timeOffset":-233},{"x":301,"y":481,"timeOffset":-200},{"x":300,"y":483,"timeOffset":-134},{"x":295,"y":490,"timeOffset":-100},{"x":293,"y":492,"timeOffset":-67}]},"timestamp":1539774755111},{"type":3,"data":{"source":2,"type":1,"id":189,"x":293,"y":492},"timestamp":1539774755137},{"type":3,"data":{"source":2,"type":6,"id":169},"timestamp":1539774755146},{"type":3,"data":{"source":2,"type":5,"id":189},"timestamp":1539774755147},{"type":3,"data":{"source":2,"type":0,"id":189,"x":293,"y":492},"timestamp":1539774755223},{"type":3,"data":{"source":2,"type":2,"id":189,"x":293,"y":492},"timestamp":1539774755223},{"type":3,"data":{"source":5,"text":"a","isChecked":false,"id":189},"timestamp":1539774755812},{"type":3,"data":{"source":5,"text":"ad","isChecked":false,"id":189},"timestamp":1539774755915},{"type":3,"data":{"source":5,"text":"adm","isChecked":false,"id":189},"timestamp":1539774756048},{"type":3,"data":{"source":5,"text":"admi","isChecked":false,"id":189},"timestamp":1539774756090},{"type":3,"data":{"source":5,"text":"admin","isChecked":false,"id":189},"timestamp":1539774756241},{"type":3,"data":{"source":1,"positions":[{"x":311,"y":510,"timeOffset":0}]},"timestamp":1539774756827},{"type":3,"data":{"source":3,"id":1,"x":0,"y":1},"timestamp":1539774757177},{"type":3,"data":{"source":3,"id":1,"x":0,"y":90},"timestamp":1539774757278},{"type":3,"data":{"source":1,"positions":[{"x":449,"y":606,"timeOffset":-468},{"x":515,"y":642,"timeOffset":-435},{"x":514,"y":627,"timeOffset":-369},{"x":410,"y":510,"timeOffset":-336},{"x":401,"y":498,"timeOffset":-269},{"x":398,"y":502,"timeOffset":-219},{"x":388,"y":506,"timeOffset":-186},{"x":385,"y":506,"timeOffset":-119},{"x":384,"y":506,"timeOffset":-68},{"x":380,"y":507,"timeOffset":-18}]},"timestamp":1539774757329},{"type":3,"data":{"source":3,"id":1,"x":0,"y":212},"timestamp":1539774757378},{"type":3,"data":{"source":1,"positions":[{"x":378,"y":506,"timeOffset":-486},{"x":373,"y":498,"timeOffset":-452},{"x":368,"y":488,"timeOffset":-420},{"x":353,"y":476,"timeOffset":-387},{"x":329,"y":458,"timeOffset":-353},{"x":320,"y":433,"timeOffset":-320},{"x":312,"y":395,"timeOffset":-287},{"x":303,"y":379,"timeOffset":-254},{"x":297,"y":369,"timeOffset":-221},{"x":294,"y":364,"timeOffset":-187}]},"timestamp":1539774757830},{"type":3,"data":{"source":2,"type":1,"id":203,"x":293,"y":363},"timestamp":1539774757849},{"type":3,"data":{"source":2,"type":6,"id":189},"timestamp":1539774757853},{"type":3,"data":{"source":2,"type":5,"id":203},"timestamp":1539774757855},{"type":3,"data":{"source":2,"type":0,"id":203,"x":293,"y":363},"timestamp":1539774757972},{"type":3,"data":{"source":2,"type":2,"id":203,"x":293,"y":363},"timestamp":1539774757972},{"type":3,"data":{"source":5,"text":"y","isChecked":false,"id":203},"timestamp":1539774758877},{"type":3,"data":{"source":5,"text":"ya","isChecked":false,"id":203},"timestamp":1539774758966},{"type":3,"data":{"source":5,"text":"yan","isChecked":false,"id":203},"timestamp":1539774759091},{"type":3,"data":{"source":5,"text":"yanz","isChecked":false,"id":203},"timestamp":1539774759222},{"type":3,"data":{"source":5,"text":"yanzh","isChecked":false,"id":203},"timestamp":1539774759318},{"type":3,"data":{"source":5,"text":"yanzhe","isChecked":false,"id":203},"timestamp":1539774759412},{"type":3,"data":{"source":5,"text":"yanzhen","isChecked":false,"id":203},"timestamp":1539774759522},{"type":3,"data":{"source":5,"text":"yanzhen@","isChecked":false,"id":203},"timestamp":1539774760043},{"type":3,"data":{"source":5,"text":"yanzhen@smartx.com","isChecked":false,"id":203},"timestamp":1539774760767},{"type":3,"data":{"source":1,"positions":[{"x":315,"y":364,"timeOffset":0}]},"timestamp":1539774761476},{"type":3,"data":{"source":1,"positions":[{"x":346,"y":366,"timeOffset":-469},{"x":342,"y":391,"timeOffset":-434},{"x":323,"y":422,"timeOffset":-401},{"x":318,"y":435,"timeOffset":-369},{"x":312,"y":443,"timeOffset":-336},{"x":308,"y":445,"timeOffset":-301},{"x":304,"y":448,"timeOffset":-252},{"x":302,"y":449,"timeOffset":-118},{"x":300,"y":451,"timeOffset":-85},{"x":300,"y":452,"timeOffset":-19}]},"timestamp":1539774761977},{"type":3,"data":{"source":2,"type":1,"id":214,"x":300,"y":452},"timestamp":1539774762010},{"type":3,"data":{"source":2,"type":6,"id":203},"timestamp":1539774762011},{"type":3,"data":{"source":2,"type":5,"id":214},"timestamp":1539774762012},{"type":3,"data":{"source":2,"type":0,"id":214,"x":300,"y":452},"timestamp":1539774762129},{"type":3,"data":{"source":2,"type":2,"id":214,"x":300,"y":452},"timestamp":1539774762129},{"type":3,"data":{"source":1,"positions":[{"x":300,"y":451,"timeOffset":0}]},"timestamp":1539774762509},{"type":3,"data":{"source":1,"positions":[{"x":302,"y":445,"timeOffset":-470},{"x":298,"y":445,"timeOffset":-369},{"x":291,"y":459,"timeOffset":-336},{"x":280,"y":514,"timeOffset":-269},{"x":280,"y":566,"timeOffset":-236},{"x":271,"y":572,"timeOffset":-170},{"x":221,"y":516,"timeOffset":-140},{"x":147,"y":458,"timeOffset":-103},{"x":145,"y":455,"timeOffset":-70},{"x":145,"y":452,"timeOffset":-37}]},"timestamp":1539774763011},{"type":3,"data":{"source":1,"positions":[{"x":146,"y":451,"timeOffset":-487},{"x":146,"y":451,"timeOffset":-404},{"x":147,"y":463,"timeOffset":-371},{"x":148,"y":473,"timeOffset":-338}]},"timestamp":1539774763512},{"type":3,"data":{"source":5,"text":"beijing","isChecked":false,"id":214},"timestamp":1539774763528},{"type":3,"data":{"source":1,"positions":[{"x":147,"y":490,"timeOffset":-470},{"x":147,"y":491,"timeOffset":-339},{"x":148,"y":499,"timeOffset":-305},{"x":149,"y":515,"timeOffset":-272},{"x":149,"y":527,"timeOffset":-238},{"x":149,"y":529,"timeOffset":-205},{"x":149,"y":532,"timeOffset":-173},{"x":149,"y":533,"timeOffset":-89},{"x":149,"y":535,"timeOffset":-55},{"x":149,"y":539,"timeOffset":-22}]},"timestamp":1539774764013},{"type":3,"data":{"source":2,"type":1,"id":227,"x":148,"y":544},"timestamp":1539774764073},{"type":3,"data":{"source":2,"type":6,"id":214},"timestamp":1539774764076},{"type":3,"data":{"source":2,"type":5,"id":227},"timestamp":1539774764078},{"type":3,"data":{"source":2,"type":0,"id":227,"x":148,"y":544},"timestamp":1539774764200},{"type":3,"data":{"source":2,"type":2,"id":227,"x":148,"y":544},"timestamp":1539774764200},{"type":3,"data":{"source":1,"positions":[{"x":148,"y":542,"timeOffset":-490},{"x":148,"y":544,"timeOffset":-441},{"x":149,"y":544,"timeOffset":-240},{"x":154,"y":542,"timeOffset":-206},{"x":161,"y":538,"timeOffset":-174},{"x":163,"y":535,"timeOffset":-123}]},"timestamp":1539774764514},{"type":3,"data":{"source":5,"text":"s","isChecked":false,"id":227},"timestamp":1539774765407},{"type":3,"data":{"source":5,"text":"sh","isChecked":false,"id":227},"timestamp":1539774765506},{"type":3,"data":{"source":5,"text":"she","isChecked":false,"id":227},"timestamp":1539774765628},{"type":3,"data":{"source":5,"text":"shen","isChecked":false,"id":227},"timestamp":1539774765722},{"type":3,"data":{"source":5,"text":"shenz","isChecked":false,"id":227},"timestamp":1539774765850},{"type":3,"data":{"source":5,"text":"shenzh","isChecked":false,"id":227},"timestamp":1539774765924},{"type":3,"data":{"source":5,"text":"shenzhn","isChecked":false,"id":227},"timestamp":1539774766130},{"type":3,"data":{"source":5,"text":"shenzh","isChecked":false,"id":227},"timestamp":1539774766706},{"type":3,"data":{"source":5,"text":"shenzhe","isChecked":false,"id":227},"timestamp":1539774766873},{"type":3,"data":{"source":5,"text":"shenzhen","isChecked":false,"id":227},"timestamp":1539774766960},{"type":3,"data":{"source":1,"positions":[{"x":166,"y":532,"timeOffset":0}]},"timestamp":1539774767574},{"type":3,"data":{"source":1,"positions":[{"x":179,"y":526,"timeOffset":-467},{"x":178,"y":526,"timeOffset":-385},{"x":159,"y":531,"timeOffset":-351},{"x":144,"y":537,"timeOffset":-318},{"x":128,"y":539,"timeOffset":-284},{"x":77,"y":546,"timeOffset":-251},{"x":30,"y":555,"timeOffset":-218},{"x":29,"y":556,"timeOffset":-101},{"x":59,"y":552,"timeOffset":-67},{"x":74,"y":549,"timeOffset":-35}]},"timestamp":1539774768074},{"type":3,"data":{"source":2,"type":1,"id":29,"x":74,"y":549},"timestamp":1539774768088},{"type":3,"data":{"source":2,"type":6,"id":227},"timestamp":1539774768091},{"type":3,"data":{"source":2,"type":0,"id":29,"x":74,"y":549},"timestamp":1539774768159},{"type":3,"data":{"source":2,"type":2,"id":29,"x":74,"y":549},"timestamp":1539774768159},{"type":3,"data":{"source":3,"id":1,"x":0,"y":213},"timestamp":1539774768356},{"type":3,"data":{"source":3,"id":1,"x":0,"y":286},"timestamp":1539774768457},{"type":3,"data":{"source":3,"id":1,"x":0,"y":421},"timestamp":1539774768557},{"type":3,"data":{"source":1,"positions":[{"x":75,"y":549,"timeOffset":-273},{"x":78,"y":549,"timeOffset":-171},{"x":85,"y":546,"timeOffset":-137},{"x":96,"y":544,"timeOffset":-105},{"x":116,"y":543,"timeOffset":-71},{"x":135,"y":537,"timeOffset":-38},{"x":155,"y":530,"timeOffset":0}]},"timestamp":1539774768578},{"type":3,"data":{"source":3,"id":1,"x":0,"y":424},"timestamp":1539774768657},{"type":3,"data":{"source":1,"positions":[{"x":210,"y":507,"timeOffset":-472},{"x":278,"y":478,"timeOffset":-439},{"x":321,"y":459,"timeOffset":-406},{"x":347,"y":440,"timeOffset":-372},{"x":367,"y":416,"timeOffset":-339},{"x":378,"y":407,"timeOffset":-305},{"x":384,"y":400,"timeOffset":-272},{"x":386,"y":397,"timeOffset":-239},{"x":386,"y":396,"timeOffset":-189},{"x":385,"y":395,"timeOffset":-155},{"x":369,"y":401,"timeOffset":-122},{"x":341,"y":415,"timeOffset":-89},{"x":326,"y":419,"timeOffset":-55}]},"timestamp":1539774769078},{"type":3,"data":{"source":2,"type":1,"id":237,"x":319,"y":422},"timestamp":1539774769208},{"type":3,"data":{"source":2,"type":5,"id":237},"timestamp":1539774769210},{"type":3,"data":{"source":1,"positions":[{"x":322,"y":420,"timeOffset":-489}]},"timestamp":1539774769578},{"type":3,"data":{"source":5,"text":"United States","isChecked":false,"id":237},"timestamp":1539774769903},{"type":3,"data":{"source":2,"type":0,"id":237,"x":0,"y":0},"timestamp":1539774769903},{"type":3,"data":{"source":2,"type":2,"id":237,"x":0,"y":0},"timestamp":1539774769903},{"type":3,"data":{"source":1,"positions":[{"x":303,"y":458,"timeOffset":-158},{"x":307,"y":457,"timeOffset":-124},{"x":326,"y":450,"timeOffset":-90},{"x":356,"y":437,"timeOffset":-57},{"x":393,"y":425,"timeOffset":-24}]},"timestamp":1539774770080},{"type":3,"data":{"source":2,"type":1,"id":255,"x":451,"y":413},"timestamp":1539774770264},{"type":3,"data":{"source":2,"type":6,"id":237},"timestamp":1539774770265},{"type":3,"data":{"source":2,"type":5,"id":255},"timestamp":1539774770267},{"type":3,"data":{"source":1,"positions":[{"x":415,"y":423,"timeOffset":-492},{"x":424,"y":420,"timeOffset":-458},{"x":436,"y":418,"timeOffset":-425},{"x":447,"y":414,"timeOffset":-391}]},"timestamp":1539774770580},{"type":3,"data":{"source":5,"text":"California","isChecked":false,"id":255},"timestamp":1539774770855},{"type":3,"data":{"source":2,"type":0,"id":255,"x":0,"y":0},"timestamp":1539774770855},{"type":3,"data":{"source":2,"type":2,"id":255,"x":0,"y":0},"timestamp":1539774770855},{"type":3,"data":{"source":1,"positions":[{"x":444,"y":466,"timeOffset":-206},{"x":447,"y":466,"timeOffset":-175},{"x":462,"y":463,"timeOffset":-142},{"x":490,"y":460,"timeOffset":-109},{"x":517,"y":455,"timeOffset":-75},{"x":544,"y":449,"timeOffset":-41},{"x":564,"y":442,"timeOffset":-8}]},"timestamp":1539774771080},{"type":3,"data":{"source":2,"type":1,"id":273,"x":623,"y":417},"timestamp":1539774771320},{"type":3,"data":{"source":2,"type":6,"id":255},"timestamp":1539774771321},{"type":3,"data":{"source":2,"type":5,"id":273},"timestamp":1539774771324},{"type":3,"data":{"source":2,"type":0,"id":273,"x":623,"y":417},"timestamp":1539774771432},{"type":3,"data":{"source":2,"type":2,"id":273,"x":623,"y":417},"timestamp":1539774771432},{"type":3,"data":{"source":1,"positions":[{"x":585,"y":433,"timeOffset":-475},{"x":603,"y":426,"timeOffset":-441},{"x":613,"y":423,"timeOffset":-408},{"x":619,"y":420,"timeOffset":-374},{"x":623,"y":417,"timeOffset":-341}]},"timestamp":1539774771580},{"type":3,"data":{"source":1,"positions":[{"x":627,"y":415,"timeOffset":-458}]},"timestamp":1539774772080},{"type":3,"data":{"source":5,"text":"1","isChecked":false,"id":273},"timestamp":1539774772151},{"type":3,"data":{"source":5,"text":"10","isChecked":false,"id":273},"timestamp":1539774772349},{"type":3,"data":{"source":5,"text":"100","isChecked":false,"id":273},"timestamp":1539774772521},{"type":3,"data":{"source":5,"text":"1000","isChecked":false,"id":273},"timestamp":1539774773008},{"type":3,"data":{"source":5,"text":"10000","isChecked":false,"id":273},"timestamp":1539774773176},{"type":3,"data":{"source":5,"text":"100000","isChecked":false,"id":273},"timestamp":1539774773539},{"type":3,"data":{"source":1,"positions":[{"x":627,"y":415,"timeOffset":0}]},"timestamp":1539774774170},{"type":3,"data":{"source":2,"type":1,"id":286,"x":320,"y":508},"timestamp":1539774774582},{"type":3,"data":{"source":2,"type":6,"id":273},"timestamp":1539774774584},{"type":3,"data":{"source":2,"type":0,"id":286,"x":320,"y":508},"timestamp":1539774774654},{"type":3,"data":{"source":2,"type":2,"id":286,"x":320,"y":508},"timestamp":1539774774654},{"type":3,"data":{"source":2,"type":5,"id":284},"timestamp":1539774774657},{"type":3,"data":{"source":2,"type":2,"id":284,"x":320,"y":508},"timestamp":1539774774657},{"type":3,"data":{"source":5,"text":"on","isChecked":true,"id":284},"timestamp":1539774774657},{"type":3,"data":{"source":1,"positions":[{"x":617,"y":385,"timeOffset":-464},{"x":552,"y":369,"timeOffset":-432},{"x":473,"y":409,"timeOffset":-398},{"x":414,"y":457,"timeOffset":-365},{"x":392,"y":490,"timeOffset":-331},{"x":385,"y":498,"timeOffset":-299},{"x":362,"y":502,"timeOffset":-265},{"x":332,"y":507,"timeOffset":-232},{"x":320,"y":508,"timeOffset":-199}]},"timestamp":1539774774670},{"type":3,"data":{"source":1,"positions":[{"x":318,"y":509,"timeOffset":-131},{"x":310,"y":511,"timeOffset":-98},{"x":299,"y":518,"timeOffset":-65},{"x":291,"y":523,"timeOffset":-32}]},"timestamp":1539774775169},{"type":3,"data":{"source":2,"type":1,"id":294,"x":286,"y":527},"timestamp":1539774775272},{"type":3,"data":{"source":2,"type":6,"id":284},"timestamp":1539774775273},{"type":3,"data":{"source":2,"type":0,"id":294,"x":286,"y":527},"timestamp":1539774775359},{"type":3,"data":{"source":2,"type":2,"id":294,"x":286,"y":527},"timestamp":1539774775359},{"type":3,"data":{"source":2,"type":5,"id":292},"timestamp":1539774775379},{"type":3,"data":{"source":2,"type":2,"id":292,"x":286,"y":527},"timestamp":1539774775379},{"type":3,"data":{"source":5,"text":"on","isChecked":true,"id":292},"timestamp":1539774775380},{"type":3,"data":{"source":3,"id":1,"x":0,"y":425},"timestamp":1539774775638},{"type":3,"data":{"source":1,"positions":[{"x":287,"y":526,"timeOffset":-499},{"x":282,"y":529,"timeOffset":-213},{"x":273,"y":540,"timeOffset":-181},{"x":269,"y":547,"timeOffset":-148},{"x":269,"y":549,"timeOffset":-99},{"x":269,"y":553,"timeOffset":-66},{"x":269,"y":555,"timeOffset":-31}]},"timestamp":1539774775669},{"type":3,"data":{"source":3,"id":1,"x":0,"y":499},"timestamp":1539774775738},{"type":3,"data":{"source":3,"id":1,"x":0,"y":652},"timestamp":1539774775838},{"type":3,"data":{"source":3,"id":1,"x":0,"y":689},"timestamp":1539774775938},{"type":3,"data":{"source":1,"positions":[{"x":267,"y":556,"timeOffset":-449},{"x":265,"y":556,"timeOffset":-416},{"x":259,"y":559,"timeOffset":-382},{"x":244,"y":559,"timeOffset":-349},{"x":225,"y":559,"timeOffset":-316},{"x":219,"y":559,"timeOffset":-282},{"x":217,"y":559,"timeOffset":-233},{"x":212,"y":552,"timeOffset":-199},{"x":203,"y":540,"timeOffset":-167},{"x":194,"y":525,"timeOffset":-134},{"x":187,"y":501,"timeOffset":-101},{"x":181,"y":469,"timeOffset":-67},{"x":177,"y":452,"timeOffset":-34}]},"timestamp":1539774776170},{"type":3,"data":{"source":2,"type":1,"id":325,"x":168,"y":419},"timestamp":1539774776495},{"type":3,"data":{"source":2,"type":6,"id":292},"timestamp":1539774776497},{"type":3,"data":{"source":2,"type":0,"id":325,"x":168,"y":419},"timestamp":1539774776590},{"type":3,"data":{"source":2,"type":2,"id":325,"x":168,"y":419},"timestamp":1539774776590},{"type":3,"data":{"source":2,"type":5,"id":323},"timestamp":1539774776594},{"type":3,"data":{"source":2,"type":2,"id":323,"x":168,"y":419},"timestamp":1539774776595},{"type":3,"data":{"source":5,"text":"on","isChecked":true,"id":323},"timestamp":1539774776596},{"type":3,"data":{"source":5,"text":"on","isChecked":false,"id":307},"timestamp":1539774776596},{"type":3,"data":{"source":5,"text":"on","isChecked":false,"id":315},"timestamp":1539774776596},{"type":3,"data":{"source":1,"positions":[{"x":176,"y":449,"timeOffset":-483},{"x":176,"y":447,"timeOffset":-450},{"x":176,"y":441,"timeOffset":-417},{"x":176,"y":430,"timeOffset":-384},{"x":173,"y":425,"timeOffset":-351},{"x":172,"y":424,"timeOffset":-317},{"x":170,"y":422,"timeOffset":-284},{"x":168,"y":419,"timeOffset":-234},{"x":167,"y":418,"timeOffset":-48},{"x":167,"y":408,"timeOffset":-16}]},"timestamp":1539774776670},{"type":3,"data":{"source":2,"type":1,"id":317,"x":166,"y":388},"timestamp":1539774776816},{"type":3,"data":{"source":2,"type":6,"id":323},"timestamp":1539774776818},{"type":3,"data":{"source":2,"type":0,"id":317,"x":166,"y":388},"timestamp":1539774776904},{"type":3,"data":{"source":2,"type":2,"id":317,"x":166,"y":388},"timestamp":1539774776905},{"type":3,"data":{"source":2,"type":5,"id":315},"timestamp":1539774776908},{"type":3,"data":{"source":2,"type":2,"id":315,"x":166,"y":388},"timestamp":1539774776908},{"type":3,"data":{"source":5,"text":"on","isChecked":true,"id":315},"timestamp":1539774776910},{"type":3,"data":{"source":5,"text":"on","isChecked":false,"id":323},"timestamp":1539774776910},{"type":3,"data":{"source":1,"positions":[{"x":167,"y":395,"timeOffset":-483},{"x":166,"y":389,"timeOffset":-450},{"x":168,"y":387,"timeOffset":-183},{"x":179,"y":390,"timeOffset":-151},{"x":208,"y":400,"timeOffset":-116},{"x":236,"y":403,"timeOffset":-84},{"x":267,"y":406,"timeOffset":-52},{"x":284,"y":408,"timeOffset":-19}]},"timestamp":1539774777171},{"type":3,"data":{"source":3,"id":1,"x":0,"y":690},"timestamp":1539774777237},{"type":3,"data":{"source":3,"id":1,"x":0,"y":733},"timestamp":1539774777338},{"type":3,"data":{"source":3,"id":1,"x":0,"y":793},"timestamp":1539774777438},{"type":3,"data":{"source":3,"id":1,"x":0,"y":795},"timestamp":1539774777539},{"type":3,"data":{"source":1,"positions":[{"x":287,"y":408,"timeOffset":-485},{"x":289,"y":409,"timeOffset":-434},{"x":289,"y":413,"timeOffset":-400},{"x":289,"y":416,"timeOffset":-351},{"x":288,"y":417,"timeOffset":-318},{"x":288,"y":417,"timeOffset":-284},{"x":287,"y":418,"timeOffset":-201},{"x":286,"y":418,"timeOffset":-169}]},"timestamp":1539774777671},{"type":3,"data":{"source":3,"id":1,"x":0,"y":796},"timestamp":1539774777869},{"type":3,"data":{"source":3,"id":1,"x":0,"y":836},"timestamp":1539774777970},{"type":3,"data":{"source":3,"id":1,"x":0,"y":972},"timestamp":1539774778071},{"type":3,"data":{"source":1,"positions":[{"x":287,"y":422,"timeOffset":-385},{"x":299,"y":438,"timeOffset":-351},{"x":312,"y":456,"timeOffset":-318},{"x":318,"y":465,"timeOffset":-285},{"x":320,"y":466,"timeOffset":-218},{"x":321,"y":466,"timeOffset":-184}]},"timestamp":1539774778171},{"type":3,"data":{"source":3,"id":1,"x":0,"y":1007},"timestamp":1539774778171},{"type":3,"data":{"source":2,"type":1,"id":390,"x":322,"y":467},"timestamp":1539774778312},{"type":3,"data":{"source":2,"type":6,"id":315},"timestamp":1539774778313},{"type":3,"data":{"source":2,"type":5,"id":390},"timestamp":1539774778315},{"type":3,"data":{"source":2,"type":0,"id":390,"x":322,"y":467},"timestamp":1539774778423},{"type":3,"data":{"source":2,"type":2,"id":390,"x":322,"y":467},"timestamp":1539774778423},{"type":3,"data":{"source":1,"positions":[{"x":322,"y":467,"timeOffset":-486},{"x":324,"y":464,"timeOffset":-136},{"x":331,"y":448,"timeOffset":-103}]},"timestamp":1539774778672},{"type":3,"data":{"source":5,"text":"h","isChecked":false,"id":390},"timestamp":1539774779696},{"type":3,"data":{"source":5,"text":"he","isChecked":false,"id":390},"timestamp":1539774779875},{"type":3,"data":{"source":5,"text":"hel","isChecked":false,"id":390},"timestamp":1539774780010},{"type":3,"data":{"source":5,"text":"hell","isChecked":false,"id":390},"timestamp":1539774780179},{"type":3,"data":{"source":5,"text":"hello","isChecked":false,"id":390},"timestamp":1539774780363},{"type":3,"data":{"source":5,"text":"hello ","isChecked":false,"id":390},"timestamp":1539774780501},{"type":3,"data":{"source":5,"text":"hello w","isChecked":false,"id":390},"timestamp":1539774780690},{"type":3,"data":{"source":5,"text":"hello wo","isChecked":false,"id":390},"timestamp":1539774780810},{"type":3,"data":{"source":5,"text":"hello wor","isChecked":false,"id":390},"timestamp":1539774780914},{"type":3,"data":{"source":5,"text":"hello worl","isChecked":false,"id":390},"timestamp":1539774781245},{"type":3,"data":{"source":5,"text":"hello world","isChecked":false,"id":390},"timestamp":1539774781381},{"type":3,"data":{"source":1,"positions":[{"x":332,"y":448,"timeOffset":0}]},"timestamp":1539774781919},{"type":3,"data":{"source":1,"positions":[{"x":333,"y":457,"timeOffset":-400},{"x":397,"y":511,"timeOffset":-368},{"x":533,"y":567,"timeOffset":-334},{"x":577,"y":603,"timeOffset":-300},{"x":581,"y":605,"timeOffset":-134},{"x":581,"y":599,"timeOffset":-100},{"x":566,"y":592,"timeOffset":-68},{"x":554,"y":586,"timeOffset":-34}]},"timestamp":1539774782419},{"type":3,"data":{"source":1,"positions":[{"x":552,"y":583,"timeOffset":-450},{"x":548,"y":578,"timeOffset":-418},{"x":547,"y":577,"timeOffset":-334},{"x":545,"y":575,"timeOffset":-301},{"x":542,"y":572,"timeOffset":-267},{"x":540,"y":572,"timeOffset":-234},{"x":539,"y":572,"timeOffset":-167},{"x":537,"y":571,"timeOffset":-134},{"x":536,"y":571,"timeOffset":-84},{"x":535,"y":571,"timeOffset":-51},{"x":531,"y":570,"timeOffset":-16}]},"timestamp":1539774782919},{"type":3,"data":{"source":1,"positions":[{"x":530,"y":569,"timeOffset":-483},{"x":528,"y":567,"timeOffset":-233},{"x":527,"y":567,"timeOffset":-201}]},"timestamp":1539774783419},{"type":3,"data":{"source":2,"type":1,"id":390,"x":526,"y":567},"timestamp":1539774783464},{"type":3,"data":{"source":0,"texts":[],"attributes":[{"id":390,"attributes":{"style":"margin-top: 0px; margin-bottom: 0px; height: 245px;"}}],"removes":[],"adds":[]},"timestamp":1539774783550},{"type":3,"data":{"source":0,"texts":[],"attributes":[{"id":390,"attributes":{"style":"margin-top: 0px; margin-bottom: 0px; height: 244px;"}}],"removes":[],"adds":[]},"timestamp":1539774783567},{"type":3,"data":{"source":0,"texts":[],"attributes":[{"id":390,"attributes":{"style":"margin-top: 0px; margin-bottom: 0px; height: 240px;"}}],"removes":[],"adds":[]},"timestamp":1539774783586},{"type":3,"data":{"source":0,"texts":[],"attributes":[{"id":390,"attributes":{"style":"margin-top: 0px; margin-bottom: 0px; height: 234px;"}}],"removes":[],"adds":[]},"timestamp":1539774783603},{"type":3,"data":{"source":0,"texts":[],"attributes":[{"id":390,"attributes":{"style":"margin-top: 0px; margin-bottom: 0px; height: 228px;"}}],"removes":[],"adds":[]},"timestamp":1539774783618},{"type":3,"data":{"source":0,"texts":[],"attributes":[{"id":390,"attributes":{"style":"margin-top: 0px; margin-bottom: 0px; height: 220px;"}}],"removes":[],"adds":[]},"timestamp":1539774783636},{"type":3,"data":{"source":0,"texts":[],"attributes":[{"id":390,"attributes":{"style":"margin-top: 0px; margin-bottom: 0px; height: 214px;"}}],"removes":[],"adds":[]},"timestamp":1539774783653},{"type":3,"data":{"source":0,"texts":[],"attributes":[{"id":390,"attributes":{"style":"margin-top: 0px; margin-bottom: 0px; height: 206px;"}}],"removes":[],"adds":[]},"timestamp":1539774783669},{"type":3,"data":{"source":0,"texts":[],"attributes":[{"id":390,"attributes":{"style":"margin-top: 0px; margin-bottom: 0px; height: 193px;"}}],"removes":[],"adds":[]},"timestamp":1539774783686},{"type":3,"data":{"source":0,"texts":[],"attributes":[{"id":390,"attributes":{"style":"margin-top: 0px; margin-bottom: 0px; height: 181px;"}}],"removes":[],"adds":[]},"timestamp":1539774783703},{"type":3,"data":{"source":0,"texts":[],"attributes":[{"id":390,"attributes":{"style":"margin-top: 0px; margin-bottom: 0px; height: 170px;"}}],"removes":[],"adds":[]},"timestamp":1539774783719},{"type":3,"data":{"source":0,"texts":[],"attributes":[{"id":390,"attributes":{"style":"margin-top: 0px; margin-bottom: 0px; height: 158px;"}}],"removes":[],"adds":[]},"timestamp":1539774783737},{"type":3,"data":{"source":0,"texts":[],"attributes":[{"id":390,"attributes":{"style":"margin-top: 0px; margin-bottom: 0px; height: 153px;"}}],"removes":[],"adds":[]},"timestamp":1539774783752},{"type":3,"data":{"source":0,"texts":[],"attributes":[{"id":390,"attributes":{"style":"margin-top: 0px; margin-bottom: 0px; height: 151px;"}}],"removes":[],"adds":[]},"timestamp":1539774783770},{"type":3,"data":{"source":0,"texts":[],"attributes":[{"id":390,"attributes":{"style":"margin-top: 0px; margin-bottom: 0px; height: 148px;"}}],"removes":[],"adds":[]},"timestamp":1539774783786},{"type":3,"data":{"source":0,"texts":[],"attributes":[{"id":390,"attributes":{"style":"margin-top: 0px; margin-bottom: 0px; height: 147px;"}}],"removes":[],"adds":[]},"timestamp":1539774783803},{"type":3,"data":{"source":0,"texts":[],"attributes":[{"id":390,"attributes":{"style":"margin-top: 0px; margin-bottom: 0px; height: 146px;"}}],"removes":[],"adds":[]},"timestamp":1539774783868},{"type":3,"data":{"source":0,"texts":[],"attributes":[{"id":390,"attributes":{"style":"margin-top: 0px; margin-bottom: 0px; height: 145px;"}}],"removes":[],"adds":[]},"timestamp":1539774783885},{"type":3,"data":{"source":0,"texts":[],"attributes":[{"id":390,"attributes":{"style":"margin-top: 0px; margin-bottom: 0px; height: 142px;"}}],"removes":[],"adds":[]},"timestamp":1539774783902},{"type":3,"data":{"source":0,"texts":[],"attributes":[{"id":390,"attributes":{"style":"margin-top: 0px; margin-bottom: 0px; height: 138px;"}}],"removes":[],"adds":[]},"timestamp":1539774783919},{"type":3,"data":{"source":1,"positions":[{"x":525,"y":566,"timeOffset":-374},{"x":526,"y":561,"timeOffset":-338},{"x":529,"y":549,"timeOffset":-306},{"x":529,"y":535,"timeOffset":-272},{"x":529,"y":514,"timeOffset":-238},{"x":529,"y":491,"timeOffset":-206},{"x":526,"y":474,"timeOffset":-172},{"x":525,"y":469,"timeOffset":-138},{"x":523,"y":467,"timeOffset":-56},{"x":523,"y":463,"timeOffset":-22}]},"timestamp":1539774783924},{"type":3,"data":{"source":0,"texts":[],"attributes":[{"id":390,"attributes":{"style":"margin-top: 0px; margin-bottom: 0px; height: 132px;"}}],"removes":[],"adds":[]},"timestamp":1539774783937},{"type":3,"data":{"source":0,"texts":[],"attributes":[{"id":390,"attributes":{"style":"margin-top: 0px; margin-bottom: 0px; height: 126px;"}}],"removes":[],"adds":[]},"timestamp":1539774783952},{"type":3,"data":{"source":0,"texts":[],"attributes":[{"id":390,"attributes":{"style":"margin-top: 0px; margin-bottom: 0px; height: 123px;"}}],"removes":[],"adds":[]},"timestamp":1539774783969},{"type":3,"data":{"source":0,"texts":[],"attributes":[{"id":390,"attributes":{"style":"margin-top: 0px; margin-bottom: 0px; height: 121px;"}}],"removes":[],"adds":[]},"timestamp":1539774783986},{"type":3,"data":{"source":2,"type":0,"id":390,"x":521,"y":442},"timestamp":1539774784166},{"type":3,"data":{"source":2,"type":2,"id":390,"x":521,"y":442},"timestamp":1539774784166},{"type":3,"data":{"source":1,"positions":[{"x":523,"y":453,"timeOffset":-487},{"x":522,"y":444,"timeOffset":-455},{"x":519,"y":443,"timeOffset":-207},{"x":518,"y":447,"timeOffset":-174},{"x":517,"y":458,"timeOffset":-141},{"x":513,"y":476,"timeOffset":-107},{"x":506,"y":490,"timeOffset":-74},{"x":503,"y":496,"timeOffset":-40},{"x":501,"y":500,"timeOffset":-6}]},"timestamp":1539774784424},{"type":3,"data":{"source":2,"type":1,"id":395,"x":491,"y":518},"timestamp":1539774784656},{"type":3,"data":{"source":2,"type":6,"id":390},"timestamp":1539774784660},{"type":3,"data":{"source":2,"type":5,"id":395},"timestamp":1539774784662},{"type":3,"data":{"source":2,"type":0,"id":395,"x":491,"y":518},"timestamp":1539774784743},{"type":3,"data":{"source":2,"type":2,"id":395,"x":491,"y":518},"timestamp":1539774784743},{"type":3,"data":{"source":0,"texts":[],"attributes":[{"id":149,"attributes":{"class":"needs-validation was-validated"}}],"removes":[],"adds":[]},"timestamp":1539774784747},{"type":3,"data":{"source":1,"positions":[{"x":500,"y":503,"timeOffset":-475},{"x":497,"y":507,"timeOffset":-441},{"x":493,"y":511,"timeOffset":-406},{"x":492,"y":514,"timeOffset":-357},{"x":491,"y":518,"timeOffset":-324}]},"timestamp":1539774784925},{"type":3,"data":{"source":3,"id":1,"x":0,"y":1006},"timestamp":1539774785383},{"type":3,"data":{"source":1,"positions":[{"x":492,"y":519,"timeOffset":-425},{"x":502,"y":516,"timeOffset":-392},{"x":518,"y":515,"timeOffset":-357},{"x":541,"y":511,"timeOffset":-325},{"x":570,"y":506,"timeOffset":-291},{"x":612,"y":494,"timeOffset":-259},{"x":638,"y":489,"timeOffset":-225},{"x":648,"y":485,"timeOffset":-193},{"x":652,"y":484,"timeOffset":-159}]},"timestamp":1539774785425},{"type":3,"data":{"source":3,"id":1,"x":0,"y":914},"timestamp":1539774785483},{"type":3,"data":{"source":3,"id":1,"x":0,"y":649},"timestamp":1539774785584},{"type":3,"data":{"source":3,"id":1,"x":0,"y":618},"timestamp":1539774785684},{"type":3,"data":{"source":3,"id":1,"x":0,"y":375},"timestamp":1539774785784},{"type":3,"data":{"source":3,"id":1,"x":0,"y":265},"timestamp":1539774785885},{"type":3,"data":{"source":1,"positions":[{"x":653,"y":483,"timeOffset":-476},{"x":656,"y":482,"timeOffset":-359},{"x":662,"y":489,"timeOffset":-325},{"x":661,"y":488,"timeOffset":-207},{"x":660,"y":487,"timeOffset":-26}]},"timestamp":1539774785926},{"type":3,"data":{"source":3,"id":1,"x":0,"y":264},"timestamp":1539774786032},{"type":3,"data":{"source":3,"id":1,"x":0,"y":231},"timestamp":1539774786132},{"type":3,"data":{"source":3,"id":1,"x":0,"y":52},"timestamp":1539774786232},{"type":3,"data":{"source":3,"id":1,"x":0,"y":0},"timestamp":1539774786331},{"type":3,"data":{"source":1,"positions":[{"x":661,"y":489,"timeOffset":-292},{"x":656,"y":485,"timeOffset":-259}]},"timestamp":1539774786426},{"type":3,"data":{"source":3,"id":1,"x":0,"y":1},"timestamp":1539774787283},{"type":3,"data":{"source":3,"id":1,"x":0,"y":43},"timestamp":1539774787384},{"type":3,"data":{"source":3,"id":1,"x":0,"y":103},"timestamp":1539774787484},{"type":3,"data":{"source":1,"positions":[{"x":656,"y":489,"timeOffset":0}]},"timestamp":1539774787582},{"type":3,"data":{"source":3,"id":1,"x":0,"y":106},"timestamp":1539774787584},{"type":3,"data":{"source":1,"positions":[{"x":675,"y":503,"timeOffset":-466},{"x":699,"y":517,"timeOffset":-434},{"x":718,"y":532,"timeOffset":-400},{"x":729,"y":547,"timeOffset":-367},{"x":745,"y":569,"timeOffset":-334},{"x":758,"y":585,"timeOffset":-300},{"x":760,"y":588,"timeOffset":-267},{"x":761,"y":589,"timeOffset":-167},{"x":763,"y":594,"timeOffset":-16}]},"timestamp":1539774788082},{"type":3,"data":{"source":2,"type":1,"id":133,"x":766,"y":603},"timestamp":1539774788159},{"type":3,"data":{"source":2,"type":6,"id":395},"timestamp":1539774788160},{"type":3,"data":{"source":2,"type":5,"id":133},"timestamp":1539774788162},{"type":3,"data":{"source":2,"type":0,"id":133,"x":766,"y":603},"timestamp":1539774788279},{"type":3,"data":{"source":2,"type":2,"id":133,"x":766,"y":603},"timestamp":1539774788279},{"type":3,"data":{"source":1,"positions":[{"x":766,"y":602,"timeOffset":-483},{"x":771,"y":598,"timeOffset":-201}]},"timestamp":1539774788582},{"type":3,"data":{"source":5,"text":"c","isChecked":false,"id":133},"timestamp":1539774788860},{"type":3,"data":{"source":5,"text":"co","isChecked":false,"id":133},"timestamp":1539774789178},{"type":3,"data":{"source":5,"text":"cod","isChecked":false,"id":133},"timestamp":1539774789265},{"type":3,"data":{"source":5,"text":"code","isChecked":false,"id":133},"timestamp":1539774789317},{"type":3,"data":{"source":1,"positions":[{"x":778,"y":596,"timeOffset":0}]},"timestamp":1539774790048},{"type":3,"data":{"source":1,"positions":[{"x":797,"y":586,"timeOffset":-466},{"x":825,"y":567,"timeOffset":-433},{"x":868,"y":538,"timeOffset":-399},{"x":922,"y":502,"timeOffset":-366},{"x":967,"y":483,"timeOffset":-332},{"x":994,"y":468,"timeOffset":-300},{"x":998,"y":466,"timeOffset":-233},{"x":1007,"y":464,"timeOffset":-199},{"x":1015,"y":462,"timeOffset":-167},{"x":1021,"y":462,"timeOffset":-133},{"x":1032,"y":460,"timeOffset":-99},{"x":1039,"y":459,"timeOffset":-65},{"x":1042,"y":457,"timeOffset":-33},{"x":1045,"y":457,"timeOffset":0}]},"timestamp":1539774790548},{"type":3,"data":{"source":1,"positions":[{"x":1047,"y":457,"timeOffset":-466},{"x":1050,"y":455,"timeOffset":-332},{"x":1051,"y":454,"timeOffset":-282},{"x":1052,"y":453,"timeOffset":-217},{"x":1060,"y":449,"timeOffset":-182},{"x":1077,"y":443,"timeOffset":-150},{"x":1101,"y":429,"timeOffset":-116},{"x":1130,"y":414,"timeOffset":-82}]},"timestamp":1539774791048},{"type":3,"data":{"source":2,"type":6,"id":133},"timestamp":1539774791137}]; const app = new App({ target: document.body, From 43b2290f5f83b8ed845ebba020c5c7c5b203bdb8 Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Thu, 18 Oct 2018 16:13:59 +0800 Subject: [PATCH 030/524] export reset id function --- index.d.ts | 1 + package.json | 2 +- src/index.ts | 4 ++-- src/snapshot.ts | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/index.d.ts b/index.d.ts index 85dc9653bf..bfd03d9696 100644 --- a/index.d.ts +++ b/index.d.ts @@ -8,3 +8,4 @@ export function serializeNodeWithId( doc: Document, map: idNodeMap, ): serializedNodeWithId | null; +export function resetId(): void; diff --git a/package.json b/package.json index 6f32f4e480..6f56531c19 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rrweb-snapshot", - "version": "0.4.2", + "version": "0.4.3", "description": "rrweb's component to take a snapshot of DOM, aka DOM serializer", "main": "dist/index.js", "module": "dist/module.js", diff --git a/src/index.ts b/src/index.ts index fd9694655a..cba7b4996f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ -import snapshot, { serializeNodeWithId } from './snapshot'; +import snapshot, { serializeNodeWithId, resetId } from './snapshot'; import rebuild from './rebuild'; export * from './types'; -export { snapshot, serializeNodeWithId, rebuild }; +export { snapshot, serializeNodeWithId, resetId, rebuild }; diff --git a/src/snapshot.ts b/src/snapshot.ts index fa3aea8cb3..c948fa14e1 100644 --- a/src/snapshot.ts +++ b/src/snapshot.ts @@ -13,7 +13,7 @@ function genId(): number { return _id++; } -function resetId() { +export function resetId() { _id = 1; } From 416c1eec9ae602274e79de74416809250b4ca4dc Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Thu, 18 Oct 2018 19:42:01 +0800 Subject: [PATCH 031/524] fix style content url normalizer and add some tests --- package.json | 2 +- src/snapshot.ts | 22 +++++++++++++++++++++- test/snapshot.test.ts | 31 +++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 test/snapshot.test.ts diff --git a/package.json b/package.json index 6f56531c19..04fde37f22 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rrweb-snapshot", - "version": "0.4.3", + "version": "0.4.4", "description": "rrweb's component to take a snapshot of DOM, aka DOM serializer", "main": "dist/index.js", "module": "dist/module.js", diff --git a/src/snapshot.ts b/src/snapshot.ts index c948fa14e1..5674e86d6d 100644 --- a/src/snapshot.ts +++ b/src/snapshot.ts @@ -28,9 +28,29 @@ function getCssRulesString(s: CSSStyleSheet): string | null { } } +function extractOrigin(url: string): string { + let origin; + if (url.indexOf('//') > -1) { + origin = url + .split('/') + .slice(0, 3) + .join('/'); + } else { + origin = url.split('/')[0]; + } + origin = origin.split('?')[0]; + return origin; +} + const URL_IN_CSS_REF = /url\((['"])([^'"]*)\1\)/gm; -function absoluteToStylesheet(cssText: string, href: string): string { +export function absoluteToStylesheet(cssText: string, href: string): string { return cssText.replace(URL_IN_CSS_REF, (_1, _2, filePath) => { + if (!/^[./]/.test(filePath)) { + return `url('${filePath}')`; + } + if (filePath[0] === '/') { + return `url('${extractOrigin(href) + filePath}')`; + } const stack = href.split('/'); const parts = filePath.split('/'); stack.pop(); diff --git a/test/snapshot.test.ts b/test/snapshot.test.ts new file mode 100644 index 0000000000..0720f1205e --- /dev/null +++ b/test/snapshot.test.ts @@ -0,0 +1,31 @@ +import 'mocha'; +import { expect } from 'chai'; +import { absoluteToStylesheet } from '../src/snapshot'; + +describe('absolute url to stylesheet', () => { + const href = 'http://localhost/css/style.css'; + + it('can handle same level path', () => { + expect(absoluteToStylesheet('url("./a.jpg")', href)).to.equal( + `url('http://localhost/css/a.jpg')`, + ); + }); + + it('can handle parent level path', () => { + expect(absoluteToStylesheet('url("../a.jpg")', href)).to.equal( + `url('http://localhost/a.jpg')`, + ); + }); + + it('can handle absolute path', () => { + expect(absoluteToStylesheet('url("/a.jpg")', href)).to.equal( + `url('http://localhost/a.jpg')`, + ); + }); + + it('can handle external path', () => { + expect( + absoluteToStylesheet('url("http://localhost/a.jpg")', href), + ).to.equal(`url('http://localhost/a.jpg')`); + }); +}); From 202a6746360fb5835e2f1345bf7a7e8d4adf9f3e Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Sun, 21 Oct 2018 22:32:31 +0800 Subject: [PATCH 032/524] use document object from params instead of the one in the current scope --- index.d.ts | 2 +- src/rebuild.ts | 22 +++++++++++----------- test/integration.ts | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/index.d.ts b/index.d.ts index bfd03d9696..9f2eda37e5 100644 --- a/index.d.ts +++ b/index.d.ts @@ -2,7 +2,7 @@ import { serializedNodeWithId, idNodeMap } from './src/types'; export * from './src/types'; export function snapshot(n: Document): [serializedNodeWithId | null, idNodeMap]; -export function rebuild(n: serializedNodeWithId): Node | null; +export function rebuild(n: serializedNodeWithId, doc: Document): Node | null; export function serializeNodeWithId( n: Node, doc: Document, diff --git a/src/rebuild.ts b/src/rebuild.ts index 4e61283e48..c53cf72b73 100644 --- a/src/rebuild.ts +++ b/src/rebuild.ts @@ -11,19 +11,19 @@ function getTagName(n: elementNode): string { return tagName; } -function buildNode(n: serializedNodeWithId): Node | null { +function buildNode(n: serializedNodeWithId, doc: Document): Node | null { switch (n.type) { case NodeType.Document: - return document.implementation.createDocument(null, '', null); + return doc.implementation.createDocument(null, '', null); case NodeType.DocumentType: - return document.implementation.createDocumentType( + return doc.implementation.createDocumentType( n.name, n.publicId, n.systemId, ); case NodeType.Element: const tagName = getTagName(n); - const node = document.createElement(tagName); + const node = doc.createElement(tagName); const extraChildIndexes: number[] = []; for (const name in n.attributes) { if (n.attributes.hasOwnProperty(name)) { @@ -32,7 +32,7 @@ function buildNode(n: serializedNodeWithId): Node | null { const isTextarea = tagName === 'textarea' && name === 'value'; const isRemoteCss = tagName === 'style' && name === '_cssText'; if (isTextarea || isRemoteCss) { - const child = document.createTextNode(value); + const child = doc.createTextNode(value); // identify the extra child DOM we added when rebuild extraChildIndexes.push(node.childNodes.length); node.appendChild(child); @@ -53,18 +53,18 @@ function buildNode(n: serializedNodeWithId): Node | null { } return node; case NodeType.Text: - return document.createTextNode(n.textContent); + return doc.createTextNode(n.textContent); case NodeType.CDATA: - return document.createCDATASection(n.textContent); + return doc.createCDATASection(n.textContent); case NodeType.Comment: - return document.createComment(n.textContent); + return doc.createComment(n.textContent); default: return null; } } -function rebuild(n: serializedNodeWithId): Node | null { - const root = buildNode(n); +function rebuild(n: serializedNodeWithId, doc: Document): Node | null { + const root = buildNode(n, doc); if (!root) { return null; } @@ -73,7 +73,7 @@ function rebuild(n: serializedNodeWithId): Node | null { } if (n.type === NodeType.Document || n.type === NodeType.Element) { for (const childN of n.childNodes) { - const childNode = rebuild(childN); + const childNode = rebuild(childN, doc); if (!childNode) { console.warn('Failed to rebuild', childN); } else { diff --git a/test/integration.ts b/test/integration.ts index 700469f2ea..d2a74aca06 100644 --- a/test/integration.ts +++ b/test/integration.ts @@ -101,7 +101,7 @@ describe('integration tests', () => { const rebuildHtml = (await page.evaluate(`${this.code} const x = new XMLSerializer(); const [snap] = rrweb.snapshot(document); - x.serializeToString(rrweb.rebuild(snap)); + x.serializeToString(rrweb.rebuild(snap, document)); `)).replace(/\n\n/g, ''); const result = matchSnapshot(rebuildHtml, __filename, title); assert(result.pass, result.pass ? '' : result.report()); From 508bbdfc2686dbee9ef14ae6491cdcf784d58ad2 Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Mon, 22 Oct 2018 10:34:23 +0800 Subject: [PATCH 033/524] refactor rebuild implementation which mount DOM onto the target document object --- index.d.ts | 12 +- package.json | 2 +- src/index.ts | 4 +- src/rebuild.ts | 156 +++++++++++++++++++++---- src/snapshot.ts | 16 +-- test/__snapshots__/integration.ts.snap | 154 ++++++++++++------------ test/integration.ts | 3 +- 7 files changed, 230 insertions(+), 117 deletions(-) diff --git a/index.d.ts b/index.d.ts index 9f2eda37e5..21a0700040 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,11 +1,19 @@ -import { serializedNodeWithId, idNodeMap } from './src/types'; +import { serializedNodeWithId, idNodeMap, INode } from './src/types'; export * from './src/types'; export function snapshot(n: Document): [serializedNodeWithId | null, idNodeMap]; -export function rebuild(n: serializedNodeWithId, doc: Document): Node | null; +export function rebuild( + n: serializedNodeWithId, + doc: Document, +): [Node | null, idNodeMap]; export function serializeNodeWithId( n: Node, doc: Document, map: idNodeMap, ): serializedNodeWithId | null; export function resetId(): void; +export function buildNodeWithSN( + n: serializedNodeWithId, + doc: Document, + map: idNodeMap, +): INode | null; diff --git a/package.json b/package.json index 04fde37f22..e0eceea0bd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rrweb-snapshot", - "version": "0.4.4", + "version": "0.5.1", "description": "rrweb's component to take a snapshot of DOM, aka DOM serializer", "main": "dist/index.js", "module": "dist/module.js", diff --git a/src/index.ts b/src/index.ts index cba7b4996f..f3238ea290 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ import snapshot, { serializeNodeWithId, resetId } from './snapshot'; -import rebuild from './rebuild'; +import rebuild, { buildNodeWithSN } from './rebuild'; export * from './types'; -export { snapshot, serializeNodeWithId, resetId, rebuild }; +export { snapshot, serializeNodeWithId, resetId, rebuild, buildNodeWithSN }; diff --git a/src/rebuild.ts b/src/rebuild.ts index c53cf72b73..c995b6cc6e 100644 --- a/src/rebuild.ts +++ b/src/rebuild.ts @@ -1,4 +1,108 @@ -import { serializedNodeWithId, NodeType, tagMap, elementNode } from './types'; +import { + serializedNodeWithId, + NodeType, + tagMap, + elementNode, + idNodeMap, + INode, +} from './types'; + +// TODO: need a more accurate list +const svgTags = [ + 'altGlyph', + 'altGlyphDef', + 'altGlyphItem', + 'animate', + 'animateColor', + 'animateMotion', + 'animateTransform', + 'animation', + 'circle', + 'clipPath', + 'color-profile', + 'cursor', + 'defs', + 'desc', + 'discard', + 'ellipse', + 'feBlend', + 'feColorMatrix', + 'feComponentTransfer', + 'feComposite', + 'feConvolveMatrix', + 'feDiffuseLighting', + 'feDisplacementMap', + 'feDistantLight', + 'feDropShadow', + 'feFlood', + 'feFuncA', + 'feFuncB', + 'feFuncG', + 'feFuncR', + 'feGaussianBlur', + 'feImage', + 'feMerge', + 'feMergeNode', + 'feMorphology', + 'feOffset', + 'fePointLight', + 'feSpecularLighting', + 'feSpotLight', + 'feTile', + 'feTurbulence', + 'filter', + 'font', + 'font-face', + 'font-face-format', + 'font-face-name', + 'font-face-src', + 'font-face-uri', + 'foreignObject', + 'g', + 'glyph', + 'glyphRef', + 'handler', + 'hatch', + 'hatchpath', + 'hkern', + 'image', + 'line', + 'linearGradient', + 'listener', + 'marker', + 'mask', + 'mesh', + 'meshgradient', + 'meshpatch', + 'meshrow', + 'metadata', + 'missing-glyph', + 'mpath', + 'path', + 'pattern', + 'polygon', + 'polyline', + 'prefetch', + 'radialGradient', + 'rect', + 'set', + 'solidColor', + 'solidcolor', + 'stop', + 'svg', + 'switch', + 'symbol', + 'tbreak', + 'text', + 'textArea', + 'textPath', + 'tref', + 'tspan', + 'unknown', + 'use', + 'view', + 'vkern', +]; const tagMap: tagMap = { script: 'noscript', @@ -23,8 +127,12 @@ function buildNode(n: serializedNodeWithId, doc: Document): Node | null { ); case NodeType.Element: const tagName = getTagName(n); - const node = doc.createElement(tagName); - const extraChildIndexes: number[] = []; + let node: Element; + if (svgTags.indexOf(tagName) < 0) { + node = doc.createElement(tagName); + } else { + node = doc.createElementNS('http://www.w3.org/2000/svg', tagName); + } for (const name in n.attributes) { if (n.attributes.hasOwnProperty(name)) { let value = n.attributes[name]; @@ -33,10 +141,7 @@ function buildNode(n: serializedNodeWithId, doc: Document): Node | null { const isRemoteCss = tagName === 'style' && name === '_cssText'; if (isTextarea || isRemoteCss) { const child = doc.createTextNode(value); - // identify the extra child DOM we added when rebuild - extraChildIndexes.push(node.childNodes.length); node.appendChild(child); - continue; } try { node.setAttribute(name, value); @@ -45,12 +150,6 @@ function buildNode(n: serializedNodeWithId, doc: Document): Node | null { } } } - if (extraChildIndexes.length) { - node.setAttribute( - 'data-extra-child-index', - JSON.stringify(extraChildIndexes), - ); - } return node; case NodeType.Text: return doc.createTextNode(n.textContent); @@ -63,25 +162,42 @@ function buildNode(n: serializedNodeWithId, doc: Document): Node | null { } } -function rebuild(n: serializedNodeWithId, doc: Document): Node | null { - const root = buildNode(n, doc); - if (!root) { +export function buildNodeWithSN( + n: serializedNodeWithId, + doc: Document, + map: idNodeMap, +): INode | null { + let node = buildNode(n, doc); + if (!node) { return null; } - if (n.type === NodeType.Element) { - (root as HTMLElement).setAttribute('data-rrid', String(n.id)); + // use target document as root document + if (n.type === NodeType.Document) { + doc.open(); + node = doc; } + + (node as INode).__sn = n; + map[n.id] = node as INode; if (n.type === NodeType.Document || n.type === NodeType.Element) { for (const childN of n.childNodes) { - const childNode = rebuild(childN, doc); + const childNode = buildNodeWithSN(childN, doc, map); if (!childNode) { console.warn('Failed to rebuild', childN); } else { - root.appendChild(childNode); + node.appendChild(childNode); } } } - return root; + return node as INode; +} + +function rebuild( + n: serializedNodeWithId, + doc: Document, +): [Node | null, idNodeMap] { + const idNodeMap: idNodeMap = {}; + return [buildNodeWithSN(n, doc, idNodeMap), idNodeMap]; } export default rebuild; diff --git a/src/snapshot.ts b/src/snapshot.ts index 5674e86d6d..d141b35bb2 100644 --- a/src/snapshot.ts +++ b/src/snapshot.ts @@ -187,24 +187,12 @@ export function serializeNodeWithId( }); (n as INode).__sn = serializedNode; map[serializedNode.id] = n as INode; - return serializedNode; -} - -function _snapshot( - n: Node, - doc: Document, - map: idNodeMap, -): serializedNodeWithId | null { - const serializedNode = serializeNodeWithId(n, doc, map); - if (!serializedNode) { - return null; - } if ( serializedNode.type === NodeType.Document || serializedNode.type === NodeType.Element ) { for (const childN of Array.from(n.childNodes)) { - const serializedChildNode = _snapshot(childN, doc, map); + const serializedChildNode = serializeNodeWithId(childN, doc, map); if (serializedChildNode) { serializedNode.childNodes.push(serializedChildNode); } @@ -216,7 +204,7 @@ function _snapshot( function snapshot(n: Document): [serializedNodeWithId | null, idNodeMap] { resetId(); const idNodeMap: idNodeMap = {}; - return [_snapshot(n, n, idNodeMap), idNodeMap]; + return [serializeNodeWithId(n, n, idNodeMap), idNodeMap]; } export default snapshot; diff --git a/test/__snapshots__/integration.ts.snap b/test/__snapshots__/integration.ts.snap index 87f1446e87..f221300322 100644 --- a/test/__snapshots__/integration.ts.snap +++ b/test/__snapshots__/integration.ts.snap @@ -1,9 +1,9 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`[html file]: about-mozilla.html 1`] = ` -" - The Book of Mozilla, 11:9 - -

- Mammon slept. And the beast reborn spread over the earth and its numbers - grew legion. And they proclaimed the times and sacrificed crops unto the - fire, with the cunning of foxes. And they built a new world in their own - image as promised by the - sacred words, and spoke +

+ Mammon slept. And the beast reborn spread over the earth and its numbers + grew legion. And they proclaimed the times and sacrificed crops unto the + fire, with the cunning of foxes. And they built a new world in their own + image as promised by the + sacred words, and spoke of the beast with their children. Mammon awoke, and lo! it was - naught but a follower. -

- from The Book of Mozilla, 11:9
(10th Edition) + naught but a follower. +

+ from The Book of Mozilla, 11:9
(10th Edition)

" `; exports[`[html file]: basic.html 1`] = ` -" - - - - Document -" +" + + + + Document +" `; exports[`[html file]: cors-style-sheet.html 1`] = ` -" - - - - with style sheet - -" +" + + + + with style sheet + +" `; exports[`[html file]: form-fields.html 1`] = ` -" - - - - form fields - -
-